boot.sl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. % Standard LISP BOOT File.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1991 RAND. All Rights Reserved.
  4. (fluid '(fname!* !*blockp !*lower !*mode !*raise))
  5. (global '(oldchan!*))
  6. (global '(crchar!* cursym!* nxtsym!* ttype!* !$eol!$))
  7. (put '!; 'switch!* '(nil !*semicol!*))
  8. (put '!( 'switch!* '(nil !*lpar!*))
  9. (put '!) 'switch!* '(nil !*rpar!*))
  10. (put '!, 'switch!* '(nil !*comma!*))
  11. (put '!. 'switch!* '(nil cons))
  12. (put '!= 'switch!* '(nil equal))
  13. (put '!: 'switch!* '(((!= nil setq)) !*colon!*))
  14. (put '!< 'switch!* '(((!= nil leq) (!< nil !*lsqbkt!*)) lessp))
  15. (put '!> 'switch!* '(((!= nil geq) (!> nil !*rsqbkt!*)) greaterp))
  16. % When the real parser is loaded the function mkprec will reset all
  17. % precedence values here. So until then please fully parenthesize
  18. % any expressions.
  19. (put '!*comma!* 'infix 1)
  20. (put 'setq 'infix 2)
  21. (put 'cons 'infix 3)
  22. (put 'equal 'infix 4)
  23. (put 'eq 'infix 5)
  24. (flag '(!*comma!*) 'nary)
  25. (flag '(!*colon!* !*semicol!* end then else) 'delim)
  26. (put 'begin 'stat 'blockstat)
  27. (put 'if 'stat 'ifstat)
  28. (put 'symbolic 'stat 'procstat)
  29. (de begin2 nil
  30. (prog nil
  31. (setq cursym!* '!*semicol!*)
  32. a (cond
  33. ((eq cursym!* 'end) (progn (rds oldchan!*) (return nil)))
  34. (t (prin2 (errorset '(eval (form (xread nil))) t t)) ))
  35. (go a)))
  36. (de form (u) u)
  37. (de xread (u) (progn (scan) (xread1 u)))
  38. (de xread1 (u)
  39. (prog (v w x y z z2)
  40. a (setq z cursym!*)
  41. a1 (cond
  42. ((or (null (atom z)) (numberp z)) (setq y nil))
  43. ((flagp z 'delim) (go end1))
  44. ((eq z '!*lpar!*) (go lparen))
  45. ((eq z '!*rpar!*) (go end1))
  46. ((and w (setq y (get z 'infix))) (go infx))
  47. ((setq y (get z 'stat)) (go stat)))
  48. a3 (setq w (cons z w))
  49. next (setq z (scan))
  50. (go a1)
  51. lparen(setq y nil)
  52. (cond
  53. ((eq (scan) '!*rpar!*)
  54. (and w (setq w (cons (list (car w)) (cdr w)))) )
  55. ((eqcar (setq z (xread1 'paren)) '!*comma!*)
  56. (setq w (cons (cons (car w) (cdr z)) (cdr w))))
  57. (t (go a3)))
  58. (go next)
  59. infx (setq z2 (mkvar (car w) z))
  60. un1 (setq w (cdr w))
  61. (cond
  62. ((null w) (go un2))
  63. (t (setq z2 (cons (car w) (list z2)))) )
  64. (go un1)
  65. un2 (setq v (cons z2 v))
  66. preced(cond ((null x) (go pr4)) ((lessp y (car (car x))) (go pr2)))
  67. pr1 (setq x (cons (cons y z) x))
  68. (go next)
  69. pr2 (setq v
  70. (cons
  71. (cond
  72. ((and (eqcar (car v) (cdar x)) (flagp (cdar x) 'nary))
  73. (cons (cdar x) (cons (cadr v) (cdar v))))
  74. (t (cons (cdar x) (list (cadr v) (car v)))) )
  75. (cdr (cdr v))))
  76. (setq x (cdr x))
  77. (go preced)
  78. stat (setq w (cons (eval (list y)) w))
  79. (setq y nil)
  80. (go a)
  81. end1 (cond
  82. ((and (and (null v) (null w)) (null x)) (return nil))
  83. (t (setq y 0)))
  84. (go infx)
  85. pr4 (cond ((null (equal y 0)) (go pr1)) (t (return (car v)))) ))
  86. (de eqcar (u v) (and (null (atom u)) (eq (car u) v)))
  87. (de mksetq (u v) (list 'setq u v))
  88. (de mkvar (u v) u)
  89. (de rread nil
  90. (prog (x)
  91. (setq x (token))
  92. (return
  93. (cond
  94. ((and (equal ttype!* 3) (eq x '!()) (rrdls))
  95. (t x)))) )
  96. (de rrdls nil
  97. (prog (x r)
  98. a (setq x (rread))
  99. (cond
  100. ((null (equal ttype!* 3)) (go b))
  101. ((eq x '!)) (return (reverse r))) % REVERSIP not yet defined.
  102. ((null (eq x '!.)) (go b)))
  103. (setq x (rread))
  104. (token)
  105. (return (nconc (reverse r) x))
  106. b (setq r (cons x r))
  107. (go a)))
  108. (de token nil
  109. (prog (x y)
  110. (setq x crchar!*)
  111. a (cond
  112. ((seprp x) (go sepr))
  113. ((digit x) (go number))
  114. ((liter x) (go letter))
  115. ((eq x '!%) (go coment))
  116. ((eq x '!!) (go escape))
  117. ((eq x '!') (go quote))
  118. ((eq x '!") (go string)))
  119. (setq ttype!* 3)
  120. (cond ((delcp x) (go d)))
  121. (setq nxtsym!* x)
  122. a1 (setq crchar!* (readch))
  123. (go c)
  124. escape(setq y (cons x y))
  125. (setq x (readch))
  126. letter(setq ttype!* 0)
  127. let1 (setq y (cons x y))
  128. (cond
  129. ((or (digit (setq x (readch))) (liter x)) (go let1))
  130. ((eq x '!!) (go escape)))
  131. (setq nxtsym!* (intern (compress (reverse y))))
  132. b (setq crchar!* x)
  133. c (return nxtsym!*)
  134. number(setq ttype!* 2)
  135. num1 (setq y (cons x y))
  136. (cond ((digit (setq x (readch))) (go num1)))
  137. (setq nxtsym!* (compress (reverse y)))
  138. (go b)
  139. quote (setq crchar!* (readch))
  140. (setq nxtsym!* (list 'quote (rread)))
  141. (setq ttype!* 4)
  142. (go c)
  143. string(prog (raise !*lower)
  144. (setq raise !*raise)
  145. (setq !*raise nil)
  146. strinx(setq y (cons x y))
  147. (cond ((null (eq (setq x (readch)) '!")) (go strinx)))
  148. (setq y (cons x y))
  149. (setq nxtsym!* (mkstrng (compress (reverse y))))
  150. (setq !*raise raise))
  151. (setq ttype!* 1)
  152. (go a1)
  153. coment(cond ((null (eq (readch) !$eol!$)) (go coment)))
  154. sepr (setq x (readch))
  155. (go a)
  156. d (setq nxtsym!* x)
  157. (setq crchar!* '! )
  158. (go c)))
  159. (setq crchar!* '! )
  160. (de delcp (u) (or (eq u '!;) (eq u '!$)))
  161. (de mkstrng (u) u)
  162. (de seprp (u) (or (eq u '! ) (eq u !$eol!$) (eq u '!
  163. )))
  164. (de scan nil
  165. (prog (x y)
  166. (cond ((null (eq cursym!* '!*semicol!*)) (go b)))
  167. a (setq nxtsym!* (token))
  168. b (cond
  169. ((or (null (atom nxtsym!*)) (numberp nxtsym!*)) (go l))
  170. ((and (setq x (get nxtsym!* 'newnam)) (setq nxtsym!* x))
  171. (go b))
  172. ((eq nxtsym!* 'comment) (go comm))
  173. ((and
  174. (eq nxtsym!* '!')
  175. (setq cursym!* (list 'quote (rread))))
  176. (go l1))
  177. ((null (setq x (get nxtsym!* 'switch!*))) (go l))
  178. ((eq (cadr x) '!*semicol!*)
  179. (return (setq cursym!* (cadr x)))) )
  180. sw1 (setq nxtsym!* (token))
  181. (cond
  182. ((or
  183. (null (car x))
  184. (null (setq y (assoc nxtsym!* (car x)))) )
  185. (return (setq cursym!* (cadr x)))) )
  186. (setq x (cdr y))
  187. (go sw1)
  188. comm (cond ((eq (readch) '!;) (setq crchar!* '! )) (t (go comm)))
  189. (go a)
  190. l (setq cursym!*
  191. (cond
  192. ((null (eqcar nxtsym!* 'string)) nxtsym!*)
  193. (t (cons 'quote (cdr nxtsym!*)))) )
  194. l1 (setq nxtsym!* (token))
  195. (return cursym!*)))
  196. (de ifstat nil
  197. (prog (condx condit)
  198. a (setq condx (xread t))
  199. (setq condit (nconc condit (list (list condx (xread t)))) )
  200. (cond
  201. ((null (eq cursym!* 'else)) (go b))
  202. ((eq (scan) 'if) (go a))
  203. (t (setq condit
  204. (nconc condit (list (list t (xread1 t)))) )))
  205. b (return (cons 'cond condit))))
  206. (de procstat nil
  207. (prog (x y)
  208. (cond ((eq cursym!* 'symbolic) (scan)))
  209. (cond
  210. ((eq cursym!* '!*semicol!*)
  211. (return (null (setq !*mode 'symbolic)))) )
  212. (setq fname!* (scan))
  213. (cond ((atom (setq x (xread1 nil))) (setq x (list x))))
  214. (setq y (xread nil))
  215. (cond ((flagp (car x) 'lose) (return nil)))
  216. (putd (car x) 'expr (list 'lambda (cdr x) y))
  217. (setq fname!* nil)
  218. (return (list 'quote (car x)))) )
  219. (de blockstat nil
  220. (prog (x hold varlis !*blockp)
  221. a0 (setq !*blockp t)
  222. (scan)
  223. (cond
  224. ((null (or (eq cursym!* 'integer) (eq cursym!* 'scalar)))
  225. (go a)))
  226. (setq x (xread nil))
  227. (setq varlis
  228. (nconc
  229. (cond ((eqcar x '!*comma!*) (cdr x)) (t (list x)))
  230. varlis))
  231. (go a0)
  232. a (setq hold (nconc hold (list (xread1 nil))))
  233. (setq x cursym!*)
  234. (scan)
  235. (cond ((not (eq x 'end)) (go a)))
  236. (return (mkprog varlis hold))))
  237. (de mkprog (u v) (cons 'prog (cons u v)))
  238. (de gostat nil
  239. (prog (x) (scan) (setq x (scan)) (scan) (return (list 'go x))))
  240. (put 'go 'stat 'gostat)
  241. (de rlis nil
  242. (prog (x)
  243. (setq x cursym!*)
  244. (return (list x (list 'quote (list (xread t)))))))
  245. (de endstat nil (prog (x) (setq x cursym!*) (scan) (return (list x))))
  246. % It is only a rather small number of lines of code to support
  247. % both << >> blocks and WHILE statements here, and doing so makes
  248. % it possible to write the full implementation of RLISP in a much
  249. % more civilised way. What I put in here is a little more than is used
  250. % to start with, but matches the eventual implementation. Eg the 'go
  251. % and 'nodel are not relevant until the read parser has been loaded.
  252. (de readprogn nil
  253. (prog (lst)
  254. a (setq lst (cons (xread 'group) lst))
  255. (cond ((null (eq cursym!* '!*rsqbkt!*)) (go a)))
  256. (scan)
  257. (return (cons 'progn (reverse lst)))))
  258. (put '!*lsqbkt!* 'stat 'readprogn)
  259. (flag '(!*lsqbkt!*) 'go)
  260. (flag '(!*rsqbkt!*) 'delim)
  261. (flag '(!*rsqbkt!*) 'nodel)
  262. % There is a "wonderful" mess here! The file support/pslprolo.red gives
  263. % the symbol "do" a newnam that maps it onto "~do" when read. This is to
  264. % avoid conflict with a PSL version of a FOR loop. A consequence is that
  265. % up until pslprolo is read in the input characters "do" are read as the
  266. % symbol with that simple name, while afterwards you get a version with
  267. % a "~" stuck on the front. The test in the code here will continue to test
  268. % for what it used to! So to survive parsing WHILE loops both before and
  269. % after I need to allow for both spellings.
  270. (de whilstat ()
  271. (prog (!*blockp bool bool2)
  272. (cond
  273. ((flagp 'do 'delim) (setq bool2 t))
  274. (t (flag '(do !~do) 'delim)))
  275. (setq bool (xread t))
  276. (cond
  277. (bool2 (remflag '(do !~do) 'delim)))
  278. (cond
  279. ((and (not (eq cursym!* 'do))
  280. (not (eq cursym!* '!~do))) (symerr 'while t)))
  281. (return (list 'while bool (xread t)))))
  282. (dm while (u)
  283. (prog (body bool lab)
  284. (setq bool (cadr u))
  285. (setq body (caddr u))
  286. (setq lab 'whilelabel)
  287. (return (list
  288. 'prog nil
  289. lab (list 'cond
  290. (list (list 'not bool) '(return nil)))
  291. body
  292. (list 'go lab)))))
  293. (put 'while 'stat 'whilstat)
  294. (flag '(while) 'nochange)
  295. (de repeatstat ()
  296. (prog (!*blockp body bool)
  297. (cond
  298. ((flagp 'until 'delim) (setq bool t))
  299. (t (flag '(until) 'delim)))
  300. (setq body (xread t))
  301. (cond
  302. ((null bool) (remflag '(until) 'delim)))
  303. (cond
  304. ((not (eq cursym!* 'until)) (symerr 'repeat t)))
  305. (return (list 'repeat body (xread t)))))
  306. (dm repeat (u)
  307. (progn (terpri) (print (prog (body bool lab)
  308. (setq body (cadr u))
  309. (setq bool (caddr u))
  310. (setq lab 'repeatlabel)
  311. (return (list
  312. 'prog nil
  313. lab body
  314. (list 'cond
  315. (list (list 'not bool) (list 'go lab)))))))))
  316. (put 'repeat 'stat 'repeatstat)
  317. (flag '(repeat) 'nochange)
  318. % It is useful to have a temporary version of this in place until the
  319. % real one gets compiled...
  320. (de make!-string!-unique (x) x)