File: xlisp.c

package info (click to toggle)
audacity 2.1.2-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 86,844 kB
  • sloc: ansic: 225,005; cpp: 221,240; sh: 27,327; python: 16,896; makefile: 8,186; lisp: 8,002; perl: 317; xml: 307; sed: 16
file content (319 lines) | stat: -rw-r--r-- 7,892 bytes parent folder | download | duplicates (2)
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
/* xlisp.c - a small implementation of lisp with object-oriented programming */
/*	Copyright (c) 1987, by David Michael Betz
        All Rights Reserved
        Permission is granted for unrestricted non-commercial use	*/

/* CHANGELOG:
  8 Oct 90 (Dannenberg) changed main() to xlisp_main_init and xlisp_main.
               made xlisp run as a module that evaluates expressions and
               retains state
 */

#include "switches.h"
#include "stdlib.h"	/* declares exit() */
#include "cext.h"
#include "xlisp.h"
#ifdef MACINTOSH
#include "Memory.h"
#endif

FORWARD void xlisp_wrapup(void);

/* define the banner line string */
#ifdef EXT
#ifdef NYQUIST
#define BANNER "XLISP version 2.0, Copyright (c) 1986, by David Betz"
#else
#define BANNER "Music Editor, Copyright (c) 1987, by Roger B. Dannenberg\n\
XLISP version 2.0, Copyright (c) 1986, by David Betz"
#endif
#else
#ifdef CMTSTUFF
#define BANNER "XLISP version 2.0, Copyright (c) 1986, by David Betz\n\
CMU MIDI Toolkit, Copyright (c) 1993,1994, by Roger B. Dannenberg"
#else
#define BANNER "XLISP version 2.0, Copyright (c) 1986, by David Betz"
#endif
#endif

/* global variables */
jmp_buf top_level;
int in_a_context = FALSE;
int xl_main_loop = FALSE;

/* external variables */
extern LVAL s_stdin,s_evalhook,s_applyhook;
extern LVAL s_1plus,s_2plus,s_3plus,s_1star,s_2star,s_3star,s_minus;
extern int xltrcindent;
extern int xldebug;
extern LVAL s_true;
extern char buf[];
extern FILE *tfp;

/* external routines */
extern FILE *osaopen();

#ifdef USE_RANDOM

/* use a fast (but not particularly good) random number generator */

long randomseed = 1L;

long random() {
// note that this takes a seed and returns a big number,
// whereas I think XLisp's RANDOM is defined differently
    long k1;

    /* algorithm taken from Dr. Dobbs Journal, November 1985, page 91 */
    k1 = randomseed / 127773L;
    if ((randomseed = 16807L * (randomseed - k1 * 127773L) - k1 * 2836L) < 0L)
      randomseed += 2147483647L;

    /* return a random number between 0 and MAXFIX */
    return randomseed;
}
#endif

/* xlrand - return next random number in sequence */
long xlrand (long range) {
    if (range == 0) return 0;
#ifdef USE_RAND
    return rand() % range;
#endif
#ifdef USE_RANDOM
    return random() % range;
#endif
}

/* xlrealrand - return random number in [0, 1] */
double xlrealrand() {
    /* always use the random generator from the C library,
       (do not use random() even if USE_RANDOM is defined */
    return (double) rand() / RAND_MAX;
}

/* xlisp_main_init - the main initialization routine */
void xlisp_main_init(int argc, char *argv[])
{
    char *transcript;
    XLCONTEXT cntxt;
    int verbose,i;
         
    /* setup default argument values */
    transcript = NULL;
    verbose = FALSE;

    /* parse the argument list switches */
#ifndef LSC
    for (i = 1; i < argc; ++i)
        if (argv[i][0] == '-')
            switch(argv[i][1]) {
            case 't':
            case 'T':
                transcript = &argv[i][2];
                break;
            case 'v':
            case 'V':
                verbose = TRUE;
                break;
            case 'r':
            case 'R':
                secure_read_path = &argv[i][2];
                break;
            case 'w':
	    case 'W':
	        safe_write_path = &argv[i][2];
                break;
            case 'l':
            case 'L':
                run_time_limit = atoi(&argv[i][2]);
                break;
            case 'm':
            case 'M':
                memory_limit = atoi(&argv[i][2]);
                break;
            }
#endif

    /* initialize and print the banner line */
    osinit(BANNER);

    /* setup initialization error handler */
    xlbegin(&cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,(LVAL)1);
    if (_setjmp(cntxt.c_jmpbuf))
        xlfatal("fatal initialization error");
    if (_setjmp(top_level))
        xlfatal("RESTORE not allowed during initialization");

    /* initialize xlisp */
    xlinit();
    xlend(&cntxt);

#ifdef EXT
    /* special initialization */
#include "xlextstart.c"
#endif

    /* reset the error handler */
    xlbegin(&cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,s_true);

    /* open the transcript file */
    if (transcript && (tfp = osaopen(transcript,"w")) == NULL) {
        sprintf(buf,"error: can't open transcript file: %s",transcript);
        stdputstr(buf);
    }

    /* load "init.lsp" */
	if (_setjmp(cntxt.c_jmpbuf) == 0) {
        xlload("init.lsp",TRUE,FALSE);
	}

    /* load any files mentioned on the command line */
    if (_setjmp(cntxt.c_jmpbuf) == 0)
        for (i = 1; i < argc; i++)
            if (argv[i][0] != '-' && !xlload(argv[i],TRUE,verbose))
                xlerror("can't load file",cvstring(argv[i]));
    xlend(&cntxt);
    if (_setjmp(top_level))
        xlfatal("RESTORE not allowed out of read-eval-print loop");
}


/* xlisp_eval -- evaluate an expression created externally */
LVAL xlisp_eval(LVAL expr)
{
    int was_in_a_context = in_a_context;
    XLCONTEXT cntxt;

    if (in_a_context == FALSE) {
        /* create an execution context */
        xlbegin(&cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,s_true);
        if (_setjmp(cntxt.c_jmpbuf)) {
            setvalue(s_evalhook,NIL);
            setvalue(s_applyhook,NIL);
            xltrcindent = 0;
            xldebug = 0;
            xlflush();
            oserror("xlisp_eval returning NIL to caller");
            in_a_context = FALSE;
            return NIL;
        }
        in_a_context = TRUE;
    }

    expr = xleval(expr);

    if (!was_in_a_context) {
        xlend(&cntxt);
        in_a_context = FALSE;
    }
    return expr;
}


/* xlisp_main -- run normal lisp read-eval-print loop */
void xlisp_main()
{
    LVAL expr;
    XLCONTEXT cntxt;

    /* build an outer-most context */
    xlbegin(&cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,s_true);
    in_a_context = TRUE;

    /* target for restore */
    if (_setjmp(top_level))
        xlbegin(&cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,s_true);

    /* protect some pointers */
    xlsave1(expr);

    /* main command processing loop */
    for (xl_main_loop = TRUE; xl_main_loop;) {

        /* setup the error return */
        if (_setjmp(cntxt.c_jmpbuf)) {
            setvalue(s_evalhook,NIL);
            setvalue(s_applyhook,NIL);
            xltrcindent = 0;
            xldebug = 0;
            xlflush();
        }

        #ifndef READ_LINE
        /* print a prompt */
        stdputstr("> ");
        #endif

        /* read an expression */
        if (!xlread(getvalue(s_stdin),&expr,FALSE))
            break;

        /* save the input expression */
        xlrdsave(expr);

        /* evaluate the expression */
        expr = xleval(expr);

        /* save the result */
        xlevsave(expr);

        /* print it */
        stdprint(expr);
    }
    xlend(&cntxt);
    in_a_context = FALSE;
}

/* #include "alloca.h" -- what was this for? -RBD */

#ifndef EXT
int main(int argc, char *argv[])
{
    xlisp_main_init(argc,argv);
    xlisp_main();

    /* clean up */
    xlisp_wrapup();
    return 0;
}
#endif


/* xlrdsave - save the last expression returned by the reader */
void xlrdsave(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(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(const char *msg)
{
    oserror(msg);
    xlisp_wrapup();
}

/* wrapup - clean up and exit to the operating system */
void xlisp_wrapup(void)
{
    if (tfp)
        osclose(tfp);
    osfinish();
#ifdef CMTSTUFF
    EXIT(0);
#else
    exit(0);
#endif
}