KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > Interpreter


1 /*
2  * Interpreter.java
3  *
4  * Copyright (C) 2002-2004 Peter Graves
5  * $Id: Interpreter.java,v 1.73 2004/09/15 17:52:50 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.lisp;
23
24 import java.io.BufferedReader JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.io.OutputStream JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31
32 public final class Interpreter extends Lisp
33 {
34     // There can only be one interpreter.
35
public static Interpreter interpreter;
36
37     private static int commandNumber;
38
39     private final boolean jlisp;
40     private final InputStream JavaDoc inputStream;
41     private final OutputStream JavaDoc 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 JavaDoc in,
56         OutputStream JavaDoc out, String JavaDoc 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 JavaDoc inputStream, OutputStream JavaDoc outputStream,
73                         String JavaDoc 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 JavaDoc 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 JavaDoc 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                 // Resolve top-level-loop autoload.
121
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 JavaDoc userHome = System.getProperty("user.home");
129                     File JavaDoc file = new File JavaDoc(userHome, ".abclrc");
130                     if (file.isFile()) {
131                         Load.load(file.getCanonicalPath());
132                         break;
133                     }
134                     if (Utilities.isPlatformWindows()) {
135                         file = new File JavaDoc("C:\\.abclrc");
136                         if (file.isFile()) {
137                             Load.load(file.getCanonicalPath());
138                             break;
139                         }
140                     }
141                     file = new File JavaDoc(userHome, ".ablrc");
142                     if (file.isFile()) {
143                         String JavaDoc 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 JavaDoc(userHome, ".ablisprc");
150                     if (file.isFile()) {
151                         String JavaDoc 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 JavaDoc t) {
160                 t.printStackTrace();
161             }
162             topLevelInitialized = true;
163         }
164     }
165
166     private void processCommandLineArguments(String JavaDoc[] args)
167     {
168         if (args.length > 0) {
169             for (int i = 0; i < args.length; ++i) {
170                 String JavaDoc 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 JavaDoc[] args)
216     {
217         LispThread thread = null;
218         try {
219             thread = LispThread.currentThread();
220         }
221         catch (Throwable JavaDoc 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 JavaDoc c = Class.forName("org.armedbear.lisp.ControlC");
233                     Method JavaDoc m = c.getMethod("initialize", null);
234                     m.invoke(null, null);
235                     out._writeString("Control-C handler installed.\n");
236                 }
237                 catch (Throwable JavaDoc 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); // Top level read.
263
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 JavaDoc e) {
294                     getStandardInput().clearInput();
295                     out._writeLine("Stack overflow");
296                 }
297                 catch (ConditionThrowable c) {
298                     reportError(c, thread);
299                 }
300                 catch (Throwable JavaDoc t) {
301                     getStandardInput().clearInput();
302                     out.printStackTrace(t);
303                     thread.backtrace();
304                 }
305             }
306         }
307         catch (Throwable JavaDoc 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 JavaDoc t) {
325             ;
326         }
327     }
328
329     public void kill()
330     {
331         if (jlisp) {
332             try {
333                 inputStream.close();
334             }
335             catch (IOException JavaDoc e) {
336                 Debug.trace(e);
337             }
338             try {
339                 outputStream.close();
340             }
341             catch (IOException JavaDoc 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 JavaDoc
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     // Used only by org.armedbear.j.Editor.executeCommand().
371
public static LispObject evaluate(String JavaDoc 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 JavaDoc build;
391
392     static {
393         String JavaDoc s = null;
394         InputStream JavaDoc in = Interpreter.class.getResourceAsStream("build");
395         if (in != null) {
396             try {
397                 BufferedReader JavaDoc reader =
398                     new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in));
399                 s = reader.readLine();
400                 reader.close();
401             }
402             catch (IOException JavaDoc e) {}
403         }
404         build = s;
405     }
406
407     private static String JavaDoc banner()
408     {
409         final String JavaDoc sep = System.getProperty("line.separator");
410         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("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 JavaDoc 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 JavaDoc prompt()
432     {
433         Package JavaDoc pkg = (Package JavaDoc) _PACKAGE_.getSymbolValue();
434         String JavaDoc pkgName = pkg.getNickname();
435         if (pkgName == null)
436             pkgName = pkg.getName();
437         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
438         sb.append(pkgName);
439         sb.append('(');
440         sb.append(commandNumber);
441         sb.append(")> ");
442         return sb.toString();
443     }
444 }
445
Popular Tags