dynamic.sch 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349
  1. ; This benchmark was obtained from Andrew Wright,
  2. ; based on Fritz Henglein's code.
  3. ; 970215 / wdc Removed most i/o and added dynamic-benchmark.
  4. ; 990707 / lth Added a quote and changed the call to run-benchmark.
  5. ; 010404 / wdc Changed the input file path name to "dynamic-input.sch".
  6. ;; Fritz's dynamic type inferencer, set up to run on itself
  7. ;; (see the end of this file).
  8. ;----------------------------------------------------------------------------
  9. ; Environment management
  10. ;----------------------------------------------------------------------------
  11. ;; environments are lists of pairs, the first component being the key
  12. ;; general environment operations
  13. ;;
  14. ;; empty-env: Env
  15. ;; gen-binding: Key x Value -> Binding
  16. ;; binding-key: Binding -> Key
  17. ;; binding-value: Binding -> Value
  18. ;; binding-show: Binding -> Symbol*
  19. ;; extend-env-with-binding: Env x Binding -> Env
  20. ;; extend-env-with-env: Env x Env -> Env
  21. ;; lookup: Key x Env -> (Binding + False)
  22. ;; env->list: Env -> Binding*
  23. ;; env-show: Env -> Symbol*
  24. ; bindings
  25. (define gen-binding cons)
  26. ; generates a type binding, binding a symbol to a type variable
  27. (define binding-key car)
  28. ; returns the key of a type binding
  29. (define binding-value cdr)
  30. ; returns the tvariable of a type binding
  31. (define (key-show key)
  32. ; default show procedure for keys
  33. key)
  34. (define (value-show value)
  35. ; default show procedure for values
  36. value)
  37. (define (binding-show binding)
  38. ; returns a printable representation of a type binding
  39. (cons (key-show (binding-key binding))
  40. (cons ': (value-show (binding-value binding)))))
  41. ; environments
  42. (define dynamic-empty-env '())
  43. ; returns the empty environment
  44. (define (extend-env-with-binding env binding)
  45. ; extends env with a binding, which hides any other binding in env
  46. ; for the same key (see dynamic-lookup)
  47. ; returns the extended environment
  48. (cons binding env))
  49. (define (extend-env-with-env env ext-env)
  50. ; extends environment env with environment ext-env
  51. ; a binding for a key in ext-env hides any binding in env for
  52. ; the same key (see dynamic-lookup)
  53. ; returns the extended environment
  54. (append ext-env env))
  55. (define dynamic-lookup (lambda (x l) (assv x l)))
  56. ; returns the first pair in env that matches the key; returns #f
  57. ; if no such pair exists
  58. (define (env->list e)
  59. ; converts an environment to a list of bindings
  60. e)
  61. (define (env-show env)
  62. ; returns a printable list representation of a type environment
  63. (map binding-show env))
  64. ;----------------------------------------------------------------------------
  65. ; Parsing for Scheme
  66. ;----------------------------------------------------------------------------
  67. ;; Needed packages: environment management
  68. ;(load "env-mgmt.ss")
  69. ;(load "pars-act.ss")
  70. ;; Lexical notions
  71. (define syntactic-keywords
  72. ;; source: IEEE Scheme, 7.1, <expression keyword>, <syntactic keyword>
  73. '(lambda if set! begin cond and or case let let* letrec do
  74. quasiquote else => define unquote unquote-splicing))
  75. ;; Parse routines
  76. ; Datum
  77. ; dynamic-parse-datum: parses nonterminal <datum>
  78. (define (dynamic-parse-datum e)
  79. ;; Source: IEEE Scheme, sect. 7.2, <datum>
  80. ;; Note: "'" is parsed as 'quote, "`" as 'quasiquote, "," as
  81. ;; 'unquote, ",@" as 'unquote-splicing (see sect. 4.2.5, p. 18)
  82. ;; ***Note***: quasi-quotations are not permitted! (It would be
  83. ;; necessary to pass the environment to dynamic-parse-datum.)
  84. (cond
  85. ((null? e)
  86. (dynamic-parse-action-null-const))
  87. ((boolean? e)
  88. (dynamic-parse-action-boolean-const e))
  89. ((char? e)
  90. (dynamic-parse-action-char-const e))
  91. ((number? e)
  92. (dynamic-parse-action-number-const e))
  93. ((string? e)
  94. (dynamic-parse-action-string-const e))
  95. ((symbol? e)
  96. (dynamic-parse-action-symbol-const e))
  97. ((vector? e)
  98. (dynamic-parse-action-vector-const (map dynamic-parse-datum (vector->list e))))
  99. ((pair? e)
  100. (dynamic-parse-action-pair-const (dynamic-parse-datum (car e))
  101. (dynamic-parse-datum (cdr e))))
  102. (else (error 'dynamic-parse-datum "Unknown datum: ~s" e))))
  103. ; VarDef
  104. ; dynamic-parse-formal: parses nonterminal <variable> in defining occurrence position
  105. (define (dynamic-parse-formal f-env e)
  106. ; e is an arbitrary object, f-env is a forbidden environment;
  107. ; returns: a variable definition (a binding for the symbol), plus
  108. ; the value of the binding as a result
  109. (if (symbol? e)
  110. (cond
  111. ((memq e syntactic-keywords)
  112. (error 'dynamic-parse-formal "Illegal identifier (keyword): ~s" e))
  113. ((dynamic-lookup e f-env)
  114. (error 'dynamic-parse-formal "Duplicate variable definition: ~s" e))
  115. (else (let ((dynamic-parse-action-result (dynamic-parse-action-var-def e)))
  116. (cons (gen-binding e dynamic-parse-action-result)
  117. dynamic-parse-action-result))))
  118. (error 'dynamic-parse-formal "Not an identifier: ~s" e)))
  119. ; dynamic-parse-formal*
  120. (define (dynamic-parse-formal* formals)
  121. ;; parses a list of formals and returns a pair consisting of generated
  122. ;; environment and list of parsing action results
  123. (letrec
  124. ((pf*
  125. (lambda (f-env results formals)
  126. ;; f-env: "forbidden" environment (to avoid duplicate defs)
  127. ;; results: the results of the parsing actions
  128. ;; formals: the unprocessed formals
  129. ;; Note: generates the results of formals in reverse order!
  130. (cond
  131. ((null? formals)
  132. (cons f-env results))
  133. ((pair? formals)
  134. (let* ((fst-formal (car formals))
  135. (binding-result (dynamic-parse-formal f-env fst-formal))
  136. (binding (car binding-result))
  137. (var-result (cdr binding-result)))
  138. (pf*
  139. (extend-env-with-binding f-env binding)
  140. (cons var-result results)
  141. (cdr formals))))
  142. (else (error 'dynamic-parse-formal* "Illegal formals: ~s" formals))))))
  143. (let ((renv-rres (pf* dynamic-empty-env '() formals)))
  144. (cons (car renv-rres) (reverse (cdr renv-rres))))))
  145. ; dynamic-parse-formals: parses <formals>
  146. (define (dynamic-parse-formals formals)
  147. ;; parses <formals>; see IEEE Scheme, sect. 7.3
  148. ;; returns a pair: env and result
  149. (letrec ((pfs (lambda (f-env formals)
  150. (cond
  151. ((null? formals)
  152. (cons dynamic-empty-env (dynamic-parse-action-null-formal)))
  153. ((pair? formals)
  154. (let* ((fst-formal (car formals))
  155. (rem-formals (cdr formals))
  156. (bind-res (dynamic-parse-formal f-env fst-formal))
  157. (bind (car bind-res))
  158. (res (cdr bind-res))
  159. (nf-env (extend-env-with-binding f-env bind))
  160. (renv-res* (pfs nf-env rem-formals))
  161. (renv (car renv-res*))
  162. (res* (cdr renv-res*)))
  163. (cons
  164. (extend-env-with-binding renv bind)
  165. (dynamic-parse-action-pair-formal res res*))))
  166. (else
  167. (let* ((bind-res (dynamic-parse-formal f-env formals))
  168. (bind (car bind-res))
  169. (res (cdr bind-res)))
  170. (cons
  171. (extend-env-with-binding dynamic-empty-env bind)
  172. res)))))))
  173. (pfs dynamic-empty-env formals)))
  174. ; Expr
  175. ; dynamic-parse-expression: parses nonterminal <expression>
  176. (define (dynamic-parse-expression env e)
  177. (cond
  178. ((symbol? e)
  179. (dynamic-parse-variable env e))
  180. ((pair? e)
  181. (let ((op (car e)) (args (cdr e)))
  182. (case op
  183. ((quote) (dynamic-parse-quote env args))
  184. ((lambda) (dynamic-parse-lambda env args))
  185. ((if) (dynamic-parse-if env args))
  186. ((set!) (dynamic-parse-set env args))
  187. ((begin) (dynamic-parse-begin env args))
  188. ((cond) (dynamic-parse-cond env args))
  189. ((case) (dynamic-parse-case env args))
  190. ((and) (dynamic-parse-and env args))
  191. ((or) (dynamic-parse-or env args))
  192. ((let) (dynamic-parse-let env args))
  193. ((let*) (dynamic-parse-let* env args))
  194. ((letrec) (dynamic-parse-letrec env args))
  195. ((do) (dynamic-parse-do env args))
  196. ((quasiquote) (dynamic-parse-quasiquote env args))
  197. (else (dynamic-parse-procedure-call env op args)))))
  198. (else (dynamic-parse-datum e))))
  199. ; dynamic-parse-expression*
  200. (define (dynamic-parse-expression* env exprs)
  201. ;; Parses lists of expressions (returns them in the right order!)
  202. (letrec ((pe*
  203. (lambda (results es)
  204. (cond
  205. ((null? es) results)
  206. ((pair? es) (pe* (cons (dynamic-parse-expression env (car es)) results) (cdr es)))
  207. (else (error 'dynamic-parse-expression* "Not a list of expressions: ~s" es))))))
  208. (reverse (pe* '() exprs))))
  209. ; dynamic-parse-expressions
  210. (define (dynamic-parse-expressions env exprs)
  211. ;; parses lists of arguments of a procedure call
  212. (cond
  213. ((null? exprs) (dynamic-parse-action-null-arg))
  214. ((pair? exprs) (let* ((fst-expr (car exprs))
  215. (rem-exprs (cdr exprs))
  216. (fst-res (dynamic-parse-expression env fst-expr))
  217. (rem-res (dynamic-parse-expressions env rem-exprs)))
  218. (dynamic-parse-action-pair-arg fst-res rem-res)))
  219. (else (error 'dynamic-parse-expressions "Illegal expression list: ~s"
  220. exprs))))
  221. ; dynamic-parse-variable: parses variables (applied occurrences)
  222. (define (dynamic-parse-variable env e)
  223. (if (symbol? e)
  224. (if (memq e syntactic-keywords)
  225. (error 'dynamic-parse-variable "Illegal identifier (keyword): ~s" e)
  226. (let ((assoc-var-def (dynamic-lookup e env)))
  227. (if assoc-var-def
  228. (dynamic-parse-action-variable (binding-value assoc-var-def))
  229. (dynamic-parse-action-identifier e))))
  230. (error 'dynamic-parse-variable "Not an identifier: ~s" e)))
  231. ; dynamic-parse-procedure-call
  232. (define (dynamic-parse-procedure-call env op args)
  233. (dynamic-parse-action-procedure-call
  234. (dynamic-parse-expression env op)
  235. (dynamic-parse-expressions env args)))
  236. ; dynamic-parse-quote
  237. (define (dynamic-parse-quote env args)
  238. (if (list-of-1? args)
  239. (dynamic-parse-datum (car args))
  240. (error 'dynamic-parse-quote "Not a datum (multiple arguments): ~s" args)))
  241. ; dynamic-parse-lambda
  242. (define (dynamic-parse-lambda env args)
  243. (if (pair? args)
  244. (let* ((formals (car args))
  245. (body (cdr args))
  246. (nenv-fresults (dynamic-parse-formals formals))
  247. (nenv (car nenv-fresults))
  248. (fresults (cdr nenv-fresults)))
  249. (dynamic-parse-action-lambda-expression
  250. fresults
  251. (dynamic-parse-body (extend-env-with-env env nenv) body)))
  252. (error 'dynamic-parse-lambda "Illegal formals/body: ~s" args)))
  253. ; dynamic-parse-body
  254. (define (dynamic-parse-body env body)
  255. ; <body> = <definition>* <expression>+
  256. (define (def-var* f-env body)
  257. ; finds the defined variables in a body and returns an
  258. ; environment containing them
  259. (if (pair? body)
  260. (let ((n-env (def-var f-env (car body))))
  261. (if n-env
  262. (def-var* n-env (cdr body))
  263. f-env))
  264. f-env))
  265. (define (def-var f-env clause)
  266. ; finds the defined variables in a single clause and extends
  267. ; f-env accordingly; returns false if it's not a definition
  268. (if (pair? clause)
  269. (case (car clause)
  270. ((define) (if (pair? (cdr clause))
  271. (let ((pattern (cadr clause)))
  272. (cond
  273. ((symbol? pattern)
  274. (extend-env-with-binding
  275. f-env
  276. (gen-binding pattern
  277. (dynamic-parse-action-var-def pattern))))
  278. ((and (pair? pattern) (symbol? (car pattern)))
  279. (extend-env-with-binding
  280. f-env
  281. (gen-binding (car pattern)
  282. (dynamic-parse-action-var-def
  283. (car pattern)))))
  284. (else f-env)))
  285. f-env))
  286. ((begin) (def-var* f-env (cdr clause)))
  287. (else #f))
  288. #f))
  289. (if (pair? body)
  290. (dynamic-parse-command* (def-var* env body) body)
  291. (error 'dynamic-parse-body "Illegal body: ~s" body)))
  292. ; dynamic-parse-if
  293. (define (dynamic-parse-if env args)
  294. (cond
  295. ((list-of-3? args)
  296. (dynamic-parse-action-conditional
  297. (dynamic-parse-expression env (car args))
  298. (dynamic-parse-expression env (cadr args))
  299. (dynamic-parse-expression env (caddr args))))
  300. ((list-of-2? args)
  301. (dynamic-parse-action-conditional
  302. (dynamic-parse-expression env (car args))
  303. (dynamic-parse-expression env (cadr args))
  304. (dynamic-parse-action-empty)))
  305. (else (error 'dynamic-parse-if "Not an if-expression: ~s" args))))
  306. ; dynamic-parse-set
  307. (define (dynamic-parse-set env args)
  308. (if (list-of-2? args)
  309. (dynamic-parse-action-assignment
  310. (dynamic-parse-variable env (car args))
  311. (dynamic-parse-expression env (cadr args)))
  312. (error 'dynamic-parse-set "Not a variable/expression pair: ~s" args)))
  313. ; dynamic-parse-begin
  314. (define (dynamic-parse-begin env args)
  315. (dynamic-parse-action-begin-expression
  316. (dynamic-parse-body env args)))
  317. ; dynamic-parse-cond
  318. (define (dynamic-parse-cond env args)
  319. (if (and (pair? args) (list? args))
  320. (dynamic-parse-action-cond-expression
  321. (map (lambda (e)
  322. (dynamic-parse-cond-clause env e))
  323. args))
  324. (error 'dynamic-parse-cond "Not a list of cond-clauses: ~s" args)))
  325. ; dynamic-parse-cond-clause
  326. (define (dynamic-parse-cond-clause env e)
  327. ;; ***Note***: Only (<test> <sequence>) is permitted!
  328. (if (pair? e)
  329. (cons
  330. (if (eqv? (car e) 'else)
  331. (dynamic-parse-action-empty)
  332. (dynamic-parse-expression env (car e)))
  333. (dynamic-parse-body env (cdr e)))
  334. (error 'dynamic-parse-cond-clause "Not a cond-clause: ~s" e)))
  335. ; dynamic-parse-and
  336. (define (dynamic-parse-and env args)
  337. (if (list? args)
  338. (dynamic-parse-action-and-expression
  339. (dynamic-parse-expression* env args))
  340. (error 'dynamic-parse-and "Not a list of arguments: ~s" args)))
  341. ; dynamic-parse-or
  342. (define (dynamic-parse-or env args)
  343. (if (list? args)
  344. (dynamic-parse-action-or-expression
  345. (dynamic-parse-expression* env args))
  346. (error 'dynamic-parse-or "Not a list of arguments: ~s" args)))
  347. ; dynamic-parse-case
  348. (define (dynamic-parse-case env args)
  349. (if (and (list? args) (> (length args) 1))
  350. (dynamic-parse-action-case-expression
  351. (dynamic-parse-expression env (car args))
  352. (map (lambda (e)
  353. (dynamic-parse-case-clause env e))
  354. (cdr args)))
  355. (error 'dynamic-parse-case "Not a list of clauses: ~s" args)))
  356. ; dynamic-parse-case-clause
  357. (define (dynamic-parse-case-clause env e)
  358. (if (pair? e)
  359. (cons
  360. (cond
  361. ((eqv? (car e) 'else)
  362. (list (dynamic-parse-action-empty)))
  363. ((list? (car e))
  364. (map dynamic-parse-datum (car e)))
  365. (else (error 'dynamic-parse-case-clause "Not a datum list: ~s" (car e))))
  366. (dynamic-parse-body env (cdr e)))
  367. (error 'dynamic-parse-case-clause "Not case clause: ~s" e)))
  368. ; dynamic-parse-let
  369. (define (dynamic-parse-let env args)
  370. (if (pair? args)
  371. (if (symbol? (car args))
  372. (dynamic-parse-named-let env args)
  373. (dynamic-parse-normal-let env args))
  374. (error 'dynamic-parse-let "Illegal bindings/body: ~s" args)))
  375. ; dynamic-parse-normal-let
  376. (define (dynamic-parse-normal-let env args)
  377. ;; parses "normal" let-expressions
  378. (let* ((bindings (car args))
  379. (body (cdr args))
  380. (env-ast (dynamic-parse-parallel-bindings env bindings))
  381. (nenv (car env-ast))
  382. (bresults (cdr env-ast)))
  383. (dynamic-parse-action-let-expression
  384. bresults
  385. (dynamic-parse-body (extend-env-with-env env nenv) body))))
  386. ; dynamic-parse-named-let
  387. (define (dynamic-parse-named-let env args)
  388. ;; parses a named let-expression
  389. (if (pair? (cdr args))
  390. (let* ((variable (car args))
  391. (bindings (cadr args))
  392. (body (cddr args))
  393. (vbind-vres (dynamic-parse-formal dynamic-empty-env variable))
  394. (vbind (car vbind-vres))
  395. (vres (cdr vbind-vres))
  396. (env-ast (dynamic-parse-parallel-bindings env bindings))
  397. (nenv (car env-ast))
  398. (bresults (cdr env-ast)))
  399. (dynamic-parse-action-named-let-expression
  400. vres bresults
  401. (dynamic-parse-body (extend-env-with-env
  402. (extend-env-with-binding env vbind)
  403. nenv) body)))
  404. (error 'dynamic-parse-named-let "Illegal named let-expression: ~s" args)))
  405. ; dynamic-parse-parallel-bindings
  406. (define (dynamic-parse-parallel-bindings env bindings)
  407. ; returns a pair consisting of an environment
  408. ; and a list of pairs (variable . asg)
  409. ; ***Note***: the list of pairs is returned in reverse unzipped form!
  410. (if (list-of-list-of-2s? bindings)
  411. (let* ((env-formals-asg
  412. (dynamic-parse-formal* (map car bindings)))
  413. (nenv (car env-formals-asg))
  414. (bresults (cdr env-formals-asg))
  415. (exprs-asg
  416. (dynamic-parse-expression* env (map cadr bindings))))
  417. (cons nenv (cons bresults exprs-asg)))
  418. (error 'dynamic-parse-parallel-bindings
  419. "Not a list of bindings: ~s" bindings)))
  420. ; dynamic-parse-let*
  421. (define (dynamic-parse-let* env args)
  422. (if (pair? args)
  423. (let* ((bindings (car args))
  424. (body (cdr args))
  425. (env-ast (dynamic-parse-sequential-bindings env bindings))
  426. (nenv (car env-ast))
  427. (bresults (cdr env-ast)))
  428. (dynamic-parse-action-let*-expression
  429. bresults
  430. (dynamic-parse-body (extend-env-with-env env nenv) body)))
  431. (error 'dynamic-parse-let* "Illegal bindings/body: ~s" args)))
  432. ; dynamic-parse-sequential-bindings
  433. (define (dynamic-parse-sequential-bindings env bindings)
  434. ; returns a pair consisting of an environment
  435. ; and a list of pairs (variable . asg)
  436. ;; ***Note***: the list of pairs is returned in reverse unzipped form!
  437. (letrec
  438. ((psb
  439. (lambda (f-env c-env var-defs expr-asgs binds)
  440. ;; f-env: forbidden environment
  441. ;; c-env: constructed environment
  442. ;; var-defs: results of formals
  443. ;; expr-asgs: results of corresponding expressions
  444. ;; binds: reminding bindings to process
  445. (cond
  446. ((null? binds)
  447. (cons f-env (cons var-defs expr-asgs)))
  448. ((pair? binds)
  449. (let ((fst-bind (car binds)))
  450. (if (list-of-2? fst-bind)
  451. (let* ((fbinding-bres
  452. (dynamic-parse-formal f-env (car fst-bind)))
  453. (fbind (car fbinding-bres))
  454. (bres (cdr fbinding-bres))
  455. (new-expr-asg
  456. (dynamic-parse-expression c-env (cadr fst-bind))))
  457. (psb
  458. (extend-env-with-binding f-env fbind)
  459. (extend-env-with-binding c-env fbind)
  460. (cons bres var-defs)
  461. (cons new-expr-asg expr-asgs)
  462. (cdr binds)))
  463. (error 'dynamic-parse-sequential-bindings
  464. "Illegal binding: ~s" fst-bind))))
  465. (else (error 'dynamic-parse-sequential-bindings
  466. "Illegal bindings: ~s" binds))))))
  467. (let ((env-vdefs-easgs (psb dynamic-empty-env env '() '() bindings)))
  468. (cons (car env-vdefs-easgs)
  469. (cons (reverse (cadr env-vdefs-easgs))
  470. (reverse (cddr env-vdefs-easgs)))))))
  471. ; dynamic-parse-letrec
  472. (define (dynamic-parse-letrec env args)
  473. (if (pair? args)
  474. (let* ((bindings (car args))
  475. (body (cdr args))
  476. (env-ast (dynamic-parse-recursive-bindings env bindings))
  477. (nenv (car env-ast))
  478. (bresults (cdr env-ast)))
  479. (dynamic-parse-action-letrec-expression
  480. bresults
  481. (dynamic-parse-body (extend-env-with-env env nenv) body)))
  482. (error 'dynamic-parse-letrec "Illegal bindings/body: ~s" args)))
  483. ; dynamic-parse-recursive-bindings
  484. (define (dynamic-parse-recursive-bindings env bindings)
  485. ;; ***Note***: the list of pairs is returned in reverse unzipped form!
  486. (if (list-of-list-of-2s? bindings)
  487. (let* ((env-formals-asg
  488. (dynamic-parse-formal* (map car bindings)))
  489. (formals-env
  490. (car env-formals-asg))
  491. (formals-res
  492. (cdr env-formals-asg))
  493. (exprs-asg
  494. (dynamic-parse-expression*
  495. (extend-env-with-env env formals-env)
  496. (map cadr bindings))))
  497. (cons
  498. formals-env
  499. (cons formals-res exprs-asg)))
  500. (error 'dynamic-parse-recursive-bindings "Illegal bindings: ~s" bindings)))
  501. ; dynamic-parse-do
  502. (define (dynamic-parse-do env args)
  503. ;; parses do-expressions
  504. ;; ***Note***: Not implemented!
  505. (error 'dynamic-parse-do "Nothing yet..."))
  506. ; dynamic-parse-quasiquote
  507. (define (dynamic-parse-quasiquote env args)
  508. ;; ***Note***: Not implemented!
  509. (error 'dynamic-parse-quasiquote "Nothing yet..."))
  510. ;; Command
  511. ; dynamic-parse-command
  512. (define (dynamic-parse-command env c)
  513. (if (pair? c)
  514. (let ((op (car c))
  515. (args (cdr c)))
  516. (case op
  517. ((define) (dynamic-parse-define env args))
  518. ; ((begin) (dynamic-parse-command* env args)) ;; AKW
  519. ((begin) (dynamic-parse-action-begin-expression (dynamic-parse-command* env args)))
  520. (else (dynamic-parse-expression env c))))
  521. (dynamic-parse-expression env c)))
  522. ; dynamic-parse-command*
  523. (define (dynamic-parse-command* env commands)
  524. ;; parses a sequence of commands
  525. (if (list? commands)
  526. (map (lambda (command) (dynamic-parse-command env command)) commands)
  527. (error 'dynamic-parse-command* "Invalid sequence of commands: ~s" commands)))
  528. ; dynamic-parse-define
  529. (define (dynamic-parse-define env args)
  530. ;; three cases -- see IEEE Scheme, sect. 5.2
  531. ;; ***Note***: the parser admits forms (define (x . y) ...)
  532. ;; ***Note***: Variables are treated as applied occurrences!
  533. (if (pair? args)
  534. (let ((pattern (car args))
  535. (exp-or-body (cdr args)))
  536. (cond
  537. ((symbol? pattern)
  538. (if (list-of-1? exp-or-body)
  539. (dynamic-parse-action-definition
  540. (dynamic-parse-variable env pattern)
  541. (dynamic-parse-expression env (car exp-or-body)))
  542. (error 'dynamic-parse-define "Not a single expression: ~s" exp-or-body)))
  543. ((pair? pattern)
  544. (let* ((function-name (car pattern))
  545. (function-arg-names (cdr pattern))
  546. (env-ast (dynamic-parse-formals function-arg-names))
  547. (formals-env (car env-ast))
  548. (formals-ast (cdr env-ast)))
  549. (dynamic-parse-action-function-definition
  550. (dynamic-parse-variable env function-name)
  551. formals-ast
  552. (dynamic-parse-body (extend-env-with-env env formals-env) exp-or-body))))
  553. (else (error 'dynamic-parse-define "Not a valid pattern: ~s" pattern))))
  554. (error 'dynamic-parse-define "Not a valid definition: ~s" args)))
  555. ;; Auxiliary routines
  556. ; forall?
  557. (define (forall? pred list)
  558. (if (null? list)
  559. #t
  560. (and (pred (car list)) (forall? pred (cdr list)))))
  561. ; list-of-1?
  562. (define (list-of-1? l)
  563. (and (pair? l) (null? (cdr l))))
  564. ; list-of-2?
  565. (define (list-of-2? l)
  566. (and (pair? l) (pair? (cdr l)) (null? (cddr l))))
  567. ; list-of-3?
  568. (define (list-of-3? l)
  569. (and (pair? l) (pair? (cdr l)) (pair? (cddr l)) (null? (cdddr l))))
  570. ; list-of-list-of-2s?
  571. (define (list-of-list-of-2s? e)
  572. (cond
  573. ((null? e)
  574. #t)
  575. ((pair? e)
  576. (and (list-of-2? (car e)) (list-of-list-of-2s? (cdr e))))
  577. (else #f)))
  578. ;; File processing
  579. ; dynamic-parse-from-port
  580. (define (dynamic-parse-from-port port)
  581. (let ((next-input (read port)))
  582. (if (eof-object? next-input)
  583. '()
  584. (dynamic-parse-action-commands
  585. (dynamic-parse-command dynamic-empty-env next-input)
  586. (dynamic-parse-from-port port)))))
  587. ; dynamic-parse-file
  588. (define (dynamic-parse-file file-name)
  589. (let ((input-port (open-input-file file-name)))
  590. (dynamic-parse-from-port input-port)))
  591. ;----------------------------------------------------------------------------
  592. ; Implementation of Union/find data structure in Scheme
  593. ;----------------------------------------------------------------------------
  594. ;; for union/find the following attributes are necessary: rank, parent
  595. ;; (see Tarjan, "Data structures and network algorithms", 1983)
  596. ;; In the Scheme realization an element is represented as a single
  597. ;; cons cell; its address is the element itself; the car field contains
  598. ;; the parent, the cdr field is an address for a cons
  599. ;; cell containing the rank (car field) and the information (cdr field)
  600. ;; general union/find data structure
  601. ;;
  602. ;; gen-element: Info -> Elem
  603. ;; find: Elem -> Elem
  604. ;; link: Elem! x Elem! -> Elem
  605. ;; asymm-link: Elem! x Elem! -> Elem
  606. ;; info: Elem -> Info
  607. ;; set-info!: Elem! x Info -> Void
  608. (define (gen-element info)
  609. ; generates a new element: the parent field is initialized to '(),
  610. ; the rank field to 0
  611. (cons '() (cons 0 info)))
  612. (define info (lambda (l) (cddr l)))
  613. ; returns the information stored in an element
  614. (define (set-info! elem info)
  615. ; sets the info-field of elem to info
  616. (set-cdr! (cdr elem) info))
  617. ; (define (find! x)
  618. ; ; finds the class representative of x and sets the parent field
  619. ; ; directly to the class representative (a class representative has
  620. ; ; '() as its parent) (uses path halving)
  621. ; ;(display "Find!: ")
  622. ; ;(display (pretty-print (info x)))
  623. ; ;(newline)
  624. ; (let ((px (car x)))
  625. ; (if (null? px)
  626. ; x
  627. ; (let ((ppx (car px)))
  628. ; (if (null? ppx)
  629. ; px
  630. ; (begin
  631. ; (set-car! x ppx)
  632. ; (find! ppx)))))))
  633. (define (find! elem)
  634. ; finds the class representative of elem and sets the parent field
  635. ; directly to the class representative (a class representative has
  636. ; '() as its parent)
  637. ;(display "Find!: ")
  638. ;(display (pretty-print (info elem)))
  639. ;(newline)
  640. (let ((p-elem (car elem)))
  641. (if (null? p-elem)
  642. elem
  643. (let ((rep-elem (find! p-elem)))
  644. (set-car! elem rep-elem)
  645. rep-elem))))
  646. (define (link! elem-1 elem-2)
  647. ; links class elements by rank
  648. ; they must be distinct class representatives
  649. ; returns the class representative of the merged equivalence classes
  650. ;(display "Link!: ")
  651. ;(display (pretty-print (list (info elem-1) (info elem-2))))
  652. ;(newline)
  653. (let ((rank-1 (cadr elem-1))
  654. (rank-2 (cadr elem-2)))
  655. (cond
  656. ((= rank-1 rank-2)
  657. (set-car! (cdr elem-2) (+ rank-2 1))
  658. (set-car! elem-1 elem-2)
  659. elem-2)
  660. ((> rank-1 rank-2)
  661. (set-car! elem-2 elem-1)
  662. elem-1)
  663. (else
  664. (set-car! elem-1 elem-2)
  665. elem-2))))
  666. (define asymm-link! (lambda (l x) (set-car! l x)))
  667. ;(define (asymm-link! elem-1 elem-2)
  668. ; links elem-1 onto elem-2 no matter what rank;
  669. ; does not update the rank of elem-2 and does not return a value
  670. ; the two arguments must be distinct
  671. ;(display "AsymmLink: ")
  672. ;(display (pretty-print (list (info elem-1) (info elem-2))))
  673. ;(newline)
  674. ;(set-car! elem-1 elem-2))
  675. ;----------------------------------------------------------------------------
  676. ; Type management
  677. ;----------------------------------------------------------------------------
  678. ; introduces type variables and types for Scheme,
  679. ;; type TVar (type variables)
  680. ;;
  681. ;; gen-tvar: () -> TVar
  682. ;; gen-type: TCon x TVar* -> TVar
  683. ;; dynamic: TVar
  684. ;; tvar-id: TVar -> Symbol
  685. ;; tvar-def: TVar -> Type + Null
  686. ;; tvar-show: TVar -> Symbol*
  687. ;;
  688. ;; set-def!: !TVar x TCon x TVar* -> Null
  689. ;; equiv!: !TVar x !TVar -> Null
  690. ;;
  691. ;;
  692. ;; type TCon (type constructors)
  693. ;;
  694. ;; ...
  695. ;;
  696. ;; type Type (types)
  697. ;;
  698. ;; gen-type: TCon x TVar* -> Type
  699. ;; type-con: Type -> TCon
  700. ;; type-args: Type -> TVar*
  701. ;;
  702. ;; boolean: TVar
  703. ;; character: TVar
  704. ;; null: TVar
  705. ;; pair: TVar x TVar -> TVar
  706. ;; procedure: TVar x TVar* -> TVar
  707. ;; charseq: TVar
  708. ;; symbol: TVar
  709. ;; array: TVar -> TVar
  710. ; Needed packages: union/find
  711. ;(load "union-fi.so")
  712. ; TVar
  713. (define counter 0)
  714. ; counter for generating tvar id's
  715. (define (gen-id)
  716. ; generates a new id (for printing purposes)
  717. (set! counter (+ counter 1))
  718. counter)
  719. (define (gen-tvar)
  720. ; generates a new type variable from a new symbol
  721. ; uses union/find elements with two info fields
  722. ; a type variable has exactly four fields:
  723. ; car: TVar (the parent field; initially null)
  724. ; cadr: Number (the rank field; is always nonnegative)
  725. ; caddr: Symbol (the type variable identifier; used only for printing)
  726. ; cdddr: Type (the leq field; initially null)
  727. (gen-element (cons (gen-id) '())))
  728. (define (gen-type tcon targs)
  729. ; generates a new type variable with an associated type definition
  730. (gen-element (cons (gen-id) (cons tcon targs))))
  731. (define dynamic (gen-element (cons 0 '())))
  732. ; the special type variable dynamic
  733. ; Generic operations
  734. (define (tvar-id tvar)
  735. ; returns the (printable) symbol representing the type variable
  736. (car (info tvar)))
  737. (define (tvar-def tvar)
  738. ; returns the type definition (if any) of the type variable
  739. (cdr (info tvar)))
  740. (define (set-def! tvar tcon targs)
  741. ; sets the type definition part of tvar to type
  742. (set-cdr! (info tvar) (cons tcon targs))
  743. '())
  744. (define (reset-def! tvar)
  745. ; resets the type definition part of tvar to nil
  746. (set-cdr! (info tvar) '()))
  747. (define type-con (lambda (l) (car l)))
  748. ; returns the type constructor of a type definition
  749. (define type-args (lambda (l) (cdr l)))
  750. ; returns the type variables of a type definition
  751. (define (tvar->string tvar)
  752. ; converts a tvar's id to a string
  753. (if (eqv? (tvar-id tvar) 0)
  754. "Dynamic"
  755. (string-append "t#" (number->string (tvar-id tvar) 10))))
  756. (define (tvar-show tv)
  757. ; returns a printable list representation of type variable tv
  758. (let* ((tv-rep (find! tv))
  759. (tv-def (tvar-def tv-rep)))
  760. (cons (tvar->string tv-rep)
  761. (if (null? tv-def)
  762. '()
  763. (cons 'is (type-show tv-def))))))
  764. (define (type-show type)
  765. ; returns a printable list representation of type definition type
  766. (cond
  767. ((eqv? (type-con type) ptype-con)
  768. (let ((new-tvar (gen-tvar)))
  769. (cons ptype-con
  770. (cons (tvar-show new-tvar)
  771. (tvar-show ((type-args type) new-tvar))))))
  772. (else
  773. (cons (type-con type)
  774. (map (lambda (tv)
  775. (tvar->string (find! tv)))
  776. (type-args type))))))
  777. ; Special type operations
  778. ; type constructor literals
  779. (define boolean-con 'boolean)
  780. (define char-con 'char)
  781. (define null-con 'null)
  782. (define number-con 'number)
  783. (define pair-con 'pair)
  784. (define procedure-con 'procedure)
  785. (define string-con 'string)
  786. (define symbol-con 'symbol)
  787. (define vector-con 'vector)
  788. ; type constants and type constructors
  789. (define (null)
  790. ; ***Note***: Temporarily changed to be a pair!
  791. ; (gen-type null-con '())
  792. (pair (gen-tvar) (gen-tvar)))
  793. (define (boolean)
  794. (gen-type boolean-con '()))
  795. (define (character)
  796. (gen-type char-con '()))
  797. (define (number)
  798. (gen-type number-con '()))
  799. (define (charseq)
  800. (gen-type string-con '()))
  801. (define (symbol)
  802. (gen-type symbol-con '()))
  803. (define (pair tvar-1 tvar-2)
  804. (gen-type pair-con (list tvar-1 tvar-2)))
  805. (define (array tvar)
  806. (gen-type vector-con (list tvar)))
  807. (define (procedure arg-tvar res-tvar)
  808. (gen-type procedure-con (list arg-tvar res-tvar)))
  809. ; equivalencing of type variables
  810. (define (equiv! tv1 tv2)
  811. (let* ((tv1-rep (find! tv1))
  812. (tv2-rep (find! tv2))
  813. (tv1-def (tvar-def tv1-rep))
  814. (tv2-def (tvar-def tv2-rep)))
  815. (cond
  816. ((eqv? tv1-rep tv2-rep)
  817. '())
  818. ((eqv? tv2-rep dynamic)
  819. (equiv-with-dynamic! tv1-rep))
  820. ((eqv? tv1-rep dynamic)
  821. (equiv-with-dynamic! tv2-rep))
  822. ((null? tv1-def)
  823. (if (null? tv2-def)
  824. ; both tv1 and tv2 are distinct type variables
  825. (link! tv1-rep tv2-rep)
  826. ; tv1 is a type variable, tv2 is a (nondynamic) type
  827. (asymm-link! tv1-rep tv2-rep)))
  828. ((null? tv2-def)
  829. ; tv1 is a (nondynamic) type, tv2 is a type variable
  830. (asymm-link! tv2-rep tv1-rep))
  831. ((eqv? (type-con tv1-def) (type-con tv2-def))
  832. ; both tv1 and tv2 are (nondynamic) types with equal numbers of
  833. ; arguments
  834. (link! tv1-rep tv2-rep)
  835. (map equiv! (type-args tv1-def) (type-args tv2-def)))
  836. (else
  837. ; tv1 and tv2 are types with distinct type constructors or different
  838. ; numbers of arguments
  839. (equiv-with-dynamic! tv1-rep)
  840. (equiv-with-dynamic! tv2-rep))))
  841. '())
  842. (define (equiv-with-dynamic! tv)
  843. (let ((tv-rep (find! tv)))
  844. (if (not (eqv? tv-rep dynamic))
  845. (let ((tv-def (tvar-def tv-rep)))
  846. (asymm-link! tv-rep dynamic)
  847. (if (not (null? tv-def))
  848. (map equiv-with-dynamic! (type-args tv-def))))))
  849. '())
  850. ;----------------------------------------------------------------------------
  851. ; Polymorphic type management
  852. ;----------------------------------------------------------------------------
  853. ; introduces parametric polymorphic types
  854. ;; forall: (Tvar -> Tvar) -> TVar
  855. ;; fix: (Tvar -> Tvar) -> Tvar
  856. ;;
  857. ;; instantiate-type: TVar -> TVar
  858. ; type constructor literal for polymorphic types
  859. (define ptype-con 'forall)
  860. (define (forall tv-func)
  861. (gen-type ptype-con tv-func))
  862. (define (forall2 tv-func2)
  863. (forall (lambda (tv1)
  864. (forall (lambda (tv2)
  865. (tv-func2 tv1 tv2))))))
  866. (define (forall3 tv-func3)
  867. (forall (lambda (tv1)
  868. (forall2 (lambda (tv2 tv3)
  869. (tv-func3 tv1 tv2 tv3))))))
  870. (define (forall4 tv-func4)
  871. (forall (lambda (tv1)
  872. (forall3 (lambda (tv2 tv3 tv4)
  873. (tv-func4 tv1 tv2 tv3 tv4))))))
  874. (define (forall5 tv-func5)
  875. (forall (lambda (tv1)
  876. (forall4 (lambda (tv2 tv3 tv4 tv5)
  877. (tv-func5 tv1 tv2 tv3 tv4 tv5))))))
  878. ; (polymorphic) instantiation
  879. (define (instantiate-type tv)
  880. ; instantiates type tv and returns a generic instance
  881. (let* ((tv-rep (find! tv))
  882. (tv-def (tvar-def tv-rep)))
  883. (cond
  884. ((null? tv-def)
  885. tv-rep)
  886. ((eqv? (type-con tv-def) ptype-con)
  887. (instantiate-type ((type-args tv-def) (gen-tvar))))
  888. (else
  889. tv-rep))))
  890. (define (fix tv-func)
  891. ; forms a recursive type: the fixed point of type mapping tv-func
  892. (let* ((new-tvar (gen-tvar))
  893. (inst-tvar (tv-func new-tvar))
  894. (inst-def (tvar-def inst-tvar)))
  895. (if (null? inst-def)
  896. (error 'fix "Illegal recursive type: ~s"
  897. (list (tvar-show new-tvar) '= (tvar-show inst-tvar)))
  898. (begin
  899. (set-def! new-tvar
  900. (type-con inst-def)
  901. (type-args inst-def))
  902. new-tvar))))
  903. ;----------------------------------------------------------------------------
  904. ; Constraint management
  905. ;----------------------------------------------------------------------------
  906. ; constraints
  907. (define gen-constr (lambda (a b) (cons a b)))
  908. ; generates an equality between tvar1 and tvar2
  909. (define constr-lhs (lambda (c) (car c)))
  910. ; returns the left-hand side of a constraint
  911. (define constr-rhs (lambda (c) (cdr c)))
  912. ; returns the right-hand side of a constraint
  913. (define (constr-show c)
  914. (cons (tvar-show (car c))
  915. (cons '=
  916. (cons (tvar-show (cdr c)) '()))))
  917. ; constraint set management
  918. (define global-constraints '())
  919. (define (init-global-constraints!)
  920. (set! global-constraints '()))
  921. (define (add-constr! lhs rhs)
  922. (set! global-constraints
  923. (cons (gen-constr lhs rhs) global-constraints))
  924. '())
  925. (define (glob-constr-show)
  926. ; returns printable version of global constraints
  927. (map constr-show global-constraints))
  928. ; constraint normalization
  929. ; Needed packages: type management
  930. ;(load "typ-mgmt.so")
  931. (define (normalize-global-constraints!)
  932. (normalize! global-constraints)
  933. (init-global-constraints!))
  934. (define (normalize! constraints)
  935. (map (lambda (c)
  936. (equiv! (constr-lhs c) (constr-rhs c))) constraints))
  937. ; ----------------------------------------------------------------------------
  938. ; Abstract syntax definition and parse actions
  939. ; ----------------------------------------------------------------------------
  940. ; Needed packages: ast-gen.ss
  941. ;(load "ast-gen.ss")
  942. ;; Abstract syntax
  943. ;;
  944. ;; VarDef
  945. ;;
  946. ;; Identifier = Symbol - SyntacticKeywords
  947. ;; SyntacticKeywords = { ... } (see Section 7.1, IEEE Scheme Standard)
  948. ;;
  949. ;; Datum
  950. ;;
  951. ;; null-const: Null -> Datum
  952. ;; boolean-const: Bool -> Datum
  953. ;; char-const: Char -> Datum
  954. ;; number-const: Number -> Datum
  955. ;; string-const: String -> Datum
  956. ;; vector-const: Datum* -> Datum
  957. ;; pair-const: Datum x Datum -> Datum
  958. ;;
  959. ;; Expr
  960. ;;
  961. ;; Datum < Expr
  962. ;;
  963. ;; var-def: Identifier -> VarDef
  964. ;; variable: VarDef -> Expr
  965. ;; identifier: Identifier -> Expr
  966. ;; procedure-call: Expr x Expr* -> Expr
  967. ;; lambda-expression: Formals x Body -> Expr
  968. ;; conditional: Expr x Expr x Expr -> Expr
  969. ;; assignment: Variable x Expr -> Expr
  970. ;; cond-expression: CondClause+ -> Expr
  971. ;; case-expression: Expr x CaseClause* -> Expr
  972. ;; and-expression: Expr* -> Expr
  973. ;; or-expression: Expr* -> Expr
  974. ;; let-expression: (VarDef* x Expr*) x Body -> Expr
  975. ;; named-let-expression: VarDef x (VarDef* x Expr*) x Body -> Expr
  976. ;; let*-expression: (VarDef* x Expr*) x Body -> Expr
  977. ;; letrec-expression: (VarDef* x Expr*) x Body -> Expr
  978. ;; begin-expression: Expr+ -> Expr
  979. ;; do-expression: IterDef* x CondClause x Expr* -> Expr
  980. ;; empty: -> Expr
  981. ;;
  982. ;; VarDef* < Formals
  983. ;;
  984. ;; simple-formal: VarDef -> Formals
  985. ;; dotted-formals: VarDef* x VarDef -> Formals
  986. ;;
  987. ;; Body = Definition* x Expr+ (reversed)
  988. ;; CondClause = Expr x Expr+
  989. ;; CaseClause = Datum* x Expr+
  990. ;; IterDef = VarDef x Expr x Expr
  991. ;;
  992. ;; Definition
  993. ;;
  994. ;; definition: Identifier x Expr -> Definition
  995. ;; function-definition: Identifier x Formals x Body -> Definition
  996. ;; begin-command: Definition* -> Definition
  997. ;;
  998. ;; Expr < Command
  999. ;; Definition < Command
  1000. ;;
  1001. ;; Program = Command*
  1002. ;; Abstract syntax operators
  1003. ; Datum
  1004. (define null-const 0)
  1005. (define boolean-const 1)
  1006. (define char-const 2)
  1007. (define number-const 3)
  1008. (define string-const 4)
  1009. (define symbol-const 5)
  1010. (define vector-const 6)
  1011. (define pair-const 7)
  1012. ; Bindings
  1013. (define var-def 8)
  1014. (define null-def 29)
  1015. (define pair-def 30)
  1016. ; Expr
  1017. (define variable 9)
  1018. (define identifier 10)
  1019. (define procedure-call 11)
  1020. (define lambda-expression 12)
  1021. (define conditional 13)
  1022. (define assignment 14)
  1023. (define cond-expression 15)
  1024. (define case-expression 16)
  1025. (define and-expression 17)
  1026. (define or-expression 18)
  1027. (define let-expression 19)
  1028. (define named-let-expression 20)
  1029. (define let*-expression 21)
  1030. (define letrec-expression 22)
  1031. (define begin-expression 23)
  1032. (define do-expression 24)
  1033. (define empty 25)
  1034. (define null-arg 31)
  1035. (define pair-arg 32)
  1036. ; Command
  1037. (define definition 26)
  1038. (define function-definition 27)
  1039. (define begin-command 28)
  1040. ;; Parse actions for abstract syntax construction
  1041. (define (dynamic-parse-action-null-const)
  1042. ;; dynamic-parse-action for '()
  1043. (ast-gen null-const '()))
  1044. (define (dynamic-parse-action-boolean-const e)
  1045. ;; dynamic-parse-action for #f and #t
  1046. (ast-gen boolean-const e))
  1047. (define (dynamic-parse-action-char-const e)
  1048. ;; dynamic-parse-action for character constants
  1049. (ast-gen char-const e))
  1050. (define (dynamic-parse-action-number-const e)
  1051. ;; dynamic-parse-action for number constants
  1052. (ast-gen number-const e))
  1053. (define (dynamic-parse-action-string-const e)
  1054. ;; dynamic-parse-action for string literals
  1055. (ast-gen string-const e))
  1056. (define (dynamic-parse-action-symbol-const e)
  1057. ;; dynamic-parse-action for symbol constants
  1058. (ast-gen symbol-const e))
  1059. (define (dynamic-parse-action-vector-const e)
  1060. ;; dynamic-parse-action for vector literals
  1061. (ast-gen vector-const e))
  1062. (define (dynamic-parse-action-pair-const e1 e2)
  1063. ;; dynamic-parse-action for pairs
  1064. (ast-gen pair-const (cons e1 e2)))
  1065. (define (dynamic-parse-action-var-def e)
  1066. ;; dynamic-parse-action for defining occurrences of variables;
  1067. ;; e is a symbol
  1068. (ast-gen var-def e))
  1069. (define (dynamic-parse-action-null-formal)
  1070. ;; dynamic-parse-action for null-list of formals
  1071. (ast-gen null-def '()))
  1072. (define (dynamic-parse-action-pair-formal d1 d2)
  1073. ;; dynamic-parse-action for non-null list of formals;
  1074. ;; d1 is the result of parsing the first formal,
  1075. ;; d2 the result of parsing the remaining formals
  1076. (ast-gen pair-def (cons d1 d2)))
  1077. (define (dynamic-parse-action-variable e)
  1078. ;; dynamic-parse-action for applied occurrences of variables
  1079. ;; ***Note***: e is the result of a dynamic-parse-action on the
  1080. ;; corresponding variable definition!
  1081. (ast-gen variable e))
  1082. (define (dynamic-parse-action-identifier e)
  1083. ;; dynamic-parse-action for undeclared identifiers (free variable
  1084. ;; occurrences)
  1085. ;; ***Note***: e is a symbol (legal identifier)
  1086. (ast-gen identifier e))
  1087. (define (dynamic-parse-action-null-arg)
  1088. ;; dynamic-parse-action for a null list of arguments in a procedure call
  1089. (ast-gen null-arg '()))
  1090. (define (dynamic-parse-action-pair-arg a1 a2)
  1091. ;; dynamic-parse-action for a non-null list of arguments in a procedure call
  1092. ;; a1 is the result of parsing the first argument,
  1093. ;; a2 the result of parsing the remaining arguments
  1094. (ast-gen pair-arg (cons a1 a2)))
  1095. (define (dynamic-parse-action-procedure-call op args)
  1096. ;; dynamic-parse-action for procedure calls: op function, args list of arguments
  1097. (ast-gen procedure-call (cons op args)))
  1098. (define (dynamic-parse-action-lambda-expression formals body)
  1099. ;; dynamic-parse-action for lambda-abstractions
  1100. (ast-gen lambda-expression (cons formals body)))
  1101. (define (dynamic-parse-action-conditional test then-branch else-branch)
  1102. ;; dynamic-parse-action for conditionals (if-then-else expressions)
  1103. (ast-gen conditional (cons test (cons then-branch else-branch))))
  1104. (define (dynamic-parse-action-empty)
  1105. ;; dynamic-parse-action for missing or empty field
  1106. (ast-gen empty '()))
  1107. (define (dynamic-parse-action-assignment lhs rhs)
  1108. ;; dynamic-parse-action for assignment
  1109. (ast-gen assignment (cons lhs rhs)))
  1110. (define (dynamic-parse-action-begin-expression body)
  1111. ;; dynamic-parse-action for begin-expression
  1112. (ast-gen begin-expression body))
  1113. (define (dynamic-parse-action-cond-expression clauses)
  1114. ;; dynamic-parse-action for cond-expressions
  1115. (ast-gen cond-expression clauses))
  1116. (define (dynamic-parse-action-and-expression args)
  1117. ;; dynamic-parse-action for and-expressions
  1118. (ast-gen and-expression args))
  1119. (define (dynamic-parse-action-or-expression args)
  1120. ;; dynamic-parse-action for or-expressions
  1121. (ast-gen or-expression args))
  1122. (define (dynamic-parse-action-case-expression key clauses)
  1123. ;; dynamic-parse-action for case-expressions
  1124. (ast-gen case-expression (cons key clauses)))
  1125. (define (dynamic-parse-action-let-expression bindings body)
  1126. ;; dynamic-parse-action for let-expressions
  1127. (ast-gen let-expression (cons bindings body)))
  1128. (define (dynamic-parse-action-named-let-expression variable bindings body)
  1129. ;; dynamic-parse-action for named-let expressions
  1130. (ast-gen named-let-expression (cons variable (cons bindings body))))
  1131. (define (dynamic-parse-action-let*-expression bindings body)
  1132. ;; dynamic-parse-action for let-expressions
  1133. (ast-gen let*-expression (cons bindings body)))
  1134. (define (dynamic-parse-action-letrec-expression bindings body)
  1135. ;; dynamic-parse-action for let-expressions
  1136. (ast-gen letrec-expression (cons bindings body)))
  1137. (define (dynamic-parse-action-definition variable expr)
  1138. ;; dynamic-parse-action for simple definitions
  1139. (ast-gen definition (cons variable expr)))
  1140. (define (dynamic-parse-action-function-definition variable formals body)
  1141. ;; dynamic-parse-action for function definitions
  1142. (ast-gen function-definition (cons variable (cons formals body))))
  1143. (define dynamic-parse-action-commands (lambda (a b) (cons a b)))
  1144. ;; dynamic-parse-action for processing a command result followed by a the
  1145. ;; result of processing the remaining commands
  1146. ;; Pretty-printing abstract syntax trees
  1147. (define (ast-show ast)
  1148. ;; converts abstract syntax tree to list representation (Scheme program)
  1149. ;; ***Note***: check translation of constructors to numbers at the top of the file
  1150. (let ((syntax-op (ast-con ast))
  1151. (syntax-arg (ast-arg ast)))
  1152. (case syntax-op
  1153. ((0 1 2 3 4 8 10) syntax-arg)
  1154. ((29 31) '())
  1155. ((30 32) (cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg))))
  1156. ((5) (list 'quote syntax-arg))
  1157. ((6) (list->vector (map ast-show syntax-arg)))
  1158. ((7) (list 'cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg))))
  1159. ((9) (ast-arg syntax-arg))
  1160. ((11) (cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg))))
  1161. ((12) (cons 'lambda (cons (ast-show (car syntax-arg))
  1162. (map ast-show (cdr syntax-arg)))))
  1163. ((13) (cons 'if (cons (ast-show (car syntax-arg))
  1164. (cons (ast-show (cadr syntax-arg))
  1165. (let ((alt (cddr syntax-arg)))
  1166. (if (eqv? (ast-con alt) empty)
  1167. '()
  1168. (list (ast-show alt))))))))
  1169. ((14) (list 'set! (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg))))
  1170. ((15) (cons 'cond
  1171. (map (lambda (cc)
  1172. (let ((guard (car cc))
  1173. (body (cdr cc)))
  1174. (cons
  1175. (if (eqv? (ast-con guard) empty)
  1176. 'else
  1177. (ast-show guard))
  1178. (map ast-show body))))
  1179. syntax-arg)))
  1180. ((16) (cons 'case
  1181. (cons (ast-show (car syntax-arg))
  1182. (map (lambda (cc)
  1183. (let ((data (car cc)))
  1184. (if (and (pair? data)
  1185. (eqv? (ast-con (car data)) empty))
  1186. (cons 'else
  1187. (map ast-show (cdr cc)))
  1188. (cons (map datum-show data)
  1189. (map ast-show (cdr cc))))))
  1190. (cdr syntax-arg)))))
  1191. ((17) (cons 'and (map ast-show syntax-arg)))
  1192. ((18) (cons 'or (map ast-show syntax-arg)))
  1193. ((19) (cons 'let
  1194. (cons (map
  1195. (lambda (vd e)
  1196. (list (ast-show vd) (ast-show e)))
  1197. (caar syntax-arg)
  1198. (cdar syntax-arg))
  1199. (map ast-show (cdr syntax-arg)))))
  1200. ((20) (cons 'let
  1201. (cons (ast-show (car syntax-arg))
  1202. (cons (map
  1203. (lambda (vd e)
  1204. (list (ast-show vd) (ast-show e)))
  1205. (caadr syntax-arg)
  1206. (cdadr syntax-arg))
  1207. (map ast-show (cddr syntax-arg))))))
  1208. ((21) (cons 'let*
  1209. (cons (map
  1210. (lambda (vd e)
  1211. (list (ast-show vd) (ast-show e)))
  1212. (caar syntax-arg)
  1213. (cdar syntax-arg))
  1214. (map ast-show (cdr syntax-arg)))))
  1215. ((22) (cons 'letrec
  1216. (cons (map
  1217. (lambda (vd e)
  1218. (list (ast-show vd) (ast-show e)))
  1219. (caar syntax-arg)
  1220. (cdar syntax-arg))
  1221. (map ast-show (cdr syntax-arg)))))
  1222. ((23) (cons 'begin
  1223. (map ast-show syntax-arg)))
  1224. ((24) (error 'ast-show "Do expressions not handled! (~s)" syntax-arg))
  1225. ((25) (error 'ast-show "This can't happen: empty encountered!"))
  1226. ((26) (list 'define
  1227. (ast-show (car syntax-arg))
  1228. (ast-show (cdr syntax-arg))))
  1229. ((27) (cons 'define
  1230. (cons
  1231. (cons (ast-show (car syntax-arg))
  1232. (ast-show (cadr syntax-arg)))
  1233. (map ast-show (cddr syntax-arg)))))
  1234. ((28) (cons 'begin
  1235. (map ast-show syntax-arg)))
  1236. (else (error 'ast-show "Unknown abstract syntax operator: ~s"
  1237. syntax-op)))))
  1238. ;; ast*-show
  1239. (define (ast*-show p)
  1240. ;; shows a list of abstract syntax trees
  1241. (map ast-show p))
  1242. ;; datum-show
  1243. (define (datum-show ast)
  1244. ;; prints an abstract syntax tree as a datum
  1245. (case (ast-con ast)
  1246. ((0 1 2 3 4 5) (ast-arg ast))
  1247. ((6) (list->vector (map datum-show (ast-arg ast))))
  1248. ((7) (cons (datum-show (car (ast-arg ast))) (datum-show (cdr (ast-arg ast)))))
  1249. (else (error 'datum-show "This should not happen!"))))
  1250. ; write-to-port
  1251. (define (write-to-port prog port)
  1252. ; writes a program to a port
  1253. (for-each
  1254. (lambda (command)
  1255. (pretty-print command port)
  1256. (newline port))
  1257. prog)
  1258. '())
  1259. ; write-file
  1260. (define (write-to-file prog filename)
  1261. ; write a program to a file
  1262. (let ((port (open-output-file filename)))
  1263. (write-to-port prog port)
  1264. (close-output-port port)
  1265. '()))
  1266. ; ----------------------------------------------------------------------------
  1267. ; Typed abstract syntax tree management: constraint generation, display, etc.
  1268. ; ----------------------------------------------------------------------------
  1269. ;; Abstract syntax operations, incl. constraint generation
  1270. (define (ast-gen syntax-op arg)
  1271. ; generates all attributes and performs semantic side effects
  1272. (let ((ntvar
  1273. (case syntax-op
  1274. ((0 29 31) (null))
  1275. ((1) (boolean))
  1276. ((2) (character))
  1277. ((3) (number))
  1278. ((4) (charseq))
  1279. ((5) (symbol))
  1280. ((6) (let ((aux-tvar (gen-tvar)))
  1281. (for-each (lambda (t)
  1282. (add-constr! t aux-tvar))
  1283. (map ast-tvar arg))
  1284. (array aux-tvar)))
  1285. ((7 30 32) (let ((t1 (ast-tvar (car arg)))
  1286. (t2 (ast-tvar (cdr arg))))
  1287. (pair t1 t2)))
  1288. ((8) (gen-tvar))
  1289. ((9) (ast-tvar arg))
  1290. ((10) (let ((in-env (dynamic-lookup arg dynamic-top-level-env)))
  1291. (if in-env
  1292. (instantiate-type (binding-value in-env))
  1293. (let ((new-tvar (gen-tvar)))
  1294. (set! dynamic-top-level-env (extend-env-with-binding
  1295. dynamic-top-level-env
  1296. (gen-binding arg new-tvar)))
  1297. new-tvar))))
  1298. ((11) (let ((new-tvar (gen-tvar)))
  1299. (add-constr! (procedure (ast-tvar (cdr arg)) new-tvar)
  1300. (ast-tvar (car arg)))
  1301. new-tvar))
  1302. ((12) (procedure (ast-tvar (car arg))
  1303. (ast-tvar (tail (cdr arg)))))
  1304. ((13) (let ((t-test (ast-tvar (car arg)))
  1305. (t-consequent (ast-tvar (cadr arg)))
  1306. (t-alternate (ast-tvar (cddr arg))))
  1307. (add-constr! (boolean) t-test)
  1308. (add-constr! t-consequent t-alternate)
  1309. t-consequent))
  1310. ((14) (let ((var-tvar (ast-tvar (car arg)))
  1311. (exp-tvar (ast-tvar (cdr arg))))
  1312. (add-constr! var-tvar exp-tvar)
  1313. var-tvar))
  1314. ((15) (let ((new-tvar (gen-tvar)))
  1315. (for-each (lambda (body)
  1316. (add-constr! (ast-tvar (tail body)) new-tvar))
  1317. (map cdr arg))
  1318. (for-each (lambda (e)
  1319. (add-constr! (boolean) (ast-tvar e)))
  1320. (map car arg))
  1321. new-tvar))
  1322. ((16) (let* ((new-tvar (gen-tvar))
  1323. (t-key (ast-tvar (car arg)))
  1324. (case-clauses (cdr arg)))
  1325. (for-each (lambda (exprs)
  1326. (for-each (lambda (e)
  1327. (add-constr! (ast-tvar e) t-key))
  1328. exprs))
  1329. (map car case-clauses))
  1330. (for-each (lambda (body)
  1331. (add-constr! (ast-tvar (tail body)) new-tvar))
  1332. (map cdr case-clauses))
  1333. new-tvar))
  1334. ((17 18) (for-each (lambda (e)
  1335. (add-constr! (boolean) (ast-tvar e)))
  1336. arg)
  1337. (boolean))
  1338. ((19 21 22) (let ((var-def-tvars (map ast-tvar (caar arg)))
  1339. (def-expr-types (map ast-tvar (cdar arg)))
  1340. (body-type (ast-tvar (tail (cdr arg)))))
  1341. (for-each add-constr! var-def-tvars def-expr-types)
  1342. body-type))
  1343. ((20) (let ((var-def-tvars (map ast-tvar (caadr arg)))
  1344. (def-expr-types (map ast-tvar (cdadr arg)))
  1345. (body-type (ast-tvar (tail (cddr arg))))
  1346. (named-var-type (ast-tvar (car arg))))
  1347. (for-each add-constr! var-def-tvars def-expr-types)
  1348. (add-constr! (procedure (convert-tvars var-def-tvars) body-type)
  1349. named-var-type)
  1350. body-type))
  1351. ((23) (ast-tvar (tail arg)))
  1352. ((24) (error 'ast-gen
  1353. "Do-expressions not handled! (Argument: ~s) arg"))
  1354. ((25) (gen-tvar))
  1355. ((26) (let ((t-var (ast-tvar (car arg)))
  1356. (t-exp (ast-tvar (cdr arg))))
  1357. (add-constr! t-var t-exp)
  1358. t-var))
  1359. ((27) (let ((t-var (ast-tvar (car arg)))
  1360. (t-formals (ast-tvar (cadr arg)))
  1361. (t-body (ast-tvar (tail (cddr arg)))))
  1362. (add-constr! (procedure t-formals t-body) t-var)
  1363. t-var))
  1364. ((28) (gen-tvar))
  1365. (else (error 'ast-gen "Can't handle syntax operator: ~s" syntax-op)))))
  1366. (cons syntax-op (cons ntvar arg))))
  1367. (define ast-con car)
  1368. ;; extracts the ast-constructor from an abstract syntax tree
  1369. (define ast-arg cddr)
  1370. ;; extracts the ast-argument from an abstract syntax tree
  1371. (define ast-tvar cadr)
  1372. ;; extracts the tvar from an abstract syntax tree
  1373. ;; tail
  1374. (define (tail l)
  1375. ;; returns the tail of a nonempty list
  1376. (if (null? (cdr l))
  1377. (car l)
  1378. (tail (cdr l))))
  1379. ; convert-tvars
  1380. (define (convert-tvars tvar-list)
  1381. ;; converts a list of tvars to a single tvar
  1382. (cond
  1383. ((null? tvar-list) (null))
  1384. ((pair? tvar-list) (pair (car tvar-list)
  1385. (convert-tvars (cdr tvar-list))))
  1386. (else (error 'convert-tvars "Not a list of tvars: ~s" tvar-list))))
  1387. ;; Pretty-printing abstract syntax trees
  1388. (define (tast-show ast)
  1389. ;; converts abstract syntax tree to list representation (Scheme program)
  1390. (let ((syntax-op (ast-con ast))
  1391. (syntax-tvar (tvar-show (ast-tvar ast)))
  1392. (syntax-arg (ast-arg ast)))
  1393. (cons
  1394. (case syntax-op
  1395. ((0 1 2 3 4 8 10) syntax-arg)
  1396. ((29 31) '())
  1397. ((30 32) (cons (tast-show (car syntax-arg))
  1398. (tast-show (cdr syntax-arg))))
  1399. ((5) (list 'quote syntax-arg))
  1400. ((6) (list->vector (map tast-show syntax-arg)))
  1401. ((7) (list 'cons (tast-show (car syntax-arg))
  1402. (tast-show (cdr syntax-arg))))
  1403. ((9) (ast-arg syntax-arg))
  1404. ((11) (cons (tast-show (car syntax-arg)) (tast-show (cdr syntax-arg))))
  1405. ((12) (cons 'lambda (cons (tast-show (car syntax-arg))
  1406. (map tast-show (cdr syntax-arg)))))
  1407. ((13) (cons 'if (cons (tast-show (car syntax-arg))
  1408. (cons (tast-show (cadr syntax-arg))
  1409. (let ((alt (cddr syntax-arg)))
  1410. (if (eqv? (ast-con alt) empty)
  1411. '()
  1412. (list (tast-show alt))))))))
  1413. ((14) (list 'set! (tast-show (car syntax-arg))
  1414. (tast-show (cdr syntax-arg))))
  1415. ((15) (cons 'cond
  1416. (map (lambda (cc)
  1417. (let ((guard (car cc))
  1418. (body (cdr cc)))
  1419. (cons
  1420. (if (eqv? (ast-con guard) empty)
  1421. 'else
  1422. (tast-show guard))
  1423. (map tast-show body))))
  1424. syntax-arg)))
  1425. ((16) (cons 'case
  1426. (cons (tast-show (car syntax-arg))
  1427. (map (lambda (cc)
  1428. (let ((data (car cc)))
  1429. (if (and (pair? data)
  1430. (eqv? (ast-con (car data)) empty))
  1431. (cons 'else
  1432. (map tast-show (cdr cc)))
  1433. (cons (map datum-show data)
  1434. (map tast-show (cdr cc))))))
  1435. (cdr syntax-arg)))))
  1436. ((17) (cons 'and (map tast-show syntax-arg)))
  1437. ((18) (cons 'or (map tast-show syntax-arg)))
  1438. ((19) (cons 'let
  1439. (cons (map
  1440. (lambda (vd e)
  1441. (list (tast-show vd) (tast-show e)))
  1442. (caar syntax-arg)
  1443. (cdar syntax-arg))
  1444. (map tast-show (cdr syntax-arg)))))
  1445. ((20) (cons 'let
  1446. (cons (tast-show (car syntax-arg))
  1447. (cons (map
  1448. (lambda (vd e)
  1449. (list (tast-show vd) (tast-show e)))
  1450. (caadr syntax-arg)
  1451. (cdadr syntax-arg))
  1452. (map tast-show (cddr syntax-arg))))))
  1453. ((21) (cons 'let*
  1454. (cons (map
  1455. (lambda (vd e)
  1456. (list (tast-show vd) (tast-show e)))
  1457. (caar syntax-arg)
  1458. (cdar syntax-arg))
  1459. (map tast-show (cdr syntax-arg)))))
  1460. ((22) (cons 'letrec
  1461. (cons (map
  1462. (lambda (vd e)
  1463. (list (tast-show vd) (tast-show e)))
  1464. (caar syntax-arg)
  1465. (cdar syntax-arg))
  1466. (map tast-show (cdr syntax-arg)))))
  1467. ((23) (cons 'begin
  1468. (map tast-show syntax-arg)))
  1469. ((24) (error 'tast-show "Do expressions not handled! (~s)" syntax-arg))
  1470. ((25) (error 'tast-show "This can't happen: empty encountered!"))
  1471. ((26) (list 'define
  1472. (tast-show (car syntax-arg))
  1473. (tast-show (cdr syntax-arg))))
  1474. ((27) (cons 'define
  1475. (cons
  1476. (cons (tast-show (car syntax-arg))
  1477. (tast-show (cadr syntax-arg)))
  1478. (map tast-show (cddr syntax-arg)))))
  1479. ((28) (cons 'begin
  1480. (map tast-show syntax-arg)))
  1481. (else (error 'tast-show "Unknown abstract syntax operator: ~s"
  1482. syntax-op)))
  1483. syntax-tvar)))
  1484. ;; tast*-show
  1485. (define (tast*-show p)
  1486. ;; shows a list of abstract syntax trees
  1487. (map tast-show p))
  1488. ;; counters for tagging/untagging
  1489. (define untag-counter 0)
  1490. (define no-untag-counter 0)
  1491. (define tag-counter 0)
  1492. (define no-tag-counter 0)
  1493. (define may-untag-counter 0)
  1494. (define no-may-untag-counter 0)
  1495. (define (reset-counters!)
  1496. (set! untag-counter 0)
  1497. (set! no-untag-counter 0)
  1498. (set! tag-counter 0)
  1499. (set! no-tag-counter 0)
  1500. (set! may-untag-counter 0)
  1501. (set! no-may-untag-counter 0))
  1502. (define (counters-show)
  1503. (list
  1504. (cons tag-counter no-tag-counter)
  1505. (cons untag-counter no-untag-counter)
  1506. (cons may-untag-counter no-may-untag-counter)))
  1507. ;; tag-show
  1508. (define (tag-show tvar-rep prog)
  1509. ; display prog with tagging operation
  1510. (if (eqv? tvar-rep dynamic)
  1511. (begin
  1512. (set! tag-counter (+ tag-counter 1))
  1513. (list 'tag prog))
  1514. (begin
  1515. (set! no-tag-counter (+ no-tag-counter 1))
  1516. (list 'no-tag prog))))
  1517. ;; untag-show
  1518. (define (untag-show tvar-rep prog)
  1519. ; display prog with untagging operation
  1520. (if (eqv? tvar-rep dynamic)
  1521. (begin
  1522. (set! untag-counter (+ untag-counter 1))
  1523. (list 'untag prog))
  1524. (begin
  1525. (set! no-untag-counter (+ no-untag-counter 1))
  1526. (list 'no-untag prog))))
  1527. (define (may-untag-show tvar-rep prog)
  1528. ; display possible untagging in actual arguments
  1529. (if (eqv? tvar-rep dynamic)
  1530. (begin
  1531. (set! may-untag-counter (+ may-untag-counter 1))
  1532. (list 'may-untag prog))
  1533. (begin
  1534. (set! no-may-untag-counter (+ no-may-untag-counter 1))
  1535. (list 'no-may-untag prog))))
  1536. ;; tag-ast-show
  1537. (define (tag-ast-show ast)
  1538. ;; converts typed and normalized abstract syntax tree to
  1539. ;; a Scheme program with explicit tagging and untagging operations
  1540. (let ((syntax-op (ast-con ast))
  1541. (syntax-tvar (find! (ast-tvar ast)))
  1542. (syntax-arg (ast-arg ast)))
  1543. (case syntax-op
  1544. ((0 1 2 3 4)
  1545. (tag-show syntax-tvar syntax-arg))
  1546. ((8 10) syntax-arg)
  1547. ((29 31) '())
  1548. ((30) (cons (tag-ast-show (car syntax-arg))
  1549. (tag-ast-show (cdr syntax-arg))))
  1550. ((32) (cons (may-untag-show (find! (ast-tvar (car syntax-arg)))
  1551. (tag-ast-show (car syntax-arg)))
  1552. (tag-ast-show (cdr syntax-arg))))
  1553. ((5) (tag-show syntax-tvar (list 'quote syntax-arg)))
  1554. ((6) (tag-show syntax-tvar (list->vector (map tag-ast-show syntax-arg))))
  1555. ((7) (tag-show syntax-tvar (list 'cons (tag-ast-show (car syntax-arg))
  1556. (tag-ast-show (cdr syntax-arg)))))
  1557. ((9) (ast-arg syntax-arg))
  1558. ((11) (let ((proc-tvar (find! (ast-tvar (car syntax-arg)))))
  1559. (cons (untag-show proc-tvar
  1560. (tag-ast-show (car syntax-arg)))
  1561. (tag-ast-show (cdr syntax-arg)))))
  1562. ((12) (tag-show syntax-tvar
  1563. (cons 'lambda (cons (tag-ast-show (car syntax-arg))
  1564. (map tag-ast-show (cdr syntax-arg))))))
  1565. ((13) (let ((test-tvar (find! (ast-tvar (car syntax-arg)))))
  1566. (cons 'if (cons (untag-show test-tvar
  1567. (tag-ast-show (car syntax-arg)))
  1568. (cons (tag-ast-show (cadr syntax-arg))
  1569. (let ((alt (cddr syntax-arg)))
  1570. (if (eqv? (ast-con alt) empty)
  1571. '()
  1572. (list (tag-ast-show alt)))))))))
  1573. ((14) (list 'set! (tag-ast-show (car syntax-arg))
  1574. (tag-ast-show (cdr syntax-arg))))
  1575. ((15) (cons 'cond
  1576. (map (lambda (cc)
  1577. (let ((guard (car cc))
  1578. (body (cdr cc)))
  1579. (cons
  1580. (if (eqv? (ast-con guard) empty)
  1581. 'else
  1582. (untag-show (find! (ast-tvar guard))
  1583. (tag-ast-show guard)))
  1584. (map tag-ast-show body))))
  1585. syntax-arg)))
  1586. ((16) (cons 'case
  1587. (cons (tag-ast-show (car syntax-arg))
  1588. (map (lambda (cc)
  1589. (let ((data (car cc)))
  1590. (if (and (pair? data)
  1591. (eqv? (ast-con (car data)) empty))
  1592. (cons 'else
  1593. (map tag-ast-show (cdr cc)))
  1594. (cons (map datum-show data)
  1595. (map tag-ast-show (cdr cc))))))
  1596. (cdr syntax-arg)))))
  1597. ((17) (cons 'and (map
  1598. (lambda (ast)
  1599. (let ((bool-tvar (find! (ast-tvar ast))))
  1600. (untag-show bool-tvar (tag-ast-show ast))))
  1601. syntax-arg)))
  1602. ((18) (cons 'or (map
  1603. (lambda (ast)
  1604. (let ((bool-tvar (find! (ast-tvar ast))))
  1605. (untag-show bool-tvar (tag-ast-show ast))))
  1606. syntax-arg)))
  1607. ((19) (cons 'let
  1608. (cons (map
  1609. (lambda (vd e)
  1610. (list (tag-ast-show vd) (tag-ast-show e)))
  1611. (caar syntax-arg)
  1612. (cdar syntax-arg))
  1613. (map tag-ast-show (cdr syntax-arg)))))
  1614. ((20) (cons 'let
  1615. (cons (tag-ast-show (car syntax-arg))
  1616. (cons (map
  1617. (lambda (vd e)
  1618. (list (tag-ast-show vd) (tag-ast-show e)))
  1619. (caadr syntax-arg)
  1620. (cdadr syntax-arg))
  1621. (map tag-ast-show (cddr syntax-arg))))))
  1622. ((21) (cons 'let*
  1623. (cons (map
  1624. (lambda (vd e)
  1625. (list (tag-ast-show vd) (tag-ast-show e)))
  1626. (caar syntax-arg)
  1627. (cdar syntax-arg))
  1628. (map tag-ast-show (cdr syntax-arg)))))
  1629. ((22) (cons 'letrec
  1630. (cons (map
  1631. (lambda (vd e)
  1632. (list (tag-ast-show vd) (tag-ast-show e)))
  1633. (caar syntax-arg)
  1634. (cdar syntax-arg))
  1635. (map tag-ast-show (cdr syntax-arg)))))
  1636. ((23) (cons 'begin
  1637. (map tag-ast-show syntax-arg)))
  1638. ((24) (error 'tag-ast-show "Do expressions not handled! (~s)" syntax-arg))
  1639. ((25) (error 'tag-ast-show "This can't happen: empty encountered!"))
  1640. ((26) (list 'define
  1641. (tag-ast-show (car syntax-arg))
  1642. (tag-ast-show (cdr syntax-arg))))
  1643. ((27) (let ((func-tvar (find! (ast-tvar (car syntax-arg)))))
  1644. (list 'define
  1645. (tag-ast-show (car syntax-arg))
  1646. (tag-show func-tvar
  1647. (cons 'lambda
  1648. (cons (tag-ast-show (cadr syntax-arg))
  1649. (map tag-ast-show (cddr syntax-arg))))))))
  1650. ((28) (cons 'begin
  1651. (map tag-ast-show syntax-arg)))
  1652. (else (error 'tag-ast-show "Unknown abstract syntax operator: ~s"
  1653. syntax-op)))))
  1654. ; tag-ast*-show
  1655. (define (tag-ast*-show p)
  1656. ; display list of commands/expressions with tagging/untagging
  1657. ; operations
  1658. (map tag-ast-show p))
  1659. ; ----------------------------------------------------------------------------
  1660. ; Top level type environment
  1661. ; ----------------------------------------------------------------------------
  1662. ; Needed packages: type management (monomorphic and polymorphic)
  1663. ;(load "typ-mgmt.ss")
  1664. ;(load "ptyp-mgm.ss")
  1665. ; type environment for miscellaneous
  1666. (define misc-env
  1667. (list
  1668. (cons 'quote (forall (lambda (tv) tv)))
  1669. (cons 'eqv? (forall (lambda (tv) (procedure (convert-tvars (list tv tv))
  1670. (boolean)))))
  1671. (cons 'eq? (forall (lambda (tv) (procedure (convert-tvars (list tv tv))
  1672. (boolean)))))
  1673. (cons 'equal? (forall (lambda (tv) (procedure (convert-tvars (list tv tv))
  1674. (boolean)))))
  1675. ))
  1676. ; type environment for input/output
  1677. (define io-env
  1678. (list
  1679. (cons 'open-input-file (procedure (convert-tvars (list (charseq))) dynamic))
  1680. (cons 'eof-object? (procedure (convert-tvars (list dynamic)) (boolean)))
  1681. (cons 'read (forall (lambda (tv)
  1682. (procedure (convert-tvars (list tv)) dynamic))))
  1683. (cons 'write (forall (lambda (tv)
  1684. (procedure (convert-tvars (list tv)) dynamic))))
  1685. (cons 'display (forall (lambda (tv)
  1686. (procedure (convert-tvars (list tv)) dynamic))))
  1687. (cons 'newline (procedure (null) dynamic))
  1688. (cons 'pretty-print (forall (lambda (tv)
  1689. (procedure (convert-tvars (list tv)) dynamic))))))
  1690. ; type environment for Booleans
  1691. (define boolean-env
  1692. (list
  1693. (cons 'boolean? (forall (lambda (tv)
  1694. (procedure (convert-tvars (list tv)) (boolean)))))
  1695. ;(cons #f (boolean))
  1696. ; #f doesn't exist in Chez Scheme, but gets mapped to null!
  1697. (cons #t (boolean))
  1698. (cons 'not (procedure (convert-tvars (list (boolean))) (boolean)))
  1699. ))
  1700. ; type environment for pairs and lists
  1701. (define (list-type tv)
  1702. (fix (lambda (tv2) (pair tv tv2))))
  1703. (define list-env
  1704. (list
  1705. (cons 'pair? (forall2 (lambda (tv1 tv2)
  1706. (procedure (convert-tvars (list (pair tv1 tv2)))
  1707. (boolean)))))
  1708. (cons 'null? (forall2 (lambda (tv1 tv2)
  1709. (procedure (convert-tvars (list (pair tv1 tv2)))
  1710. (boolean)))))
  1711. (cons 'list? (forall2 (lambda (tv1 tv2)
  1712. (procedure (convert-tvars (list (pair tv1 tv2)))
  1713. (boolean)))))
  1714. (cons 'cons (forall2 (lambda (tv1 tv2)
  1715. (procedure (convert-tvars (list tv1 tv2))
  1716. (pair tv1 tv2)))))
  1717. (cons 'car (forall2 (lambda (tv1 tv2)
  1718. (procedure (convert-tvars (list (pair tv1 tv2)))
  1719. tv1))))
  1720. (cons 'cdr (forall2 (lambda (tv1 tv2)
  1721. (procedure (convert-tvars (list (pair tv1 tv2)))
  1722. tv2))))
  1723. (cons 'set-car! (forall2 (lambda (tv1 tv2)
  1724. (procedure (convert-tvars (list (pair tv1 tv2)
  1725. tv1))
  1726. dynamic))))
  1727. (cons 'set-cdr! (forall2 (lambda (tv1 tv2)
  1728. (procedure (convert-tvars (list (pair tv1 tv2)
  1729. tv2))
  1730. dynamic))))
  1731. (cons 'caar (forall3 (lambda (tv1 tv2 tv3)
  1732. (procedure (convert-tvars
  1733. (list (pair (pair tv1 tv2) tv3)))
  1734. tv1))))
  1735. (cons 'cdar (forall3 (lambda (tv1 tv2 tv3)
  1736. (procedure (convert-tvars
  1737. (list (pair (pair tv1 tv2) tv3)))
  1738. tv2))))
  1739. (cons 'cadr (forall3 (lambda (tv1 tv2 tv3)
  1740. (procedure (convert-tvars
  1741. (list (pair tv1 (pair tv2 tv3))))
  1742. tv2))))
  1743. (cons 'cddr (forall3 (lambda (tv1 tv2 tv3)
  1744. (procedure (convert-tvars
  1745. (list (pair tv1 (pair tv2 tv3))))
  1746. tv3))))
  1747. (cons 'caaar (forall4
  1748. (lambda (tv1 tv2 tv3 tv4)
  1749. (procedure (convert-tvars
  1750. (list (pair (pair (pair tv1 tv2) tv3) tv4)))
  1751. tv1))))
  1752. (cons 'cdaar (forall4
  1753. (lambda (tv1 tv2 tv3 tv4)
  1754. (procedure (convert-tvars
  1755. (list (pair (pair (pair tv1 tv2) tv3) tv4)))
  1756. tv2))))
  1757. (cons 'cadar (forall4
  1758. (lambda (tv1 tv2 tv3 tv4)
  1759. (procedure (convert-tvars
  1760. (list (pair (pair tv1 (pair tv2 tv3)) tv4)))
  1761. tv2))))
  1762. (cons 'cddar (forall4
  1763. (lambda (tv1 tv2 tv3 tv4)
  1764. (procedure (convert-tvars
  1765. (list (pair (pair tv1 (pair tv2 tv3)) tv4)))
  1766. tv3))))
  1767. (cons 'caadr (forall4
  1768. (lambda (tv1 tv2 tv3 tv4)
  1769. (procedure (convert-tvars
  1770. (list (pair tv1 (pair (pair tv2 tv3) tv4))))
  1771. tv2))))
  1772. (cons 'cdadr (forall4
  1773. (lambda (tv1 tv2 tv3 tv4)
  1774. (procedure (convert-tvars
  1775. (list (pair tv1 (pair (pair tv2 tv3) tv4))))
  1776. tv3))))
  1777. (cons 'caddr (forall4
  1778. (lambda (tv1 tv2 tv3 tv4)
  1779. (procedure (convert-tvars
  1780. (list (pair tv1 (pair tv2 (pair tv3 tv4)))))
  1781. tv3))))
  1782. (cons 'cdddr (forall4
  1783. (lambda (tv1 tv2 tv3 tv4)
  1784. (procedure (convert-tvars
  1785. (list (pair tv1 (pair tv2 (pair tv3 tv4)))))
  1786. tv4))))
  1787. (cons 'cadddr
  1788. (forall5 (lambda (tv1 tv2 tv3 tv4 tv5)
  1789. (procedure (convert-tvars
  1790. (list (pair tv1
  1791. (pair tv2
  1792. (pair tv3
  1793. (pair tv4 tv5))))))
  1794. tv4))))
  1795. (cons 'cddddr
  1796. (forall5 (lambda (tv1 tv2 tv3 tv4 tv5)
  1797. (procedure (convert-tvars
  1798. (list (pair tv1
  1799. (pair tv2
  1800. (pair tv3
  1801. (pair tv4 tv5))))))
  1802. tv5))))
  1803. (cons 'list (forall (lambda (tv)
  1804. (procedure tv tv))))
  1805. (cons 'length (forall (lambda (tv)
  1806. (procedure (convert-tvars (list (list-type tv)))
  1807. (number)))))
  1808. (cons 'append (forall (lambda (tv)
  1809. (procedure (convert-tvars (list (list-type tv)
  1810. (list-type tv)))
  1811. (list-type tv)))))
  1812. (cons 'reverse (forall (lambda (tv)
  1813. (procedure (convert-tvars (list (list-type tv)))
  1814. (list-type tv)))))
  1815. (cons 'list-ref (forall (lambda (tv)
  1816. (procedure (convert-tvars (list (list-type tv)
  1817. (number)))
  1818. tv))))
  1819. (cons 'memq (forall (lambda (tv)
  1820. (procedure (convert-tvars (list tv
  1821. (list-type tv)))
  1822. (boolean)))))
  1823. (cons 'memv (forall (lambda (tv)
  1824. (procedure (convert-tvars (list tv
  1825. (list-type tv)))
  1826. (boolean)))))
  1827. (cons 'member (forall (lambda (tv)
  1828. (procedure (convert-tvars (list tv
  1829. (list-type tv)))
  1830. (boolean)))))
  1831. (cons 'assq (forall2 (lambda (tv1 tv2)
  1832. (procedure (convert-tvars
  1833. (list tv1
  1834. (list-type (pair tv1 tv2))))
  1835. (pair tv1 tv2)))))
  1836. (cons 'assv (forall2 (lambda (tv1 tv2)
  1837. (procedure (convert-tvars
  1838. (list tv1
  1839. (list-type (pair tv1 tv2))))
  1840. (pair tv1 tv2)))))
  1841. (cons 'assoc (forall2 (lambda (tv1 tv2)
  1842. (procedure (convert-tvars
  1843. (list tv1
  1844. (list-type (pair tv1 tv2))))
  1845. (pair tv1 tv2)))))
  1846. ))
  1847. (define symbol-env
  1848. (list
  1849. (cons 'symbol? (forall (lambda (tv)
  1850. (procedure (convert-tvars (list tv)) (boolean)))))
  1851. (cons 'symbol->string (procedure (convert-tvars (list (symbol))) (charseq)))
  1852. (cons 'string->symbol (procedure (convert-tvars (list (charseq))) (symbol)))
  1853. ))
  1854. (define number-env
  1855. (list
  1856. (cons 'number? (forall (lambda (tv)
  1857. (procedure (convert-tvars (list tv)) (boolean)))))
  1858. (cons '+ (procedure (convert-tvars (list (number) (number))) (number)))
  1859. (cons '- (procedure (convert-tvars (list (number) (number))) (number)))
  1860. (cons '* (procedure (convert-tvars (list (number) (number))) (number)))
  1861. (cons '/ (procedure (convert-tvars (list (number) (number))) (number)))
  1862. (cons 'number->string (procedure (convert-tvars (list (number))) (charseq)))
  1863. (cons 'string->number (procedure (convert-tvars (list (charseq))) (number)))
  1864. ))
  1865. (define char-env
  1866. (list
  1867. (cons 'char? (forall (lambda (tv)
  1868. (procedure (convert-tvars (list tv)) (boolean)))))
  1869. (cons 'char->integer (procedure (convert-tvars (list (character)))
  1870. (number)))
  1871. (cons 'integer->char (procedure (convert-tvars (list (number)))
  1872. (character)))
  1873. ))
  1874. (define string-env
  1875. (list
  1876. (cons 'string? (forall (lambda (tv)
  1877. (procedure (convert-tvars (list tv)) (boolean)))))
  1878. ))
  1879. (define vector-env
  1880. (list
  1881. (cons 'vector? (forall (lambda (tv)
  1882. (procedure (convert-tvars (list tv)) (boolean)))))
  1883. (cons 'make-vector (forall (lambda (tv)
  1884. (procedure (convert-tvars (list (number)))
  1885. (array tv)))))
  1886. (cons 'vector-length (forall (lambda (tv)
  1887. (procedure (convert-tvars (list (array tv)))
  1888. (number)))))
  1889. (cons 'vector-ref (forall (lambda (tv)
  1890. (procedure (convert-tvars (list (array tv)
  1891. (number)))
  1892. tv))))
  1893. (cons 'vector-set! (forall (lambda (tv)
  1894. (procedure (convert-tvars (list (array tv)
  1895. (number)
  1896. tv))
  1897. dynamic))))
  1898. ))
  1899. (define procedure-env
  1900. (list
  1901. (cons 'procedure? (forall (lambda (tv)
  1902. (procedure (convert-tvars (list tv)) (boolean)))))
  1903. (cons 'map (forall2 (lambda (tv1 tv2)
  1904. (procedure (convert-tvars
  1905. (list (procedure (convert-tvars
  1906. (list tv1)) tv2)
  1907. (list-type tv1)))
  1908. (list-type tv2)))))
  1909. (cons 'foreach (forall2 (lambda (tv1 tv2)
  1910. (procedure (convert-tvars
  1911. (list (procedure (convert-tvars
  1912. (list tv1)) tv2)
  1913. (list-type tv1)))
  1914. (list-type tv2)))))
  1915. (cons 'call-with-current-continuation
  1916. (forall2 (lambda (tv1 tv2)
  1917. (procedure (convert-tvars
  1918. (list (procedure
  1919. (convert-tvars
  1920. (list (procedure (convert-tvars
  1921. (list tv1)) tv2)))
  1922. tv2)))
  1923. tv2))))
  1924. ))
  1925. ; global top level environment
  1926. (define (global-env)
  1927. (append misc-env
  1928. io-env
  1929. boolean-env
  1930. symbol-env
  1931. number-env
  1932. char-env
  1933. string-env
  1934. vector-env
  1935. procedure-env
  1936. list-env))
  1937. (define dynamic-top-level-env (global-env))
  1938. (define (init-dynamic-top-level-env!)
  1939. (set! dynamic-top-level-env (global-env))
  1940. '())
  1941. (define (dynamic-top-level-env-show)
  1942. ; displays the top level environment
  1943. (map (lambda (binding)
  1944. (cons (key-show (binding-key binding))
  1945. (cons ': (tvar-show (binding-value binding)))))
  1946. (env->list dynamic-top-level-env)))
  1947. ; ----------------------------------------------------------------------------
  1948. ; Dynamic type inference for Scheme
  1949. ; ----------------------------------------------------------------------------
  1950. ; Needed packages:
  1951. (define (ic!) (init-global-constraints!))
  1952. (define (pc) (glob-constr-show))
  1953. (define (lc) (length global-constraints))
  1954. (define (n!) (normalize-global-constraints!))
  1955. (define (pt) (dynamic-top-level-env-show))
  1956. (define (it!) (init-dynamic-top-level-env!))
  1957. (define (io!) (set! tag-ops 0) (set! no-ops 0))
  1958. (define (i!) (ic!) (it!) (io!) '())
  1959. (define tag-ops 0)
  1960. (define no-ops 0)
  1961. ; This wasn't intended to be an i/o benchmark,
  1962. ; so let's read the file just once.
  1963. (define *forms*
  1964. (call-with-input-file
  1965. "dynamic-input.sch"
  1966. (lambda (port)
  1967. (define (loop forms)
  1968. (let ((form (read port)))
  1969. (if (eof-object? form)
  1970. (reverse forms)
  1971. (loop (cons form forms)))))
  1972. (loop '()))))
  1973. (define (dynamic-parse-forms forms)
  1974. (if (null? forms)
  1975. '()
  1976. (let ((next-input (car forms)))
  1977. (dynamic-parse-action-commands
  1978. (dynamic-parse-command dynamic-empty-env next-input)
  1979. (dynamic-parse-forms (cdr forms))))))
  1980. (define doit
  1981. (lambda ()
  1982. (i!)
  1983. (let ((foo (dynamic-parse-forms *forms*)))
  1984. (normalize-global-constraints!)
  1985. (reset-counters!)
  1986. (tag-ast*-show foo)
  1987. (counters-show))))
  1988. (define (dynamic-benchmark . rest)
  1989. (let ((n (if (null? rest) 1 (car rest))))
  1990. (run-benchmark "dynamic"
  1991. n
  1992. doit
  1993. (lambda (result)
  1994. #t))))
  1995. ; eof