1 /* xlisp.c - a small implementation of lisp with object-oriented programming */
2 /* Copyright (c) 1989, by David Michael Betz. */
3 /* You may give out copies of this software; for conditions see the file */
4 /* COPYING included with this distribution. */
6 /* For full credits see file xlisp.h */
10 /* define the banner line string */
11 #define BANNER "XLISP-PLUS version 3.04\n\
12 Portions Copyright (c) 1988, by David Betz.\n\
13 Modified by Thomas Almy and others."
15 /* global variables */
19 char *progname
; /* used for reading the symbol table - L. Tierney */
21 char *resfile
= "xlisp.wks"; /* make extern to allow setting elsewhere */
25 XL_JMP_BUF exit_xlisp
;
27 /* forward declarations */
31 int main
_((int argc
, char *argv
[]));
32 #endif /* MACINTOSH */
33 LOCAL VOID
toplevelloop(V
);
35 /* main - the main routine */
40 int argc
; char *argv
[];
41 #endif /* MACINTOSH */
46 struct { char *transcript
; int verbose
, i
; } state
;
48 char project
[30],defdir
[50];
51 /* The way out on errors */
52 i
= XL_SETJMP(exit_xlisp
);
56 /* setup default argument values */
61 /* Initialize the file table values */
62 filetab
[0].fp
= stdin
;
63 filetab
[0].tname
= "(stdin)";
64 filetab
[1].fp
= stdout
;
65 filetab
[1].tname
= "(stdout)";
66 filetab
[2].fp
= stderr
;
67 filetab
[2].tname
= "(console)";
69 filetab
[3].tname
= "";
72 /* parse the argument list switches */
75 FindStart(&argc
,argv
,deftool
,project
,defdir
);
77 progname
= argv
[0]; /* L. Tierney */
78 for (i
= 1; i
< argc
; ++i
)
79 if (argv
[i
][0] == '-')
80 switch(isupper(argv
[i
][1])?tolower(argv
[i
][1]):argv
[i
][1]) {
82 transcript
= &argv
[i
][2];
92 resfile
= &argv
[i
][2];
97 defaultpath
= &argv
[i
][2];
99 #endif /* XLISP_STAT */
101 default: /* Added to print bad switch message */
102 fprintf(stderr
,"Bad switch: %s\n",argv
[i
]);
105 #endif /* MACINTOSH */
107 /* initialize and print the banner line */
110 /* setup initialization error handler */
111 xlbegin(&cntxt
,CF_TOPLEVEL
|CF_CLEANUP
|CF_BRKLEVEL
,(LVAL
)1);
112 state
.transcript
= transcript
; state
.verbose
= verbose
; state
.i
= i
;
113 sts
= XL_SETJMP(cntxt
.c_jmpbuf
);
114 transcript
= state
.transcript
; verbose
= state
.verbose
; i
= state
.i
;
116 xlfatal("fatal initialization error");
118 state
.transcript
= transcript
; state
.verbose
= verbose
; state
.i
= i
;
119 sts
= XL_SETJMP(top_level
);
120 transcript
= state
.transcript
; verbose
= state
.verbose
; i
= state
.i
;
122 xlfatal("RESTORE not allowed during initialization");
125 /* initialize xlisp */
128 i
= macxlinit(resfile
);
131 #endif /* MACINTOSH */
136 /* reset the error handler, since we know what "true" is */
138 xlbegin(&cntxt
, CF_TOPLEVEL
|CF_CLEANUP
|CF_BRKLEVEL
, s_true
);
140 /* open the transcript file */
141 if (transcript
!=NULL
&& (tfp
= OSAOPEN(transcript
,CREATE_WR
)) == CLOSED
) {
142 /* TAA Mod -- quote name so "-t foo" will indicate no file name */
143 sprintf(buf
,"error: can't open transcript file: \"%s\"",transcript
);
148 /* enter the command line (L. Tierney 9/93) */
149 state
.transcript
= transcript
; state
.verbose
= verbose
; state
.i
= i
;
150 sts
= XL_SETJMP(cntxt
.c_jmpbuf
);
151 transcript
= state
.transcript
; verbose
= state
.verbose
; i
= state
.i
;
157 for (j
= argc
- 1; j
>= 0; j
--)
158 line
= cons(cvstring(argv
[j
]), line
);
160 setsvalue(s_command_line
, line
);
162 #endif /* MACINTOSH */
166 /* load "init.lsp" */
168 state
.transcript
= transcript
; state
.verbose
= verbose
; state
.i
= i
;
169 sts
= XL_SETJMP(cntxt
.c_jmpbuf
);
170 transcript
= state
.transcript
; verbose
= state
.verbose
; i
= state
.i
;
172 xsload("init.lsp",TRUE
,FALSE
);
175 /* run any startup functions (L. Tierney 9/93) */
176 state
.transcript
= transcript
; state
.verbose
= verbose
; state
.i
= i
;
177 sts
= XL_SETJMP(cntxt
.c_jmpbuf
);
178 transcript
= state
.transcript
; verbose
= state
.verbose
; i
= state
.i
;
180 LVAL funs
= getvalue(s_startup_functions
);
183 for (; consp(funs
); funs
= cdr(funs
)) {
185 pusharg(cvfixnum((FIXTYPE
)(newfp
- xlfp
)));
187 pusharg(cvfixnum((FIXTYPE
) 0));
193 /* load any files mentioned on the command line */
194 if (! null(getvalue(s_loadfileargs
))) {
195 state
.transcript
= transcript
; state
.verbose
= verbose
; state
.i
= i
;
196 sts
= XL_SETJMP(cntxt
.c_jmpbuf
);
197 transcript
= state
.transcript
; verbose
= state
.verbose
; i
= state
.i
;
202 for (i
= 1; i
< argc
; i
++)
203 if (argv
[i
][0] != '-' && !xsload(argv
[i
],TRUE
,verbose
))
204 xlerror("can't load file",cvstring(argv
[i
]));
205 #endif /* MACINTOSH */
209 /* target for restore */
211 state
.transcript
= transcript
; state
.verbose
= verbose
; state
.i
= i
;
212 sts
= XL_SETJMP(top_level
);
213 transcript
= state
.transcript
; verbose
= state
.verbose
; i
= state
.i
;
215 xlbegin(&cntxt
, CF_TOPLEVEL
|CF_CLEANUP
|CF_BRKLEVEL
, s_true
);
218 /* main command processing loop */
221 /* setup the error return */
222 if (XL_SETJMP(cntxt
.c_jmpbuf
)) {
223 setvalue(s_evalhook
,NIL
);
224 setvalue(s_applyhook
,NIL
);
227 osreset(); /* L. Tierney */
235 if (boundp(s_toplevelloop
)) {
239 pusharg(cvfixnum((FIXTYPE
)(newfp
- xlfp
)));
240 pusharg(getvalue(s_toplevelloop
));
241 pusharg(cvfixnum((FIXTYPE
) 0));
247 } /* never exit from here */
250 /* xtoplevelloop - lisp-callable top level loop */
251 /* Luke Tierney 9/93 */
252 LVAL
xtoplevelloop(V
)
257 return(NIL
); /* doesn't return */
260 /* toplevelloop - the default command loop */
261 LOCAL VOID
toplevelloop(V
)
268 /* protect some pointers */
275 LVAL pack
= getvalue(s_package
);
276 if (pack
!= xluserpack
&& goodpackagep(pack
)) {
277 dbgputstr(getstring(xlpackagename(pack
)));
282 if (!redirectin
) dbgputstr("> ");
283 #endif /* PACKAGES */
285 /* read an expression */
286 if (!xlread(getvalue(s_stdin
),&expr
,FALSE
,FALSE
)) {
292 /* save the input expression */
295 /* evaluate the expression */
298 /* save the result */
301 /* Show result on a new line -- TAA MOD to improve display */
302 xlfreshline(getvalue(s_stdout
));
306 switch (xlnumresults
) {
308 case 1: stdprint(expr
); break;
313 for (i
= xlnumresults
; i
-- > 0; ) vals
= cons(xlresults
[i
], vals
);
314 for (; consp(vals
); vals
= cdr(vals
)) stdprint(car(vals
));
324 /* xlrdsave - save the last expression returned by the reader */
325 VOID xlrdsave
P1C(LVAL
, expr
)
327 setvalue(s_3plus
,getvalue(s_2plus
));
328 setvalue(s_2plus
,getvalue(s_1plus
));
329 setvalue(s_1plus
,getvalue(s_minus
));
330 setvalue(s_minus
,expr
);
333 /* xlevsave - save the last expression returned by the evaluator */
334 VOID xlevsave
P1C(LVAL
, expr
)
336 setvalue(s_3star
,getvalue(s_2star
));
337 setvalue(s_2star
,getvalue(s_1star
));
338 setvalue(s_1star
,expr
);
341 /* xlfatal - print a fatal error message and exit */
342 VOID xlfatal
P1C(char *, msg
)
348 /* do-exits - run user exit functions */
353 xlbegin(&cntxt
,CF_TOPLEVEL
|CF_CLEANUP
|CF_BRKLEVEL
,s_true
);
354 XL_SETJMP(cntxt
.c_jmpbuf
);
356 while (s_exit_functions
!= NULL
&& consp(getvalue(s_exit_functions
))) {
358 LVAL func
= car(getvalue(s_exit_functions
));
359 setvalue(s_exit_functions
, cdr(getvalue(s_exit_functions
)));
361 pusharg(cvfixnum((FIXTYPE
)(newfp
- xlfp
)));
363 pusharg(cvfixnum((FIXTYPE
) 0));
370 /* wrapup - clean up and exit to the operating system */
373 /* $putpatch.c$: "MODULE_XLISP_C_WRAPUP" */
377 if (XL_SETJMP(cntxt
.c_jmpbuf
) == 0) {
382 XL_LONGJMP(exit_xlisp
, 1);
385 /* xresetsystem - reset system for user top-levels */
388 osreset(); /* L. Tierney */
393 /* new internal load function -- allows load to be redefined in workspace */
394 int xsload
P3C(char *, name
, int, vflag
, int, pflag
)
396 if (fboundp(s_load
)) {
399 /* create the new call frame */
401 pusharg(cvfixnum((FIXTYPE
)(newfp
- xlfp
)));
402 pusharg(getfunction(s_load
));
403 pusharg(cvfixnum((FIXTYPE
) 7));
404 pusharg(cvstring(name
));
406 pusharg(pflag
? s_true
: NIL
);
408 pusharg(vflag
? s_true
: NIL
);
413 /* return the result of applying the function */
414 return null(xlapply(7)) ? FALSE
: TRUE
;
417 return xlload(name
, pflag
, vflag
);