1 package gnu.expr; 2 import gnu.bytecode.Type; 3 import gnu.mapping.*; 4 import gnu.text.Printable; 5 import gnu.text.SourceLocator; 6 import gnu.lists.Consumer; 7 import java.io.PrintWriter ; 8 9 14 15 public abstract class Expression extends Procedure0 16 implements Printable, SourceLocator 17 { 18 public final Object eval (CallContext ctx) throws Throwable 19 { 20 int start = ctx.startFromContext(); 21 try 22 { 23 match0(ctx); 24 return ctx.getFromContext(start); 25 } 26 catch (Throwable ex) 27 { 28 ctx.cleanupFromContext(start); 29 throw ex; 30 } 31 } 32 33 public final Object eval (Environment env) throws Throwable 34 { 35 CallContext ctx = CallContext.getInstance(); 36 Environment save = ctx.getEnvironmentRaw(); 37 if (env != save) 38 ctx.setEnvironmentRaw(env); 39 try 40 { 41 return eval(ctx); 42 } 43 finally 44 { 45 if (env != save) 46 ctx.setEnvironmentRaw(save); 47 } 48 } 49 50 protected abstract boolean mustCompile (); 51 52 public final int match0 (CallContext ctx) 53 { 54 ctx.proc = this; 55 ctx.pc = 0; 56 return 0; 57 } 58 59 public final Object apply0 () throws Throwable 60 { 61 CallContext ctx = CallContext.getInstance(); 62 check0(ctx); 63 return ctx.runUntilValue(); 64 } 65 66 71 public void apply (CallContext ctx) throws Throwable 72 { 73 throw new RuntimeException ("internal error - " 74 + getClass() + ".eval called"); 75 } 76 77 public final void print (Consumer out) 78 { 79 if (out instanceof OutPort) 80 print((OutPort) out); 81 else if (out instanceof PrintWriter ) 82 { 83 OutPort port = new OutPort((PrintWriter ) out); 84 print(port); 85 port.close(); 86 } 87 else 88 { 89 CharArrayOutPort port = new CharArrayOutPort(); 90 print(port); 91 port.close(); 92 port.writeTo(out); 93 } 94 } 95 96 public abstract void print (OutPort ps); 97 98 102 public void printLineColumn(OutPort out) 103 { 104 int line = getLineNumber(); 105 if (line > 0) 106 { 107 out.print("line:"); 108 out.print(line); 109 int column = getColumnNumber(); 110 if (column > 0) 111 { 112 out.print(':'); 113 out.print(column); 114 } 115 out.writeSpaceFill(); 116 } 117 } 118 119 public abstract void compile (Compilation comp, Target target); 120 121 122 public final void compileWithPosition(Compilation comp, Target target) 123 { 124 int line = getLineNumber (); 125 if (line > 0) 126 { 127 comp.getCode().putLineNumber(getFileName(), line); 128 compileNotePosition(comp, target, this); 129 } 130 else 131 compile(comp, target); 132 } 133 134 136 public final void compileWithPosition(Compilation comp, Target target, 137 Expression position) 138 { 139 int line = position.getLineNumber (); 140 if (line > 0) 141 { 142 comp.getCode().putLineNumber(position.getFileName(), line); 143 compileNotePosition(comp, target, position); 144 } 145 else 146 compile(comp, target); 147 } 148 149 150 public final void compileNotePosition(Compilation comp, Target target, 151 Expression position) 152 { 153 String saveFilename = comp.getFileName(); 154 int saveLine = comp.getLineNumber(); 155 int saveColumn = comp.getColumnNumber(); 156 comp.setLine(position); 157 compile(comp, target); 158 comp.setLine(saveFilename, saveLine, saveColumn); 162 } 163 164 public final void compile (Compilation comp, Type type) 165 { 166 compile (comp, StackTarget.getInstance(type)); 168 } 169 170 175 public final void compile (Compilation comp, Declaration lhs) 176 { 177 compile (comp, 178 CheckedTarget.getInstance(lhs.getType(), 179 lhs.getName(), 180 WrongType.ARG_VARNAME)); 181 } 182 183 186 public static void compileButFirst (Expression exp, Compilation comp) 187 { 188 if (exp instanceof BeginExp) 189 { 190 BeginExp bexp = (BeginExp) exp; 191 int n = bexp.length; 192 if (n == 0) 193 return; 194 Expression[] exps = bexp.exps; 195 compileButFirst(exps[0], comp); 196 for (int i = 1; i < n; i++) 197 exps[i].compileWithPosition(comp, Target.Ignore); 198 } 199 } 200 201 protected Expression walk (ExpWalker walker) 202 { 203 return walker.walkExpression(this); 204 } 205 206 protected void walkChildren (ExpWalker walker) { } 207 208 217 public Expression inline (ApplyExp exp, InlineCalls walker, Declaration decl) 218 { 219 return exp; 220 } 221 222 String filename; 223 int position; 224 225 public static final Expression[] noExpressions = new Expression[0]; 226 227 228 public static Expression makeWhile(Object cond, Object body, Compilation parser) 229 { 230 Expression[] inits = new Expression[1]; 231 LetExp let = new LetExp(inits); 232 String fname = "%do%loop"; 233 Declaration fdecl = let.addDeclaration(fname); 234 Expression recurse = new ApplyExp(new ReferenceExp(fdecl), noExpressions); 235 LambdaExp lexp = new LambdaExp(); 236 parser.push(lexp); 237 lexp.body = new IfExp(parser.parse(cond), 238 new BeginExp(parser.parse(body), recurse), 239 QuoteExp.voidExp); 240 lexp.setName(fname); 241 parser.pop(lexp); 242 inits[0] = lexp; 243 fdecl.noteValue(lexp); 244 let.setBody(new ApplyExp(new ReferenceExp(fdecl), noExpressions)); 245 return let; 246 } 247 248 249 public final void setLocation (SourceLocator location) 250 { 251 this.filename = location.getFileName(); 252 setLine(location.getLineNumber(), location.getColumnNumber()); 253 } 254 255 public final Expression setLine(Expression old) 256 { 257 setLocation(old); 258 return this; 259 } 260 261 public final void setFile (String filename) 262 { 263 this.filename = filename; 264 } 265 266 public final void setLine (int lineno, int colno) 267 { 268 if (lineno < 0) 269 lineno = 0; 270 if (colno < 0) 271 colno = 0; 272 position = (lineno << 12) + colno; 273 } 274 275 public final void setLine (int lineno) 276 { 277 setLine (lineno, 0); 278 } 279 280 public final String getFileName () 281 { 282 return filename; 283 } 284 285 286 public void setLine (Compilation comp) 287 { 288 int line = comp.getLineNumber(); 289 if (line > 0) 290 { 291 setFile(comp.getFileName()); 292 setLine(line, comp.getColumnNumber()); 293 } 294 } 295 296 public String getPublicId () 297 { 298 return null; 299 } 300 301 public String getSystemId () 302 { 303 return filename; 304 } 305 306 308 public final int getLineNumber() 309 { 310 int line = position >> 12; 311 return line == 0 ? -1 : line; 312 } 313 314 public final int getColumnNumber() 315 { 316 int column = position & ((1 << 12) - 1); 317 return column == 0 ? -1 : column; 318 } 319 320 public boolean isStableSourceLocation() { return true; } 321 322 323 public Type getType() 324 { 325 return Type.pointer_type; 326 } 327 328 329 public Object valueIfConstant () 330 { 331 return null; 332 } 333 334 protected int flags; 335 protected static final int NEXT_AVAIL_FLAG = 1; 336 337 public void setFlag (boolean setting, int flag) 338 { 339 if (setting) flags |= flag; 340 else flags &= ~flag; 341 } 342 343 public void setFlag (int flag) 344 { 345 flags |= flag; 346 } 347 348 public int getFlags() 349 { 350 return flags; 351 } 352 353 public boolean getFlag (int flag) 354 { 355 return (flags & flag) != 0; 356 } 357 358 359 public boolean side_effects () { return true; } 360 361 public String toString () 362 { 363 String tname = getClass().getName(); 364 if (tname.startsWith("gnu.expr.")) 365 tname = tname.substring(9); 366 return tname+"@"+Integer.toHexString(hashCode()); 367 } 368 } 369 | Popular Tags |