summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-09-03 22:14:20 +0000
committerRich Hickey <richhickey@gmail.com>2007-09-03 22:14:20 +0000
commita51a104cfff59b7b27628dcc66885d712510879f (patch)
treeead77a60ea60dab4d02c9836edb8616e16da815b /src
parent5759cb53f75f34e43814d99a362f96ffc315eb42 (diff)
interim checkin
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/BytecodeCompiler.java56
1 files changed, 53 insertions, 3 deletions
diff --git a/src/jvm/clojure/lang/BytecodeCompiler.java b/src/jvm/clojure/lang/BytecodeCompiler.java
index c8fd191b..1dd51e80 100644
--- a/src/jvm/clojure/lang/BytecodeCompiler.java
+++ b/src/jvm/clojure/lang/BytecodeCompiler.java
@@ -152,10 +152,11 @@ static class DefExpr implements Expr{
}
}
-static class VarExpr implements Expr{
+static class VarExpr implements Expr, AssignableExpr{
final Var var;
final Symbol tag;
final static Method getMethod = Method.getMethod("Object get()");
+ final static Method setMethod = Method.getMethod("Object set(Object)");
public VarExpr(Var var, Symbol tag){
this.var = var;
@@ -173,6 +174,19 @@ static class VarExpr implements Expr{
gen.invokeVirtual(VAR_TYPE, getMethod);
}
}
+
+ public Object evalAssign(Expr val) throws Exception{
+ return var.set(val.eval());
+ }
+
+ public void emitAssign(C context, FnExpr fn, GeneratorAdapter gen,
+ Expr val) throws Exception{
+ fn.emitVar(gen, var);
+ val.emit(C.EXPRESSION, fn, gen);
+ gen.invokeVirtual(VAR_TYPE, setMethod);
+ if(context == C.STATEMENT)
+ gen.pop();
+ }
}
static class TheVarExpr implements Expr{
@@ -226,6 +240,12 @@ static abstract class LiteralExpr implements Expr{
}
}
+static interface AssignableExpr{
+ Object evalAssign(Expr val) throws Exception;
+
+ void emitAssign(C context, FnExpr fn, GeneratorAdapter gen, Expr val) throws Exception;
+}
+
static abstract class HostExpr implements Expr{
public static Expr parse(C context, ISeq form) throws Exception{
//(. x fieldname-sym) or (. x (methodname-sym args...))
@@ -280,10 +300,11 @@ static abstract class HostExpr implements Expr{
static abstract class FieldExpr extends HostExpr{
}
-static class InstanceFieldExpr extends FieldExpr{
+static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{
final Expr target;
final String fieldName;
final static Method getInstanceFieldMethod = Method.getMethod("Object getInstanceField(Object,String)");
+ final static Method setInstanceFieldMethod = Method.getMethod("Object setInstanceField(Object,String,Object)");
public InstanceFieldExpr(Expr target, String fieldName){
@@ -303,12 +324,27 @@ static class InstanceFieldExpr extends FieldExpr{
gen.invokeStatic(REFLECTOR_TYPE, getInstanceFieldMethod);
}
}
+
+ public Object evalAssign(Expr val) throws Exception{
+ return Reflector.setInstanceField(target.eval(), fieldName, val.eval());
+ }
+
+ public void emitAssign(C context, FnExpr fn, GeneratorAdapter gen,
+ Expr val) throws Exception{
+ target.emit(C.EXPRESSION, fn, gen);
+ gen.push(fieldName);
+ val.emit(C.EXPRESSION, fn, gen);
+ gen.invokeStatic(REFLECTOR_TYPE, setInstanceFieldMethod);
+ if(context == C.STATEMENT)
+ gen.pop();
+ }
}
-static class StaticFieldExpr extends FieldExpr{
+static class StaticFieldExpr extends FieldExpr implements AssignableExpr{
final String className;
final String fieldName;
final static Method getStaticFieldMethod = Method.getMethod("Object getStaticField(String,String)");
+ final static Method setStaticFieldMethod = Method.getMethod("Object setStaticField(String,String,Object)");
public StaticFieldExpr(String className, String fieldName){
@@ -325,6 +361,20 @@ static class StaticFieldExpr extends FieldExpr{
gen.push(fieldName);
gen.invokeStatic(REFLECTOR_TYPE, getStaticFieldMethod);
}
+
+ public Object evalAssign(Expr val) throws Exception{
+ return Reflector.setStaticField(className, fieldName, val.eval());
+ }
+
+ public void emitAssign(C context, FnExpr fn, GeneratorAdapter gen,
+ Expr val) throws Exception{
+ gen.push(className);
+ gen.push(fieldName);
+ val.emit(C.EXPRESSION, fn, gen);
+ gen.invokeStatic(REFLECTOR_TYPE, setStaticFieldMethod);
+ if(context == C.STATEMENT)
+ gen.pop();
+ }
}
static abstract class MethodExpr extends HostExpr{