1 package gnu.expr; 2 import gnu.bytecode.*; 3 import gnu.mapping.*; 4 5 9 10 public class LetExp extends ScopeExp 11 { 12 public Expression[] inits; 13 public Expression body; 14 15 public LetExp (Expression[] i) { inits = i; } 16 17 public Expression getBody() { return body; } 18 public void setBody(Expression body) { this.body = body; } 19 20 protected boolean mustCompile () { return false; } 21 22 public void apply (CallContext ctx) throws Throwable 23 { 24 setIndexes(); 25 int level = ScopeExp.nesting(this); 26 int i = frameSize; 27 28 Object [] evalFrame = new Object [i]; 29 Object [][] evalFrames = ctx.evalFrames; 30 if (evalFrames == null) 31 { 32 evalFrames = new Object [level+10][]; 33 ctx.evalFrames = evalFrames; 34 } 35 else if (level >= evalFrames.length) 36 { 37 Object [][] newFrames = new Object [level+10][]; 38 System.arraycopy(evalFrames, 0, newFrames, 0, evalFrames.length); 39 ctx.evalFrames = evalFrames = newFrames; 40 } 41 evalFrames[level] = evalFrame; 42 43 try 44 { 45 i = 0; 46 for (Declaration decl = firstDecl(); decl != null; 47 decl = decl.nextDecl(), i++) 48 { 49 Expression init = inits[i]; 50 if (init == QuoteExp.undefined_exp) 51 continue; 52 Object value = init.eval(ctx); 53 Type type = decl.type; 54 if (type != null && type != Type.pointer_type) 55 value = type.coerceFromObject(value); 56 if (decl.isIndirectBinding()) 57 { 58 gnu.mapping.Location loc = decl.makeIndirectLocationFor(); 59 loc.set(value); 60 value = loc; 61 } 62 evalFrame[i] = value; 63 } 64 body.apply(ctx); 65 } 66 finally 67 { 68 evalFrames[level] = null; 69 } 70 } 71 72 113 114 116 void store_rest (Compilation comp, int i, Declaration decl) 117 { 118 if (decl != null) 119 { 120 store_rest (comp, i+1, decl.nextDecl()); 121 if (decl.needsInit()) 122 { 123 if (decl.isIndirectBinding()) 124 { 125 CodeAttr code = comp.getCode(); 126 if (inits[i] == QuoteExp.undefined_exp) 127 { 128 Object name = decl.getSymbol(); 129 comp.compileConstant(name, Target.pushObject); 130 code.emitInvokeStatic(BindingInitializer.makeLocationMethod(name)); 131 } 132 else 133 { 134 decl.pushIndirectBinding(comp); 135 } 136 } 137 decl.compileStore(comp); 138 } 139 } 140 } 141 142 public void compile (Compilation comp, Target target) 143 { 144 gnu.bytecode.CodeAttr code = comp.getCode(); 145 146 155 156 158 Declaration decl = firstDecl(); 159 for (int i = 0; i < inits.length; i++, decl = decl.nextDecl()) 160 { 161 Target varTarget; 162 Expression init = inits[i]; 163 boolean needsInit = decl.needsInit(); 164 if (needsInit) 165 decl.allocateVariable(code); 166 if (! needsInit 167 || (decl.isIndirectBinding() && init == QuoteExp.undefined_exp)) 168 varTarget = Target.Ignore; 169 else 170 { 171 Type varType = decl.getType(); 172 varTarget = CheckedTarget.getInstance(varType); 173 if (init == QuoteExp.undefined_exp) 174 { 175 if (varType instanceof PrimType) 177 init = new QuoteExp(new Byte ((byte) 0)); 178 else if (varType != null && varType != Type.pointer_type) 179 init = QuoteExp.nullExp; 180 } 181 } 182 init.compile (comp, varTarget); 183 } 184 185 code.enterScope(getVarScope()); 186 187 188 store_rest (comp, 0, firstDecl()); 189 190 body.compileWithPosition(comp, target); 191 popScope(code); 192 } 193 194 public final gnu.bytecode.Type getType() 195 { 196 return body.getType(); 197 } 198 199 protected Expression walk (ExpWalker walker) 200 { 201 return walker.walkLetExp(this); 202 } 203 204 public void walkInitializers (ExpWalker walker) 205 { 206 Declaration decl = firstDecl(); 207 for (int i = 0; i < inits.length; i++, decl = decl.nextDecl()) 208 { 209 Expression init0 = inits[i]; 210 Expression init = walker.walk(init0); 211 inits[i] = init; 212 if (decl.value == init0) 213 decl.value = init; 214 } 215 } 216 217 protected void walkChildren(ExpWalker walker) 218 { 219 walkInitializers(walker); 220 if (walker.exitValue == null) 221 body = (Expression) walker.walk(body); 222 } 223 224 public void print (OutPort out) 225 { 226 print(out, "(Let", ")"); 227 } 228 229 public void print (OutPort out, String startTag, String endTag) 230 { 231 out.startLogicalBlock(startTag+"#"+id, endTag, 2); 232 out.writeSpaceFill(); 233 printLineColumn(out); 234 out.startLogicalBlock("(", false, ")"); 235 Declaration decl = firstDecl(); 236 int i = 0; 237 238 for (; decl != null; decl = decl.nextDecl()) 239 { 240 if (i > 0) 241 out.writeSpaceFill(); 242 out.startLogicalBlock("(", false, ")"); 243 decl.printInfo(out); 244 if (inits != null) 245 { 246 out.writeSpaceFill(); 247 out.print('='); 248 out.writeSpaceFill(); 249 { 253 if (i >= inits.length) 254 out.print("<missing init>"); 255 else if (inits[i] == null) 256 out.print("<null>"); 257 else 258 inits[i].print(out); 259 i++; 260 } 261 } 262 out.endLogicalBlock(")"); 263 } 264 out.endLogicalBlock(")"); 265 out.writeSpaceLinear(); 266 if (body == null) 267 out.print("<null body>"); 268 else 269 body.print (out); 270 out.endLogicalBlock(endTag); 271 } 272 } 273 | Popular Tags |