1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
|
/* xlisp.c - a small implementation of lisp with object-oriented programming */
/* Copyright (c) 1989, by David Michael Betz. */
/* You may give out copies of this software; for conditions see the file */
/* COPYING included with this distribution. */
/* For full credits see file xlisp.h */
#include "xlisp.h"
/* define the banner line string */
#define BANNER "XLISP-PLUS version 3.04\n\
Portions Copyright (c) 1988, by David Betz.\n\
Modified by Thomas Almy and others."
/* global variables */
#ifdef SAVERESTORE
jmp_buf top_level;
#endif
char *progname; /* used for reading the symbol table - L. Tierney */
#ifdef SAVERESTORE
char *resfile = "xlisp.wks"; /* make extern to allow setting elsewhere */
#endif
/* local variables */
jmp_buf exit_xlisp;
/* forward declarations */
#ifdef MACINTOSH
int main(void);
#else
int main _((int argc, char *argv[]));
#endif /* MACINTOSH */
LOCAL VOID toplevelloop(V);
/* main - the main routine */
#ifdef MACINTOSH
int main(void)
#else
int main(argc,argv)
int argc; char *argv[];
#endif /* MACINTOSH */
{
char *transcript;
CONTEXT cntxt;
int verbose,i, sts;
struct { char *transcript; int verbose, i; } state;
#ifdef AMIGA
char project[30],defdir[50];
#endif /* AMIGA */
/* The way out on errors */
i = setjmp(exit_xlisp);
if (i != 0)
return i-1;
/* setup default argument values */
transcript = NULL;
verbose = FALSE;
#ifdef FILETABLE
/* Initialize the file table values */
filetab[0].fp = stdin;
filetab[0].tname = "(stdin)";
filetab[1].fp = stdout;
filetab[1].tname = "(stdout)";
filetab[2].fp = stderr;
filetab[2].tname = "(console)";
filetab[3].fp = NULL;
filetab[3].tname = "";
#endif
/* parse the argument list switches */
#ifndef MACINTOSH
#ifdef AMIGA
FindStart(&argc,argv,deftool,project,defdir);
#endif /* AMIGA */
progname = argv[0]; /* L. Tierney */
for (i = 1; i < argc; ++i)
if (argv[i][0] == '-')
switch(isupper(argv[i][1])?tolower(argv[i][1]):argv[i][1]) {
case 't':
transcript = &argv[i][2];
break;
case 'b':
batchmode = TRUE;
break;
case 'v':
verbose = TRUE;
break;
#ifdef SAVERESTORE
case 'w':
resfile = &argv[i][2];
break;
#endif
#ifdef XLISP_STAT
case 'p':
defaultpath = &argv[i][2];
break;
#endif /* XLISP_STAT */
#ifndef _Windows
default: /* Added to print bad switch message */
fprintf(stderr,"Bad switch: %s\n",argv[i]);
#endif
}
#endif /* MACINTOSH */
/* initialize and print the banner line */
osinit(BANNER);
/* setup initialization error handler */
xlbegin(&cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,(LVAL)1);
state.transcript = transcript; state.verbose = verbose; state.i = i;
sts = setjmp(cntxt.c_jmpbuf);
transcript = state.transcript; verbose = state.verbose; i = state.i;
if (sts)
xlfatal("fatal initialization error");
#ifdef SAVERESTORE
state.transcript = transcript; state.verbose = verbose; state.i = i;
sts = setjmp(top_level);
transcript = state.transcript; verbose = state.verbose; i = state.i;
if (sts)
xlfatal("RESTORE not allowed during initialization");
#endif
/* initialize xlisp */
#ifdef SAVERESTORE
#ifdef MACINTOSH
i = macxlinit(resfile);
#else
i = xlinit(resfile);
#endif /* MACINTOSH */
#else
i = xlinit(NULL);
#endif
/* reset the error handler, since we know what "true" is */
xlend(&cntxt);
xlbegin(&cntxt, CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL, s_true);
/* open the transcript file */
if (transcript!=NULL && (tfp = OSAOPEN(transcript,CREATE_WR)) == CLOSED) {
/* TAA Mod -- quote name so "-t foo" will indicate no file name */
sprintf(buf,"error: can't open transcript file: \"%s\"",transcript);
stdputstr(buf);
}
#ifndef MACINTOSH
/* enter the command line (L. Tierney 9/93) */
state.transcript = transcript; state.verbose = verbose; state.i = i;
sts = setjmp(cntxt.c_jmpbuf);
transcript = state.transcript; verbose = state.verbose; i = state.i;
if (sts == 0) {
LVAL line;
int j;
xlsave1(line);
line = NIL;
for (j = argc - 1; j >= 0; j--)
line = cons(cvstring(argv[j]), line);
xlpop();
setsvalue(s_command_line, line);
}
#endif /* MACINTOSH */
enable_interrupts();
/* load "init.lsp" */
if (i) {
state.transcript = transcript; state.verbose = verbose; state.i = i;
sts = setjmp(cntxt.c_jmpbuf);
transcript = state.transcript; verbose = state.verbose; i = state.i;
if (sts == 0)
xsload("init.lsp",TRUE,FALSE);
}
/* run any startup functions (L. Tierney 9/93) */
state.transcript = transcript; state.verbose = verbose; state.i = i;
sts = setjmp(cntxt.c_jmpbuf);
transcript = state.transcript; verbose = state.verbose; i = state.i;
if (sts == 0) {
LVAL funs = getvalue(s_startup_functions);
FRAMEP newfp;
for (; consp(funs); funs = cdr(funs)) {
newfp = xlsp;
pusharg(cvfixnum((FIXTYPE)(newfp - xlfp)));
pusharg(car(funs));
pusharg(cvfixnum((FIXTYPE) 0));
xlfp = newfp;
xlapply(0);
}
}
/* load any files mentioned on the command line */
if (! null(getvalue(s_loadfileargs))) {
state.transcript = transcript; state.verbose = verbose; state.i = i;
sts = setjmp(cntxt.c_jmpbuf);
transcript = state.transcript; verbose = state.verbose; i = state.i;
if (sts == 0) {
#ifdef MACINTOSH
macloadinits();
#else
for (i = 1; i < argc; i++)
if (argv[i][0] != '-' && !xsload(argv[i],TRUE,verbose))
xlerror("can't load file",cvstring(argv[i]));
#endif /* MACINTOSH */
}
}
/* target for restore */
#ifdef SAVERESTORE
state.transcript = transcript; state.verbose = verbose; state.i = i;
sts = setjmp(top_level);
transcript = state.transcript; verbose = state.verbose; i = state.i;
if (sts)
xlbegin(&cntxt, CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL, s_true);
#endif
/* main command processing loop */
for (;;) {
/* setup the error return */
if (setjmp(cntxt.c_jmpbuf)) {
setvalue(s_evalhook,NIL);
setvalue(s_applyhook,NIL);
xltrcindent = 0;
xldebug = 0;
osreset(); /* L. Tierney */
xlflush();
}
#ifdef STSZ
stackwarn = FALSE;
#endif
if (boundp(s_toplevelloop)) {
FRAMEP newfp;
newfp = xlsp;
pusharg(cvfixnum((FIXTYPE)(newfp - xlfp)));
pusharg(getvalue(s_toplevelloop));
pusharg(cvfixnum((FIXTYPE) 0));
xlfp = newfp;
xlapply(0);
}
else
toplevelloop();
} /* never exit from here */
}
/* xtoplevelloop - lisp-callable top level loop */
/* Luke Tierney 9/93 */
LVAL xtoplevelloop(V)
{
xllastarg();
toplevelloop();
return(NIL); /* doesn't return */
}
/* toplevelloop - the default command loop */
LOCAL VOID toplevelloop(V)
{
LVAL expr;
#ifdef MULVALS
int i;
#endif /* MULVALS */
/* protect some pointers */
xlsave1(expr);
for(;;) {
/* print a prompt */
#ifdef PACKAGES
if (!redirectin) {
LVAL pack = getvalue(s_package);
if (pack != xluserpack && goodpackagep(pack)) {
dbgputstr(getstring(xlpackagename(pack)));
}
dbgputstr("> ");
}
#else
if (!redirectin) dbgputstr("> ");
#endif /* PACKAGES */
/* read an expression */
if (!xlread(getvalue(s_stdin),&expr,FALSE,FALSE)) {
/* clean up */
wrapup();
break;
}
/* save the input expression */
xlrdsave(expr);
/* evaluate the expression */
expr = xleval(expr);
/* save the result */
xlevsave(expr);
/* Show result on a new line -- TAA MOD to improve display */
xlfreshline(getvalue(s_stdout));
/* print it */
#ifdef MULVALS
switch (xlnumresults) {
case 0: break;
case 1: stdprint(expr); break;
default:
{
LVAL vals;
xlsave1(vals);
for (i = xlnumresults; i-- > 0; ) vals = cons(xlresults[i], vals);
for (; consp(vals); vals = cdr(vals)) stdprint(car(vals));
xlpop();
}
}
#else
stdprint(expr);
#endif /* MULVALS */
}
}
/* xlrdsave - save the last expression returned by the reader */
VOID xlrdsave P1C(LVAL, expr)
{
setvalue(s_3plus,getvalue(s_2plus));
setvalue(s_2plus,getvalue(s_1plus));
setvalue(s_1plus,getvalue(s_minus));
setvalue(s_minus,expr);
}
/* xlevsave - save the last expression returned by the evaluator */
VOID xlevsave P1C(LVAL, expr)
{
setvalue(s_3star,getvalue(s_2star));
setvalue(s_2star,getvalue(s_1star));
setvalue(s_1star,expr);
}
/* xlfatal - print a fatal error message and exit */
VOID xlfatal P1C(char *, msg)
{
xoserror(msg);
wrapup();
}
/* wrapup - clean up and exit to the operating system */
VOID wrapup(V)
{
/* $putpatch.c$: "MODULE_XLISP_C_WRAPUP" */
CONTEXT cntxt;
xlbegin(&cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,s_true);
if (setjmp(cntxt.c_jmpbuf) == 0) {
if (tfp != CLOSED)
OSCLOSE(tfp);
osfinish();
}
longjmp(exit_xlisp, 1);
}
/* xresetsystem - reset system for user top-levels */
LVAL xresetsystem(V)
{
osreset(); /* L. Tierney */
xlflush();
return(NIL);
}
/* new internal load function -- allows load to be redefined in workspace */
int xsload P3C(char *, name, int, vflag, int, pflag)
{
if (fboundp(s_load)) {
FRAMEP newfp;
/* create the new call frame */
newfp = xlsp;
pusharg(cvfixnum((FIXTYPE)(newfp - xlfp)));
pusharg(getfunction(s_load));
pusharg(cvfixnum((FIXTYPE) 7));
pusharg(cvstring(name));
pusharg(k_print);
pusharg(pflag ? s_true : NIL);
pusharg(k_verbose);
pusharg(vflag ? s_true : NIL);
pusharg(k_nexist);
pusharg(NIL);
xlfp = newfp;
/* return the result of applying the function */
return null(xlapply(7)) ? FALSE : TRUE;
}
else
return xlload(name, pflag, vflag);
}
|