summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-09-05 16:50:12 +0000
committerRich Hickey <richhickey@gmail.com>2007-09-05 16:50:12 +0000
commitca3cfe298fc492ebe113c984535e76435ebf590a (patch)
treeae81b741eb425c633023e0576db2cd7fbef2ace0 /src
parentfc05db1783036d621215de9c297500c2d349b33e (diff)
added try-finally
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/BytecodeCompiler.java49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/jvm/clojure/lang/BytecodeCompiler.java b/src/jvm/clojure/lang/BytecodeCompiler.java
index 5f4d39bb..4130e78a 100644
--- a/src/jvm/clojure/lang/BytecodeCompiler.java
+++ b/src/jvm/clojure/lang/BytecodeCompiler.java
@@ -34,6 +34,7 @@ static final Symbol QUOTE = Symbol.create("quote");
static final Symbol THE_VAR = Symbol.create("the-var");
static final Symbol DOT = Symbol.create(".");
static final Symbol ASSIGN = Symbol.create("=");
+static final Symbol TRY_FINALLY = Symbol.create("try-finally");
static final Symbol THISFN = Symbol.create("thisfn");
static final Symbol IFN = Symbol.create("clojure.lang", "IFn");
@@ -639,6 +640,52 @@ static class CharExpr extends LiteralExpr{
}
}
+static class TryFinallyExpr implements Expr{
+ final Expr tryExpr;
+ final Expr finallyExpr;
+
+
+ public TryFinallyExpr(Expr tryExpr, Expr finallyExpr){
+ this.tryExpr = tryExpr;
+ this.finallyExpr = finallyExpr;
+ }
+
+ public Object eval() throws Exception{
+ throw new UnsupportedOperationException("Can't eval try");
+ }
+
+ public void emit(C context, FnExpr fn, GeneratorAdapter gen){
+ Label startTry = gen.newLabel();
+ Label endTry = gen.newLabel();
+ Label end = gen.newLabel();
+ Label finallyLabel = gen.newLabel();
+ gen.visitTryCatchBlock(startTry, endTry, finallyLabel, null);
+ gen.mark(startTry);
+ tryExpr.emit(context, fn, gen);
+ gen.mark(endTry);
+ finallyExpr.emit(C.STATEMENT, fn, gen);
+ gen.goTo(end);
+ gen.mark(finallyLabel);
+ //exception should be on stack
+ finallyExpr.emit(C.STATEMENT, fn, gen);
+ gen.throwException();
+ gen.mark(end);
+ }
+
+ public static Expr parse(C context, ISeq form) throws Exception{
+ //(try-finally try-expr finally-expr)
+ if(form.count() != 3)
+ throw new IllegalArgumentException(
+ "Wrong number of arguments, expecting: (try-finally try-expr finally-expr) ");
+
+ if(context == C.EVAL)
+ return analyze(context, RT.list(RT.list(FN, PersistentVector.EMPTY, form)));
+
+ return new TryFinallyExpr(analyze(context, RT.second(form)),
+ analyze(C.STATEMENT, RT.third(form)));
+ }
+}
+
static class IfExpr implements Expr{
final Expr testExpr;
final Expr thenExpr;
@@ -1416,6 +1463,8 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti
return TheVarExpr.parse(context, form);
else if(op.equals(ASSIGN))
return AssignExpr.parse(context, form);
+ else if(op.equals(TRY_FINALLY))
+ return TryFinallyExpr.parse(context, form);
else
return InvokeExpr.parse(context, form);
}