1 21 22 package org.armedbear.lisp; 23 24 import java.io.BufferedReader ; 25 import java.io.File ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.InputStreamReader ; 29 import java.io.OutputStream ; 30 import java.lang.reflect.Method ; 31 32 public final class Interpreter extends Lisp 33 { 34 public static Interpreter interpreter; 36 37 private static int commandNumber; 38 39 private final boolean jlisp; 40 private final InputStream inputStream; 41 private final OutputStream outputStream; 42 43 public static synchronized Interpreter getInstance() 44 { 45 return interpreter; 46 } 47 48 public static synchronized Interpreter createInstance() 49 { 50 if (interpreter != null) 51 return null; 52 return interpreter = new Interpreter(); 53 } 54 55 public static synchronized Interpreter createInstance(InputStream in, 56 OutputStream out, String initialDirectory) 57 { 58 if (interpreter != null) 59 return null; 60 return interpreter = new Interpreter(in, out, initialDirectory); 61 } 62 63 private final Environment environment = new Environment(); 64 65 private Interpreter() 66 { 67 jlisp = false; 68 inputStream = null; 69 outputStream = null; 70 } 71 72 private Interpreter(InputStream inputStream, OutputStream outputStream, 73 String initialDirectory) 74 { 75 jlisp = true; 76 this.inputStream = inputStream; 77 this.outputStream = outputStream; 78 resetIO(new Stream(inputStream, Symbol.CHARACTER), 79 new Stream(outputStream, Symbol.CHARACTER)); 80 if (!initialDirectory.endsWith(File.separator)) 81 initialDirectory = initialDirectory.concat(File.separator); 82 try { 83 _DEFAULT_PATHNAME_DEFAULTS_.setSymbolValue(new Pathname(initialDirectory)); 84 } 85 catch (Throwable t) { 86 Debug.trace(t); 87 } 88 } 89 90 public static synchronized void initializeLisp(boolean jlisp) 91 { 92 if (!initialized) { 93 try { 94 if (jlisp) { 95 _FEATURES_.setSymbolValue(new Cons(Keyword.J, 96 _FEATURES_.getSymbolValue())); 97 } 98 Load.loadSystemFile("boot.lisp", false, false, false); 99 if (jlisp) { 100 Class.forName("org.armedbear.j.LispAPI"); 101 Load.loadSystemFile("j.lisp"); 102 } 103 } 104 catch (ConditionThrowable c) { 105 reportError(c, LispThread.currentThread()); 106 } 107 catch (Throwable t) { 108 t.printStackTrace(); 109 } 110 initialized = true; 111 } 112 } 113 114 private static boolean topLevelInitialized; 115 116 private static synchronized void initializeTopLevel() 117 { 118 if (!topLevelInitialized) { 119 try { 120 Symbol TOP_LEVEL_LOOP = intern("TOP-LEVEL-LOOP", PACKAGE_TPL); 122 LispObject tplFun = TOP_LEVEL_LOOP.getSymbolFunction(); 123 if (tplFun instanceof Autoload) { 124 Autoload autoload = (Autoload) tplFun; 125 autoload.load(); 126 } 127 do { 128 String userHome = System.getProperty("user.home"); 129 File file = new File (userHome, ".abclrc"); 130 if (file.isFile()) { 131 Load.load(file.getCanonicalPath()); 132 break; 133 } 134 if (Utilities.isPlatformWindows()) { 135 file = new File ("C:\\.abclrc"); 136 if (file.isFile()) { 137 Load.load(file.getCanonicalPath()); 138 break; 139 } 140 } 141 file = new File (userHome, ".ablrc"); 142 if (file.isFile()) { 143 String message = 144 "Warning: use of .ablrc is deprecated; use .abclrc instead."; 145 getStandardOutput()._writeLine(message); 146 Load.load(file.getCanonicalPath()); 147 break; 148 } 149 file = new File (userHome, ".ablisprc"); 150 if (file.isFile()) { 151 String message = 152 "Warning: use of .ablisprc is deprecated; use .abclrc instead."; 153 getStandardOutput()._writeLine(message); 154 Load.load(file.getCanonicalPath()); 155 break; 156 } 157 } while (false); 158 } 159 catch (Throwable t) { 160 t.printStackTrace(); 161 } 162 topLevelInitialized = true; 163 } 164 } 165 166 private void processCommandLineArguments(String [] args) 167 { 168 if (args.length > 0) { 169 for (int i = 0; i < args.length; ++i) { 170 String arg = args[i]; 171 if (arg.equals("--eval")) { 172 if (i + 1 < args.length) { 173 LispObject result = null; 174 try { 175 result = evaluate(args[i + 1]); 176 } 177 catch (ConditionThrowable c) { 178 System.err.println("Caught condition: " + 179 c.getCondition().toString() + 180 " while evaluating: " + 181 args[i+1]); 182 System.exit(2); 183 } 184 ++i; 185 } else { 186 System.err.println("No argument supplied to --eval"); 187 System.exit(1); 188 } 189 } else if (arg.equals("--load") || 190 arg.equals("--load-system-file")) { 191 if (i + 1 < args.length) { 192 try { 193 if (arg.equals("--load")) 194 Load.load(args[i + 1], false, false, true); 195 else 196 Load.loadSystemFile(args[i + 1]); 197 } 198 catch (ConditionThrowable c) { 199 System.err.println("Caught condition: " + 200 c.getCondition().toString() + 201 " while loading: " + 202 args[i+1]); 203 System.exit(2); 204 } 205 ++i; 206 } else { 207 System.err.println("No argument supplied to --load"); 208 System.exit(1); 209 } 210 } 211 } 212 } 213 } 214 215 public void run(String [] args) 216 { 217 LispThread thread = null; 218 try { 219 thread = LispThread.currentThread(); 220 } 221 catch (Throwable t) { 222 return; 223 } 224 commandNumber = 0; 225 try { 226 Stream out = getStandardOutput(); 227 out._writeString(banner()); 228 out._finishOutput(); 229 if (Utilities.isPlatformUnix()) { 230 try { 231 System.loadLibrary("abcl"); 232 Class c = Class.forName("org.armedbear.lisp.ControlC"); 233 Method m = c.getMethod("initialize", null); 234 m.invoke(null, null); 235 out._writeString("Control-C handler installed.\n"); 236 } 237 catch (Throwable t) {} 238 } 239 if (!jlisp) { 240 double uptime = (System.currentTimeMillis() - Main.startTimeMillis) / 1000.0; 241 System.out.println("Low-level initialization completed in " + 242 uptime + " seconds."); 243 } 244 initializeLisp(jlisp); 245 initializeTopLevel(); 246 if (args != null) 247 processCommandLineArguments(args); 248 Symbol TOP_LEVEL_LOOP = intern("TOP-LEVEL-LOOP", PACKAGE_TPL); 249 LispObject tplFun = TOP_LEVEL_LOOP.getSymbolFunction(); 250 if (tplFun instanceof Function) { 251 funcall0(tplFun, thread); 252 return; 253 } 254 while (true) { 255 try { 256 thread.resetStack(); 257 thread.setDynamicEnvironment(null); 258 ++commandNumber; 259 out._writeString(prompt()); 260 out._finishOutput(); 261 LispObject 262 object = getStandardInput().read(false, EOF, false); if (object == EOF) 264 break; 265 out.setCharPos(0); 266 Symbol.MINUS.setSymbolValue(object); 267 LispObject result = eval(object, environment, thread); 268 Debug.assertTrue(result != null); 269 Symbol.STAR_STAR_STAR.setSymbolValue(Symbol.STAR_STAR.getSymbolValue()); 270 Symbol.STAR_STAR.setSymbolValue(Symbol.STAR.getSymbolValue()); 271 Symbol.STAR.setSymbolValue(result); 272 Symbol.PLUS_PLUS_PLUS.setSymbolValue(Symbol.PLUS_PLUS.getSymbolValue()); 273 Symbol.PLUS_PLUS.setSymbolValue(Symbol.PLUS.getSymbolValue()); 274 Symbol.PLUS.setSymbolValue(Symbol.MINUS.getSymbolValue()); 275 out = getStandardOutput(); 276 out.freshLine(); 277 LispObject[] values = thread.getValues(); 278 Symbol.SLASH_SLASH_SLASH.setSymbolValue(Symbol.SLASH_SLASH.getSymbolValue()); 279 Symbol.SLASH_SLASH.setSymbolValue(Symbol.SLASH.getSymbolValue()); 280 if (values != null) { 281 LispObject slash = NIL; 282 for (int i = values.length; i-- > 0;) 283 slash = new Cons(values[i], slash); 284 Symbol.SLASH.setSymbolValue(slash); 285 for (int i = 0; i < values.length; i++) 286 out._writeLine(values[i].writeToString()); 287 } else { 288 Symbol.SLASH.setSymbolValue(new Cons(result)); 289 out._writeLine(result.writeToString()); 290 } 291 out._finishOutput(); 292 } 293 catch (StackOverflowError e) { 294 getStandardInput().clearInput(); 295 out._writeLine("Stack overflow"); 296 } 297 catch (ConditionThrowable c) { 298 reportError(c, thread); 299 } 300 catch (Throwable t) { 301 getStandardInput().clearInput(); 302 out.printStackTrace(t); 303 thread.backtrace(); 304 } 305 } 306 } 307 catch (Throwable t) { 308 t.printStackTrace(); 309 } 310 } 311 312 private static void reportError(ConditionThrowable c, LispThread thread) 313 { 314 try { 315 getStandardInput().clearInput(); 316 Stream out = getStandardOutput(); 317 out.freshLine(); 318 Condition condition = (Condition) c.getCondition(); 319 out._writeLine("Error: unhandled condition: " + 320 condition.getConditionReport()); 321 if (thread != null) 322 thread.backtrace(); 323 } 324 catch (Throwable t) { 325 ; 326 } 327 } 328 329 public void kill() 330 { 331 if (jlisp) { 332 try { 333 inputStream.close(); 334 } 335 catch (IOException e) { 336 Debug.trace(e); 337 } 338 try { 339 outputStream.close(); 340 } 341 catch (IOException e) { 342 Debug.trace(e); 343 } 344 } else 345 System.exit(0); 346 } 347 348 public synchronized void dispose() 349 { 350 Debug.trace("Interpreter.dispose"); 351 Debug.assertTrue(interpreter == this); 352 interpreter = null; 353 } 354 355 protected void finalize() throws Throwable 356 { 357 System.err.println("Interpreter.finalize"); 358 } 359 360 private static final Primitive2 _DEBUGGER_HOOK_FUNCTION = 361 new Primitive2("%debugger-hook-function", PACKAGE_SYS, false) 362 { 363 public LispObject execute(LispObject first, LispObject second) 364 throws ConditionThrowable 365 { 366 throw new ConditionThrowable((Condition)first); 367 } 368 }; 369 370 public static LispObject evaluate(String s) throws ConditionThrowable 372 { 373 if (!initialized) 374 initializeLisp(true); 375 StringInputStream stream = new StringInputStream(s); 376 LispObject obj = stream.read(false, EOF, false); 377 if (obj == EOF) 378 return signal(new EndOfFile(stream)); 379 final LispThread thread = LispThread.currentThread(); 380 final Environment oldDynEnv = thread.getDynamicEnvironment(); 381 thread.bindSpecial(_DEBUGGER_HOOK_, _DEBUGGER_HOOK_FUNCTION); 382 try { 383 return eval(obj, new Environment(), thread); 384 } 385 finally { 386 thread.setDynamicEnvironment(oldDynEnv); 387 } 388 } 389 390 private static final String build; 391 392 static { 393 String s = null; 394 InputStream in = Interpreter.class.getResourceAsStream("build"); 395 if (in != null) { 396 try { 397 BufferedReader reader = 398 new BufferedReader (new InputStreamReader (in)); 399 s = reader.readLine(); 400 reader.close(); 401 } 402 catch (IOException e) {} 403 } 404 build = s; 405 } 406 407 private static String banner() 408 { 409 final String sep = System.getProperty("line.separator"); 410 StringBuffer sb = new StringBuffer ("Armed Bear Common Lisp "); 411 sb.append(Version.getVersion()); 412 if (build != null) { 413 sb.append(" (built "); 414 sb.append(build); 415 sb.append(')'); 416 } 417 sb.append(sep); 418 sb.append("Java "); 419 sb.append(System.getProperty("java.version")); 420 sb.append(' '); 421 sb.append(System.getProperty("java.vendor")); 422 sb.append(sep); 423 String vm = System.getProperty("java.vm.name"); 424 if (vm != null) { 425 sb.append(vm); 426 sb.append(sep); 427 } 428 return sb.toString(); 429 } 430 431 private static String prompt() 432 { 433 Package pkg = (Package ) _PACKAGE_.getSymbolValue(); 434 String pkgName = pkg.getNickname(); 435 if (pkgName == null) 436 pkgName = pkg.getName(); 437 StringBuffer sb = new StringBuffer (); 438 sb.append(pkgName); 439 sb.append('('); 440 sb.append(commandNumber); 441 sb.append(")> "); 442 return sb.toString(); 443 } 444 } 445 | Popular Tags |