001: package gnu.expr;
002:
003: import gnu.bytecode.*;
004: import gnu.mapping.*;
005:
006: /**
007: * This class represents try/catch/finally.
008: * @author Per Bothner
009: */
010:
011: public class TryExp extends Expression {
012: Expression try_clause;
013:
014: CatchClause catch_clauses;
015:
016: Expression finally_clause;
017:
018: public final CatchClause getCatchClauses() {
019: return catch_clauses;
020: }
021:
022: public final void setCatchClauses(CatchClause catch_clauses) {
023: this .catch_clauses = catch_clauses;
024: }
025:
026: public TryExp(Expression try_clause, Expression finally_clause) {
027: this .try_clause = try_clause;
028: this .finally_clause = finally_clause;
029: }
030:
031: public Object eval(Environment env) throws Throwable {
032: if (catch_clauses != null)
033: throw new RuntimeException(
034: "internal error - TryExp.eval called");
035: try {
036: return try_clause.eval(env);
037: } finally {
038: finally_clause.eval(env);
039: }
040: }
041:
042: public void compile(Compilation comp, Target target) {
043: CodeAttr code = comp.getCode();
044: boolean has_finally = finally_clause != null;
045: Type result_type = target instanceof IgnoreTarget ? null
046: : getType();
047: Target ttarg;
048: if (result_type == null)
049: ttarg = Target.Ignore;
050: else if (result_type == Type.pointer_type)
051: ttarg = Target.pushObject;
052: else
053: ttarg = new StackTarget(result_type);
054: code.emitTryStart(has_finally, result_type);
055: try_clause.compileWithPosition(comp, ttarg);
056: code.emitTryEnd();
057:
058: CatchClause catch_clause = catch_clauses;
059: for (; catch_clause != null; catch_clause = catch_clause
060: .getNext()) {
061: catch_clause.compile(comp, ttarg);
062: }
063:
064: if (finally_clause != null) {
065: code.emitFinallyStart();
066: finally_clause.compileWithPosition(comp, Target.Ignore);
067: code.emitFinallyEnd();
068: }
069: code.emitTryCatchEnd();
070: if (result_type != null)
071: target.compileFromStack(comp, result_type);
072: }
073:
074: protected Expression walk(ExpWalker walker) {
075: return walker.walkTryExp(this );
076: }
077:
078: protected void walkChildren(ExpWalker walker) {
079: try_clause = try_clause.walk(walker);
080: CatchClause catch_clause = catch_clauses;
081: while (walker.exitValue == null && catch_clause != null) {
082: catch_clause.walk(walker);
083: catch_clause = catch_clause.getNext();
084: }
085:
086: if (walker.exitValue == null && finally_clause != null)
087: finally_clause = finally_clause.walk(walker);
088: }
089:
090: public void print(OutPort ps) {
091: ps.print("(Try ");
092: try_clause.print(ps);
093: CatchClause catch_clause = catch_clauses;
094: for (; catch_clause != null; catch_clause = catch_clause
095: .getNext()) {
096: catch_clause.print(ps);
097: }
098: if (finally_clause != null) {
099: ps.print(" finally: ");
100: finally_clause.print(ps);
101: }
102: ps.print(")");
103: }
104:
105: public final Type getType() {
106: return Type.void_type;
107: }
108: }
|