|
|
1.1 root 1: ;--- file: complrb.l
2: (include "compmacs.l")
3:
4: (setq compiler-name '"Lisp Compiler V3.0")
5:
6: (setq old-top-level (getd 'top-level))
7: (setq original-readtable readtable)
8: (setq raw-readtable (makereadtable t))
9:
10: ;--- lcfinit : called upon compiler startup. If there are any args
11: ; on the command line, we build up a call to lcf, which
12: ; will do the compile. Afterwards we exit.
13: ;
14: (def lcfinit
15: (lambda nil
16: (cond ((greaterp (argv -1) 1) ; build up list of args
17: (do ((i (sub1 (argv -1)) (sub1 i)) (arglis))
18: ((lessp i 1)
19: (exit (apply 'liszt arglis)))
20: (setq arglis (cons (argv i) arglis))))
21: (t (patom compiler-name)
22: (terpr poport)
23: (putd 'top-level old-top-level)))))
24:
25: (putd 'top-level (getd 'lcfinit))
26:
27:
28:
29:
30: ;--- lcf - v-x : list containing file name to compile and optionaly
31: ; and output file name for the assembler source.
32: ;
33: (def liszt
34: (nlambda (v-x)
35: (prog (piport v-root v-ifile v-sfile v-ofile
36: vp-ifile vp-sfile vps-crap
37: vps-include
38: k-pid v-crap tmp rootreal
39: tem temr starttime startptime startgccount
40: fl-asm fl-warn fl-verb fl-inter)
41:
42: (setq starttime (syscall 13) ; real time in seconds
43: startptime (ptime)
44: startgccount $gccount$)
45: (setq k-lams (setq k-nlams (setq k-macros nil)))
46: (cond ((null (boundp 'internal-macros))
47: (setq internal-macros nil)))
48: (cond ((null (boundp 'macros))
49: (setq macros nil)))
50: (setq k-free nil)
51: (setq er-fatal 0)
52: (setq k-ptrs nil)
53: (setq k-disp -4)
54: (setq k-fnum 0) ; function number
55: (setq w-bind nil)
56: (setq vps-include nil)
57: (setq twa-list nil)
58:
59: (setq x-spec (gensym 'S)) ; flag for special atom
60: ; declare these special
61: (flag nil x-spec)
62: (flag t x-spec)
63:
64: (sstatus feature complr)
65:
66: ; process input form
67: (setq fl-asm t ; assembler file assembled
68: fl-warn t ; print warnings
69: fl-verb t ; be verbose
70: fl-macl nil ; compile maclisp file
71: fl-inter nil ; print intermediate forms
72: )
73:
74: (do ((i v-x (cdr i))) ; for each argument
75: ((null i))
76: (setq tem (aexplodec (car i)))
77:
78: (cond ((eq '- (car tem)) ; if switch
79: (do ((j (cdr tem) (cdr j)))
80: ((null j))
81: (cond ((eq 'S (car j)) (setq fl-asm nil))
82: ((eq 'm (car j)) (setq fl-macl t))
83: ((eq 'o (car j)) (setq v-ofile (cadr i)
84: i (cdr i)))
85: ((eq 'w (car j)) (setq fl-warn t))
86: ((eq 'q (car j)) (setq fl-verb nil))
87: ((eq 'i (car j)) (setq fl-inter t))
88: (t (comp-gerr "Unknown switch: "
89: (car j))))))
90: ((null v-root)
91: (setq temr (reverse tem))
92: (cond ((and (eq 'l (car temr))
93: (eq '"." (cadr temr)))
94: (setq rootreal nil)
95: (setq v-root (apply 'concat (reverse (cddr temr)))))
96: (t (setq v-root (car i)
97: rootreal t))))
98:
99: (t (comp-gerr "Extra input file name: " (car i)))))
100:
101:
102:
103: ; now see what the arguments have left us
104:
105: (cond ((null v-root)
106: (comp-gerr "No file for input"))
107: ((or (portp
108: (setq vp-ifile
109: (car (errset (infile
110: (setq v-ifile
111: (concat v-root '".l")))
112: nil))))
113: (and rootreal
114: (portp
115: (setq vp-ifile
116: (car (errset
117: (infile (setq v-ifile v-root))
118: nil)))))))
119: (t (comp-gerr "Couldn't open the source file :"
120: (or v-ifile))))
121:
122:
123: (setq k-pid (apply 'concat (cons 'F (cvt (syscall 20)))))
124: ; determine the name of the .s file
125: ; strategy: if fl-asm is t (only assemble) use (v-root).s
126: ; else use /tmp/(k-pid).s
127: ;
128: (cond (fl-asm (setq v-sfile (concat '"/tmp/"
129: k-pid
130: '".s")))
131: (t (setq v-sfile (concat v-root '".s"))))
132:
133: (cond ((not (portp (setq vp-sfile
134: (car (errset (outfile v-sfile)
135: nil)))))
136: (comp-gerr "Couldn't open the .s file: "
137: (or v-sfile))))
138:
139:
140: ; determine the name of the .o file (object file)
141: ; strategy: if we aren't supposed to assemble the .s file
142: ; don't worry about a name
143: ; else if a name is given, use it
144: ; else if use (v-root).o
145: (cond ((or v-ofile (null fl-asm))) ;ignore
146: (t (setq v-ofile (concat v-root '".o"))))
147:
148: (cond ((checkfatal) (return 1)))
149:
150: (setq readtable (makereadtable nil)) ; use new readtable
151:
152:
153: ; make i/o descriptors to point to crap file then
154: ; unlink crap file so if we die while compiling the crap
155: ; file will disappear
156: (setq v-crap (concat k-pid k-fnum 'crap))
157: (setq tmp (outfile v-crap)) ; create output first
158: (setq vps-crap (cons (infile v-crap) tmp))
159: (apply 'syscall `(10 ',v-crap)) ; unlink it
160:
161: (emit1 `(".." ,k-pid ,k-fnum :))
162: (emit1 '".long linker")
163: (emit1 '".long BINDER")
164:
165: ; if the macsyma flag is set, change the syntax to the
166: ; maclisp standard syntax. We must be careful that we
167: ; dont clobber any syntax changes made by files preloaded
168: ; into the compiler.
169:
170: (cond (fl-macl (setsyntax '\/ 143) ; 143 = vesc
171:
172: (cond ((equal 143 (status syntax \\))
173: (setsyntax '\\ 2)))
174:
175: (setsyntax '\| 138) ; 138 = vdq
176: (cond ((equal 138 (status syntax \"))
177: (setsyntax '\" 2)))
178: (cond ((equal 198 (status syntax \[))
179: (setsyntax '\[ 2)
180: (setsyntax '\] 2)))
181: (setq ibase 8.)
182: (sstatus uctolc t)
183:
184: (flag 'ibase x-spec) ; to be special
185: (flag 'base x-spec)
186: (flag 'tty x-spec)
187:
188: (errset (cond ((null (getd 'macsyma-env))
189: (load 'machacks)))
190: nil)))
191:
192: (cond ((checkfatal) (return 1))) ; leave if fatal errors
193:
194: (comp-note "Compilation begins with " (or compiler-name))
195: (comp-note "source: " (or v-ifile) ", result: "
196: (cond (fl-asm v-ofile) (t v-sfile)))
197: (setq piport vp-ifile) ; set to standard input
198:
199: loop
200: ;(cond ((atom (errset (do ((i (read) (read)))
201: ; ((eq i 'eof) nil)
202: ; (cleanup)
203: ; (lcfform i))))
204: ; (patom '"error during compilation, I quit")))
205:
206: (cond ((atom (errset
207: (do ((i (read piport '<<end-of-file>>)
208: (read piport '<<end-of-file>>)))
209: ((eq i '<<end-of-file>>) nil)
210: (cleanup)
211: (catch (lcfform i) Comp-error))))
212: (comp-note "Lisp error during compilation")
213: (setq piport nil)
214: (setq er-fatal (add1 er-fatal))
215: (return 1)))
216:
217: (close piport)
218:
219: (cond ((checkfatal) (return 1)))
220:
221: ; if doing special character stuff (maclisp) reassert
222: ; the state
223:
224: (cond (vps-include
225: (comp-note " done include")
226: (setq piport (car vps-include))
227: (setq vps-include (cdr vps-include))
228: (go loop)))
229:
230: ; reset input base
231: (setq ibase 10.)
232:
233:
234: (close (cdr vps-crap))
235:
236: (setq vp-ifile (car vps-crap)) ; read crap file
237:
238: ((lambda (readtable)
239: (do ((i (read vp-ifile '<<end-of-file>>)
240: (read vp-ifile '<<end-of-file>>)))
241: ((eq i '<<end-of-file>>) nil)
242: (setq w-bind (cons (list 0 i 'Crap) w-bind)))
243:
244: (cm-alist))
245: raw-readtable)
246:
247: (close vp-sfile) ; close assembler language file
248: (comp-note "Compilation complete")
249:
250: (setq tem (Divide (difference (syscall 13) starttime) 60))
251: (comp-note " Real time: " (car tem) " minutes, "
252: (cadr tem) " seconds")
253: (setq tem (ptime))
254: (setq temr (Divide (difference (car tem) (car startptime))
255: 3600))
256: (comp-note " CPU time: " (car temr) " minutes, "
257: (quotient (cadr temr) 60.0) " seconds")
258: (setq temr (Divide (difference (cadr tem) (cadr startptime))
259: 3600))
260: (comp-note " of which " (car temr) " minutes and "
261: (quotient (cadr temr) 60.0)
262: " seconds were for the "
263: (difference $gccount$ startgccount)
264: " gcs which were done")
265:
266:
267: (cond (fl-asm ; assemble file
268: (comp-note "Assembly begins")
269: (cond ((not
270: (zerop
271: (setq tmp
272: (apply 'process
273: (ncons (concat '"as -o "
274: v-ofile
275: '" "
276: v-sfile))))))
277: (comp-gerr "Assembler detected error, code: "
278: (or tmp)))
279: (t (comp-note "Assembly completed successfully")))))
280: (cond (fl-asm (apply 'syscall `(10 ',v-sfile))))
281:
282: (setq readtable original-readtable)
283: (return 0))))
284:
285: (def checkfatal
286: (lambda nil
287: (cond ((greaterp er-fatal 0)
288: (comp-note "Compilation aborted")
289: t))))
290:
291:
292: ;--- lcfform - i : form to compile
293: ; This compiles one form.
294: ;
295: (def lcfform
296: (lambda (i)
297: (prog (tmp v-x)
298: ; macro expand
299: (setq i (cmacroexpand i))
300: ; now look at what is left
301: (cond ((eq (car i) 'def) ; jkf mod
302: (cond (fl-verb (print (cadr i)) (terpr)(drain)))
303: (dodef i))
304: ((eq (car i) 'declare) (dodcl i))
305: ((eq (car i) 'eval-when) (doevalwhen i))
306: ((and (eq (car i) 'progn) (equal (cadr i) '(quote compile)))
307: ((lambda (internal-macros) ; compile macros too
308: (mapc 'lcfform (cddr i)))
309: t))
310: ((or (eq (car i) '"%include")
311: (eq (car i) '"include"))
312: (cond ((or (portp (setq v-x
313: (car (errset (infile (cadr i)) nil))))
314: (portp (setq v-x
315: (car (errset (infile (concat '"/usr/lib/lisp"
316: (cadr i)))
317: nil)))))
318: (setq vps-include (cons piport vps-include))
319: (setq piport v-x)
320: (comp-note " INCLUDEing file: " (cadr i)))
321: (t (comp-gerr "Cannot open include file: " (cadr i)))))
322: (t ((lambda (readtable)
323: (print i (cdr vps-crap))
324: (terpr (cdr vps-crap)))
325: raw-readtable))))))
326:
327: ;--- cmacroexpand - i : functional form
328: ; the form is macro expanded on the top level as many times as
329: ; possible.
330: ;
331: (def cmacroexpand
332: (lambda (i)
333: (cond ((atom i) i)
334: (t (do ((j (ismacro (car i)) (ismacro (car i)))
335: (tmp))
336: ((null j) i)
337: (cond ((bcdp j)
338: (putd (setq tmp (Gensym nil))
339: (mfunction (getentry j) 'nlambda)))
340: (t (setq tmp (cons 'nlambda (cdr j)))))
341: (setq i (apply tmp i))
342: (cond ((atom i) (return i))))))))
343:
344: (def dodef
345: (lambda (v-f)
346: (prog (v-n v-t v-c w-save w-ret w-labs w-locs)
347: (setq k-current (setq v-n (cadr v-f))) ; v-n <= name of func
348: ; add function to approp. list
349: (cond ((or (eq (setq v-t (caaddr v-f)) 'lambda)
350: (eq v-t 'lexpr))
351: (setq k-lams (cons (list v-n t) k-lams)
352: k-ftype v-t
353: v-t 'lambda))
354: ((eq v-t 'nlambda)
355: (setq k-nlams (cons (list v-n t) k-nlams)
356: k-ftype 'nlambda))
357: ((eq v-t 'macro)
358: (setq k-macros (cons (list v-n (caddr v-f)) k-macros))
359: (setq k-ftype 'macro)
360: (eval v-f)
361: ; if macros is nil, we do not compile this macro
362: (cond ((and (null macros)
363: (null internal-macros))
364: (return nil))))
365: (t (comp-err (or v-n) " has an unknown function type"
366: (v-f))))
367:
368:
369: (setq v-c (concat k-pid k-fnum)) ; v-c <= unique name
370: (setq k-fnum (add1 k-fnum))
371: (cm-bind v-c v-n v-t) ; update k-regs
372: (setq v-t (f-func (cdaddr v-f))) ; do parse
373: (emit3 '# v-c v-n) ; put out header
374: (cm-alst4 v-n)
375: (cond (fl-inter (print v-t)(terpr)))
376: (cm-emit v-t v-c)))) ; emit code
377:
378: ;--- doevalwhen, process evalwhen directive. This is inadequate.
379: ;
380: (def doevalwhen
381: (lambda (v-f)
382: (prog (docom dolod)
383: (setq docom (member 'compile (cadr v-f))
384:
385: dolod (member 'load (cadr v-f)))
386: (mapc '(lambda (frm) (cond (docom (eval frm)))
387: (cond (dolod
388: ((lambda (internal-macros)
389: (lcfform frm))
390: t))))
391: (cddr v-f)))))
392:
393:
394: ;---- dodcl - v-f declare form
395: ; process the declare form given. We evaluate each arg
396: ;
397: (def dodcl
398: (lambda (v-f)
399: (setq v-f (cdr v-f))
400: (do ((i (car v-f) (car v-f)))
401: ((null i))
402: (setq v-f (cdr v-f))
403: (cond ((getd (car i)) (eval i)) ; if this is a function
404: (t (comp-warn "Unknown declare attribute: " (car i)))))))
405:
406: ;---> handlers for declare forms
407: ;
408: (def *fexpr
409: (nlambda (args)
410: (mapc '(lambda (v-x)
411: (setq k-nlams (cons (list v-x t) k-nlams)))
412: args)))
413: (def special
414: (nlambda (v-l)
415: (mapc '(lambda (v-a)
416: (unflag v-a x-con)
417: (flag v-a x-spec))
418: v-l)
419: t))
420: (def unspecial
421: (nlambda (v-l)
422: (mapc '(lambda (v-a)
423: (unflag v-a x-spec))
424: v-l)
425: t))
426:
427: (def *expr (nlambda (args) nil)) ; ignore
428:
429: (def macros (nlambda (args) (setq macros (car args))))
430: ;---> end declare form handlers
431:
432:
433: (def cm-bind
434: (lambda (v-lab v-atm v-type)
435: (setq w-bind (cons (list v-lab v-atm v-type) w-bind))))
436:
437: (def cm-emit
438: (lambda (v-t v-nm)
439: (setq k-back (setq k-regs nil))
440: (setq k-code v-t)
441: (prog (v-i v-l)
442: (emit2 '".globl" v-nm)
443: (emit1 (list v-nm ':))
444: next (cond ((null k-code) (return)))
445: (setq v-i (car k-code))
446: (setq k-code (cdr k-code))
447: (setq v-l (get (car v-i) x-emit))
448: (cond ((null (cdr v-i))
449: (funcall v-l)
450: (go next))
451: ((ifflag (car v-i) x-asg)
452: (setq v-t (e-reg (cadr v-i) nil)))
453: (t (setq v-t (cadr v-i))))
454: (apply v-l (rplaca (cdr v-i) v-t))
455: (go next))))
456:
457: ;--- cm-alist - print out the list of special lispvalues we reference
458: ; in compiled code
459: ;
460:
461: (def cm-alist
462: (lambda nil
463: (prog (cm-alv)
464: (cond (faslflag (emit1 '".text"))
465: (t (emit1 '".data")))
466: (emit1 '".align 2")
467: (emit1 '"lbnp: .long _bnp")
468: (emit1 '"lfun: .long __qfuncl")
469: (emit1 '"lf4: .long __qf4")
470: (emit1 '"lf3: .long __qf3")
471: (emit1 '"lf2: .long __qf2")
472: (emit1 '"lf1: .long __qf1")
473: (emit1 '"lf0: .long __qf0")
474: (emit2 '"lgc: .long" 0)
475: (emit1 '"linker:" )
476: (mapc 'cm-alst1 (reverse k-ptrs))
477: (emit2 '".long" -1)
478: (cond (faslflag (emit1 '".data"))
479: (t (emit1 '".text")))
480: (emit1 '".align 2")
481: (emit1 '"B:")
482: (emit1 '"BINDER:")
483: (mapc 'cm-alst2 (reverse w-bind))
484: (emit4 '".long" -1 -1 -1)
485: (emit1 '"litstrt:")
486: (mapc 'cm-alst3 (reverse cm-alv))
487: (emit1 '"litend:")
488: (cleanup))))
489:
490:
491: (def cm-alst1
492: (lambda (v-x)
493: (prog (v-g)
494: (setq v-g (Gensym 's))
495: (emit2 '".long" (list v-g '-B))
496: (putprop v-g (car v-x) 'label)
497: (setq cm-alv (cons v-g cm-alv)))))
498:
499: (def cm-alst2
500: (lambda (v-x)
501: (prog (v-g)
502: (emit2 '".long" (car v-x))
503: (setq v-g (Gensym 's))
504: (emit2 '".long" (list v-g '-B))
505: (putprop v-g (cadr v-x) 'label)
506: (setq cm-alv (cons v-g cm-alv))
507: (setq v-g (caddr v-x))
508: (emit2 '".long"
509: (cond ((eq v-g 'lambda) 0)
510: ((eq v-g 'nlambda) 1)
511: ((eq v-g 'macro) 2)
512: ((eq v-g 'Crap) 99)
513: (t 'UDEF_TYPE))))))
514:
515: (def cm-alst3
516: (lambda (v-x)
517: ($pr$ v-x)
518: ($pr$ '": ")
519: (setq v-x (get v-x 'label))
520: (cm-alst4 v-x)))
521:
522: ;--- cm-alst4 - v-x : s-expression
523: ; the given expression is exploded and printed as a string to the
524: ; assembler, this requires that each character be individually
525: ; noted and that the number of bytes on a line be limited.
526: ;
527: (def cm-alst4
528: (lambda (v-x)
529: ($pr$ '".byte ")
530: (do ((l (explode v-x) (cdr l))
531: (cnt 1 (add1 cnt)))
532: ((null l) ($pr$ 0) ($terpri))
533: ($pr$ '\')
534: ($pr$ (car l))
535: (cond ((greaterp cnt 13) ($terpri) ($pr$ '".byte ") (setq cnt 0))
536: (t ($pr$ '\,))))))
537: ;--- w-save
538: ; stack the values of w-ret and w-labs
539: ;
540: (def w-save
541: (lambda nil (setq w-save (cons `(,w-ret ,w-labs ,w-locs) w-save))))
542:
543: ;--- w-unsave
544: ; restore the values of w-ret and w-labs, popping them
545: ; off the w-save stack
546: ;
547: (def w-unsave
548: (lambda nil (setq w-ret (caar w-save)
549: w-labs (cadar w-save)
550: w-locs (caddar w-save)
551: w-save (cdr w-save))))
552:
553:
554: ;--- f-exp - v-e form to evaluate
555: ; - v-r location to place result in.
556: ; - v-t restof stuff (intermidiate forms)
557: ;
558: ; This is the real workhorse of the compiler.
559: ;
560: (def f-exp
561: (lambda (v-e v-r v-t)
562: (prog (v-f v-i v-tem)
563: begin (cond ; atoms
564: ((f-one v-e)
565: ; if the symbol has not been declared special and is
566: ; not a local variable, we declare it special.
567: (g-specialchk v-e)
568: (return (f-addi (list 'get v-r v-e) v-t)))
569:
570: ; lambda expressions, we do the correct thing.
571: ; should check for bad forms here rather than call
572: ; f-chkf
573: ((not (atom (setq v-f (car v-e))))
574: (setq v-f (cmacroexpand v-f))
575: ; must check if the expression changes to an atom
576: (cond ((atom v-f)
577: (setq v-e (cons v-f (cdr v-e)))
578: (go begin)))
579:
580: (cond ((eq 'lambda (car v-f))
581: (return (f-lambexp v-e v-r v-t)))
582: ; this case is necessary to compile
583: ; ('add 1 2) which the interpreter will
584: ; handle and I guess we should too
585: ((eq 'quote (car v-f))
586: (comp-warn "Bizzare function name " (or v-f) N)
587: (setq v-e (cons (cadr v-f) (cdr v-e)))
588: (go begin))
589: (t (comp-err " Illegal expression: "
590: (or v-f)
591: N))))
592:
593: ; macro expand and continue
594: ((and (or (setq v-e (cmacroexpand v-e)) t)
595: (cond ((or (atom v-e)
596: (not (atom (car v-e))))
597: (go begin)) ; if reduce to atom
598: ; or lambda exp
599: (t (setq v-f (car v-e))))
600: nil))
601:
602: ; special functions
603: ((setq v-i (get v-f x-spf)) (go special))
604: ((setq v-i (get v-f x-spfq))
605: (put v-f x-spfq nil)
606: (go special))
607: ((setq v-i (get v-f x-spfn)) (go special))
608: ((setq v-i (get v-f x-spfh))
609: (setq v-e (funcall v-i v-e))
610: (go normal))
611:
612: ; macro within compiler
613: ((setq v-i (get v-f 'x-spfm))
614: (setq v-e (funcall v-i v-e))
615: (go begin))
616:
617: ; nlambbdas, we quote the args
618: ((isnlam v-f)
619: (setq v-e (list v-f (list 'quote (cdr v-e))))
620: (go normal))
621:
622:
623: ; cxr form where x is elt of {a d}
624: ((setq v-i (chain v-f))
625: (setq v-t (f-addi
626: (list 'chain
627: v-r
628: (setq v-r (f-use (Gensym nil)))
629: v-i)
630: v-t))
631: (setq v-e (cadr v-e)) ; calc expr to new v-r
632: (go begin))
633:
634: ; if this is not the last form before a return,
635: ; we go to normal to do a function invocation
636: ; otherwise we look to see if tail merging is
637: ; possible.
638: ((not (eq (caar v-t) 'return)) (go normal))
639: ((or (eq (setq v-i w-bv) t)
640: (not (equal v-f w-name))) (go normal))
641: ((not (f-iter (cdr v-e) (reverse v-i))) (go normal)) )
642:
643: ; do tail merging.
644: (setq v-t (f-addi '(repeat) v-t))
645: (setq v-e (reverse (cdr v-e)))
646: iterate (cond ((null v-e) (return v-t))
647: ((equal (car v-e) (car v-i)) (go next)))
648: (setq v-t (f-addi (list 'set
649: (setq v-r (f-reg 'set))
650: (car v-i))
651: v-t))
652: (setq v-t (f-exp (car v-e) v-r v-t))
653: next (setq v-e (cdr v-e))
654: (setq v-i (cdr v-i))
655: (go iterate)
656:
657: ; the function will be handled specially by the compiler
658: special (cond ((setq v-i (funcall v-i (cdr v-e) v-r v-t))
659: (return v-i)))
660:
661: ; normal handling, call function.
662: ; if this is a system function, do it quickly
663: normal (cond ((setq v-i (get (car v-e) 'x-sysf)) ; system fcn
664: (setq v-t
665: (f-pusha (cdr v-e)
666: (Gensym nil)
667: (f-addi `(call ,(f-make v-r r-xv)
668: ,v-i
669: ,(length (cdr v-e)))
670: v-t))))
671: (t (setq v-t
672: (f-pusha `((quote ,(car v-e)) ,@(cdr v-e))
673: (Gensym nil)
674: (f-addi `(call ,(f-make v-r r-xv)
675: nil
676: ,(length v-e))
677: v-t)))))
678:
679: (return v-t))))
680:
681: ;--- g-specialchk - v-e : expression
682: ; if v-e is a symbol and not declared special and not a local variable
683: ; we complain and delare it special
684: ; v-e is returned.
685: ;
686: (def g-specialchk
687: (lambda (v-e)
688: (cond ((and (symbolp v-e)
689: (not (get v-e x-spec))
690: (not (member v-e w-locs)))
691: (flag v-e x-spec)
692: (comp-warn (or v-e) " declared special by compiler")))
693: v-e))
694:
695:
696: ;--- f-lambexp - v-e : lambda expression: ((lambda (x y z) exp) a b c)
697: ; - v-r : weather where result should be placed
698: ; - v-t : tail
699: ;
700: ; This compiled a lambda expression. This is a very simple do-expression
701: ; with the difference that returns are not allowed from within it.
702:
703: (def f-lambexp
704: (lambda (v-e v-r v-t)
705: (f-pusha (cdr v-e)
706: (Gensym nil)
707: (f-lambbody (cdar v-e) v-r (length (cadar v-e)) v-t))))
708:
709: ;--- f-lambbody - v-e : args + body of lambda ((a b c) exp1 exp2 ...)
710: ; - v-ags : number of args pushed for this lambda, it will
711: ; normally equal the length of (cadr v-e) but
712: ; in the case of the top level lambda expression
713: ; in a function it will be 0
714: ; - v-r : psreg to place result in
715: ; - v-t : tail
716: ; We emit the intermediate expressions necessary to evaluate the
717: ; lambda body
718: ;
719: (def f-lambbody
720: (lambda (v-e v-r v-ags v-t)
721: (w-save) ; stack old values
722: (prog (w-ret w-labs tmp)
723: (setq tmp `((begin ,v-ags)
724: ,@(mapcar '(lambda (arg) (setq w-locs
725: (cons arg w-locs))
726: `(bind ,arg))
727: (car v-e))
728: ,@(f-seq (cdr v-e)
729: v-r
730: `((end nil)
731: ,@v-t))))
732: (w-unsave)
733: (return tmp))))
734:
735: ;--- f-func - v-l : function args and body.
736: ;
737: ; result is: (entry type) ; type is lambda,lexpr, macro
738: ; or nlambda
739: ; ..body..
740: ;
741: ; (fini)
742: ;
743: (def f-func
744: (lambda (v-l)
745: `((entry ,k-ftype)
746: ,@(f-lambbody v-l 'xv 0 '((fini))))))
747:
748:
749: ;--- f-prog - v-l : args + prog body
750: ; - v-r : psreg to store result in
751: ; - v-t : tail
752: ;
753: (def f-prog
754: (lambda (v-l v-r v-t)
755: (w-save)
756: (prog (w-ret tmp retlb w-labs)
757: (setq tmp (length (car v-l)) ; number of locals
758: retlb (Gensym nil) ; label to leave prog
759: w-labs (Gensym nil) ; hang labels here
760: w-ret `(,v-r . (go ,retlb)))
761:
762: (setq tmp `((pushnil ,tmp) ; start out with nils
763: (begin ,tmp) ; declare variables
764: ,@(mapcar '(lambda (arg) (setq w-locs
765: (cons arg w-locs))
766: `(bind ,arg))
767: (car v-l)) ; bind locals
768: ,@(f-seqp (cdr v-l) (Gensym nil)
769: `((get ,v-r nil)
770: (end ,retlb)
771: ,@v-t))))
772: (w-unsave)
773: (return tmp))))
774:
775:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.