Advertisement
Guest User

Untitled

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