123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349 |
- ; This benchmark was obtained from Andrew Wright,
- ; based on Fritz Henglein's code.
- ; 970215 / wdc Removed most i/o and added dynamic-benchmark.
- ; 990707 / lth Added a quote and changed the call to run-benchmark.
- ; 010404 / wdc Changed the input file path name to "dynamic-input.sch".
- ;; Fritz's dynamic type inferencer, set up to run on itself
- ;; (see the end of this file).
- ;----------------------------------------------------------------------------
- ; Environment management
- ;----------------------------------------------------------------------------
- ;; environments are lists of pairs, the first component being the key
- ;; general environment operations
- ;;
- ;; empty-env: Env
- ;; gen-binding: Key x Value -> Binding
- ;; binding-key: Binding -> Key
- ;; binding-value: Binding -> Value
- ;; binding-show: Binding -> Symbol*
- ;; extend-env-with-binding: Env x Binding -> Env
- ;; extend-env-with-env: Env x Env -> Env
- ;; lookup: Key x Env -> (Binding + False)
- ;; env->list: Env -> Binding*
- ;; env-show: Env -> Symbol*
- ; bindings
- (define gen-binding cons)
- ; generates a type binding, binding a symbol to a type variable
- (define binding-key car)
- ; returns the key of a type binding
- (define binding-value cdr)
- ; returns the tvariable of a type binding
- (define (key-show key)
- ; default show procedure for keys
- key)
- (define (value-show value)
- ; default show procedure for values
- value)
- (define (binding-show binding)
- ; returns a printable representation of a type binding
- (cons (key-show (binding-key binding))
- (cons ': (value-show (binding-value binding)))))
- ; environments
- (define dynamic-empty-env '())
- ; returns the empty environment
- (define (extend-env-with-binding env binding)
- ; extends env with a binding, which hides any other binding in env
- ; for the same key (see dynamic-lookup)
- ; returns the extended environment
- (cons binding env))
- (define (extend-env-with-env env ext-env)
- ; extends environment env with environment ext-env
- ; a binding for a key in ext-env hides any binding in env for
- ; the same key (see dynamic-lookup)
- ; returns the extended environment
- (append ext-env env))
- (define dynamic-lookup (lambda (x l) (assv x l)))
- ; returns the first pair in env that matches the key; returns #f
- ; if no such pair exists
- (define (env->list e)
- ; converts an environment to a list of bindings
- e)
- (define (env-show env)
- ; returns a printable list representation of a type environment
- (map binding-show env))
- ;----------------------------------------------------------------------------
- ; Parsing for Scheme
- ;----------------------------------------------------------------------------
- ;; Needed packages: environment management
- ;(load "env-mgmt.ss")
- ;(load "pars-act.ss")
- ;; Lexical notions
- (define syntactic-keywords
- ;; source: IEEE Scheme, 7.1, <expression keyword>, <syntactic keyword>
- '(lambda if set! begin cond and or case let let* letrec do
- quasiquote else => define unquote unquote-splicing))
- ;; Parse routines
- ; Datum
- ; dynamic-parse-datum: parses nonterminal <datum>
- (define (dynamic-parse-datum e)
- ;; Source: IEEE Scheme, sect. 7.2, <datum>
- ;; Note: "'" is parsed as 'quote, "`" as 'quasiquote, "," as
- ;; 'unquote, ",@" as 'unquote-splicing (see sect. 4.2.5, p. 18)
- ;; ***Note***: quasi-quotations are not permitted! (It would be
- ;; necessary to pass the environment to dynamic-parse-datum.)
- (cond
- ((null? e)
- (dynamic-parse-action-null-const))
- ((boolean? e)
- (dynamic-parse-action-boolean-const e))
- ((char? e)
- (dynamic-parse-action-char-const e))
- ((number? e)
- (dynamic-parse-action-number-const e))
- ((string? e)
- (dynamic-parse-action-string-const e))
- ((symbol? e)
- (dynamic-parse-action-symbol-const e))
- ((vector? e)
- (dynamic-parse-action-vector-const (map dynamic-parse-datum (vector->list e))))
- ((pair? e)
- (dynamic-parse-action-pair-const (dynamic-parse-datum (car e))
- (dynamic-parse-datum (cdr e))))
- (else (error 'dynamic-parse-datum "Unknown datum: ~s" e))))
- ; VarDef
- ; dynamic-parse-formal: parses nonterminal <variable> in defining occurrence position
- (define (dynamic-parse-formal f-env e)
- ; e is an arbitrary object, f-env is a forbidden environment;
- ; returns: a variable definition (a binding for the symbol), plus
- ; the value of the binding as a result
- (if (symbol? e)
- (cond
- ((memq e syntactic-keywords)
- (error 'dynamic-parse-formal "Illegal identifier (keyword): ~s" e))
- ((dynamic-lookup e f-env)
- (error 'dynamic-parse-formal "Duplicate variable definition: ~s" e))
- (else (let ((dynamic-parse-action-result (dynamic-parse-action-var-def e)))
- (cons (gen-binding e dynamic-parse-action-result)
- dynamic-parse-action-result))))
- (error 'dynamic-parse-formal "Not an identifier: ~s" e)))
- ; dynamic-parse-formal*
- (define (dynamic-parse-formal* formals)
- ;; parses a list of formals and returns a pair consisting of generated
- ;; environment and list of parsing action results
- (letrec
- ((pf*
- (lambda (f-env results formals)
- ;; f-env: "forbidden" environment (to avoid duplicate defs)
- ;; results: the results of the parsing actions
- ;; formals: the unprocessed formals
- ;; Note: generates the results of formals in reverse order!
- (cond
- ((null? formals)
- (cons f-env results))
- ((pair? formals)
- (let* ((fst-formal (car formals))
- (binding-result (dynamic-parse-formal f-env fst-formal))
- (binding (car binding-result))
- (var-result (cdr binding-result)))
- (pf*
- (extend-env-with-binding f-env binding)
- (cons var-result results)
- (cdr formals))))
- (else (error 'dynamic-parse-formal* "Illegal formals: ~s" formals))))))
- (let ((renv-rres (pf* dynamic-empty-env '() formals)))
- (cons (car renv-rres) (reverse (cdr renv-rres))))))
- ; dynamic-parse-formals: parses <formals>
- (define (dynamic-parse-formals formals)
- ;; parses <formals>; see IEEE Scheme, sect. 7.3
- ;; returns a pair: env and result
- (letrec ((pfs (lambda (f-env formals)
- (cond
- ((null? formals)
- (cons dynamic-empty-env (dynamic-parse-action-null-formal)))
- ((pair? formals)
- (let* ((fst-formal (car formals))
- (rem-formals (cdr formals))
- (bind-res (dynamic-parse-formal f-env fst-formal))
- (bind (car bind-res))
- (res (cdr bind-res))
- (nf-env (extend-env-with-binding f-env bind))
- (renv-res* (pfs nf-env rem-formals))
- (renv (car renv-res*))
- (res* (cdr renv-res*)))
- (cons
- (extend-env-with-binding renv bind)
- (dynamic-parse-action-pair-formal res res*))))
- (else
- (let* ((bind-res (dynamic-parse-formal f-env formals))
- (bind (car bind-res))
- (res (cdr bind-res)))
- (cons
- (extend-env-with-binding dynamic-empty-env bind)
- res)))))))
- (pfs dynamic-empty-env formals)))
- ; Expr
- ; dynamic-parse-expression: parses nonterminal <expression>
- (define (dynamic-parse-expression env e)
- (cond
- ((symbol? e)
- (dynamic-parse-variable env e))
- ((pair? e)
- (let ((op (car e)) (args (cdr e)))
- (case op
- ((quote) (dynamic-parse-quote env args))
- ((lambda) (dynamic-parse-lambda env args))
- ((if) (dynamic-parse-if env args))
- ((set!) (dynamic-parse-set env args))
- ((begin) (dynamic-parse-begin env args))
- ((cond) (dynamic-parse-cond env args))
- ((case) (dynamic-parse-case env args))
- ((and) (dynamic-parse-and env args))
- ((or) (dynamic-parse-or env args))
- ((let) (dynamic-parse-let env args))
- ((let*) (dynamic-parse-let* env args))
- ((letrec) (dynamic-parse-letrec env args))
- ((do) (dynamic-parse-do env args))
- ((quasiquote) (dynamic-parse-quasiquote env args))
- (else (dynamic-parse-procedure-call env op args)))))
- (else (dynamic-parse-datum e))))
- ; dynamic-parse-expression*
- (define (dynamic-parse-expression* env exprs)
- ;; Parses lists of expressions (returns them in the right order!)
- (letrec ((pe*
- (lambda (results es)
- (cond
- ((null? es) results)
- ((pair? es) (pe* (cons (dynamic-parse-expression env (car es)) results) (cdr es)))
- (else (error 'dynamic-parse-expression* "Not a list of expressions: ~s" es))))))
- (reverse (pe* '() exprs))))
- ; dynamic-parse-expressions
- (define (dynamic-parse-expressions env exprs)
- ;; parses lists of arguments of a procedure call
- (cond
- ((null? exprs) (dynamic-parse-action-null-arg))
- ((pair? exprs) (let* ((fst-expr (car exprs))
- (rem-exprs (cdr exprs))
- (fst-res (dynamic-parse-expression env fst-expr))
- (rem-res (dynamic-parse-expressions env rem-exprs)))
- (dynamic-parse-action-pair-arg fst-res rem-res)))
- (else (error 'dynamic-parse-expressions "Illegal expression list: ~s"
- exprs))))
- ; dynamic-parse-variable: parses variables (applied occurrences)
- (define (dynamic-parse-variable env e)
- (if (symbol? e)
- (if (memq e syntactic-keywords)
- (error 'dynamic-parse-variable "Illegal identifier (keyword): ~s" e)
- (let ((assoc-var-def (dynamic-lookup e env)))
- (if assoc-var-def
- (dynamic-parse-action-variable (binding-value assoc-var-def))
- (dynamic-parse-action-identifier e))))
- (error 'dynamic-parse-variable "Not an identifier: ~s" e)))
- ; dynamic-parse-procedure-call
- (define (dynamic-parse-procedure-call env op args)
- (dynamic-parse-action-procedure-call
- (dynamic-parse-expression env op)
- (dynamic-parse-expressions env args)))
- ; dynamic-parse-quote
- (define (dynamic-parse-quote env args)
- (if (list-of-1? args)
- (dynamic-parse-datum (car args))
- (error 'dynamic-parse-quote "Not a datum (multiple arguments): ~s" args)))
- ; dynamic-parse-lambda
- (define (dynamic-parse-lambda env args)
- (if (pair? args)
- (let* ((formals (car args))
- (body (cdr args))
- (nenv-fresults (dynamic-parse-formals formals))
- (nenv (car nenv-fresults))
- (fresults (cdr nenv-fresults)))
- (dynamic-parse-action-lambda-expression
- fresults
- (dynamic-parse-body (extend-env-with-env env nenv) body)))
- (error 'dynamic-parse-lambda "Illegal formals/body: ~s" args)))
- ; dynamic-parse-body
- (define (dynamic-parse-body env body)
- ; <body> = <definition>* <expression>+
- (define (def-var* f-env body)
- ; finds the defined variables in a body and returns an
- ; environment containing them
- (if (pair? body)
- (let ((n-env (def-var f-env (car body))))
- (if n-env
- (def-var* n-env (cdr body))
- f-env))
- f-env))
- (define (def-var f-env clause)
- ; finds the defined variables in a single clause and extends
- ; f-env accordingly; returns false if it's not a definition
- (if (pair? clause)
- (case (car clause)
- ((define) (if (pair? (cdr clause))
- (let ((pattern (cadr clause)))
- (cond
- ((symbol? pattern)
- (extend-env-with-binding
- f-env
- (gen-binding pattern
- (dynamic-parse-action-var-def pattern))))
- ((and (pair? pattern) (symbol? (car pattern)))
- (extend-env-with-binding
- f-env
- (gen-binding (car pattern)
- (dynamic-parse-action-var-def
- (car pattern)))))
- (else f-env)))
- f-env))
- ((begin) (def-var* f-env (cdr clause)))
- (else #f))
- #f))
- (if (pair? body)
- (dynamic-parse-command* (def-var* env body) body)
- (error 'dynamic-parse-body "Illegal body: ~s" body)))
- ; dynamic-parse-if
- (define (dynamic-parse-if env args)
- (cond
- ((list-of-3? args)
- (dynamic-parse-action-conditional
- (dynamic-parse-expression env (car args))
- (dynamic-parse-expression env (cadr args))
- (dynamic-parse-expression env (caddr args))))
- ((list-of-2? args)
- (dynamic-parse-action-conditional
- (dynamic-parse-expression env (car args))
- (dynamic-parse-expression env (cadr args))
- (dynamic-parse-action-empty)))
- (else (error 'dynamic-parse-if "Not an if-expression: ~s" args))))
- ; dynamic-parse-set
- (define (dynamic-parse-set env args)
- (if (list-of-2? args)
- (dynamic-parse-action-assignment
- (dynamic-parse-variable env (car args))
- (dynamic-parse-expression env (cadr args)))
- (error 'dynamic-parse-set "Not a variable/expression pair: ~s" args)))
- ; dynamic-parse-begin
- (define (dynamic-parse-begin env args)
- (dynamic-parse-action-begin-expression
- (dynamic-parse-body env args)))
- ; dynamic-parse-cond
- (define (dynamic-parse-cond env args)
- (if (and (pair? args) (list? args))
- (dynamic-parse-action-cond-expression
- (map (lambda (e)
- (dynamic-parse-cond-clause env e))
- args))
- (error 'dynamic-parse-cond "Not a list of cond-clauses: ~s" args)))
- ; dynamic-parse-cond-clause
- (define (dynamic-parse-cond-clause env e)
- ;; ***Note***: Only (<test> <sequence>) is permitted!
- (if (pair? e)
- (cons
- (if (eqv? (car e) 'else)
- (dynamic-parse-action-empty)
- (dynamic-parse-expression env (car e)))
- (dynamic-parse-body env (cdr e)))
- (error 'dynamic-parse-cond-clause "Not a cond-clause: ~s" e)))
- ; dynamic-parse-and
- (define (dynamic-parse-and env args)
- (if (list? args)
- (dynamic-parse-action-and-expression
- (dynamic-parse-expression* env args))
- (error 'dynamic-parse-and "Not a list of arguments: ~s" args)))
- ; dynamic-parse-or
- (define (dynamic-parse-or env args)
- (if (list? args)
- (dynamic-parse-action-or-expression
- (dynamic-parse-expression* env args))
- (error 'dynamic-parse-or "Not a list of arguments: ~s" args)))
- ; dynamic-parse-case
- (define (dynamic-parse-case env args)
- (if (and (list? args) (> (length args) 1))
- (dynamic-parse-action-case-expression
- (dynamic-parse-expression env (car args))
- (map (lambda (e)
- (dynamic-parse-case-clause env e))
- (cdr args)))
- (error 'dynamic-parse-case "Not a list of clauses: ~s" args)))
- ; dynamic-parse-case-clause
- (define (dynamic-parse-case-clause env e)
- (if (pair? e)
- (cons
- (cond
- ((eqv? (car e) 'else)
- (list (dynamic-parse-action-empty)))
- ((list? (car e))
- (map dynamic-parse-datum (car e)))
- (else (error 'dynamic-parse-case-clause "Not a datum list: ~s" (car e))))
- (dynamic-parse-body env (cdr e)))
- (error 'dynamic-parse-case-clause "Not case clause: ~s" e)))
- ; dynamic-parse-let
- (define (dynamic-parse-let env args)
- (if (pair? args)
- (if (symbol? (car args))
- (dynamic-parse-named-let env args)
- (dynamic-parse-normal-let env args))
- (error 'dynamic-parse-let "Illegal bindings/body: ~s" args)))
- ; dynamic-parse-normal-let
- (define (dynamic-parse-normal-let env args)
- ;; parses "normal" let-expressions
- (let* ((bindings (car args))
- (body (cdr args))
- (env-ast (dynamic-parse-parallel-bindings env bindings))
- (nenv (car env-ast))
- (bresults (cdr env-ast)))
- (dynamic-parse-action-let-expression
- bresults
- (dynamic-parse-body (extend-env-with-env env nenv) body))))
- ; dynamic-parse-named-let
- (define (dynamic-parse-named-let env args)
- ;; parses a named let-expression
- (if (pair? (cdr args))
- (let* ((variable (car args))
- (bindings (cadr args))
- (body (cddr args))
- (vbind-vres (dynamic-parse-formal dynamic-empty-env variable))
- (vbind (car vbind-vres))
- (vres (cdr vbind-vres))
- (env-ast (dynamic-parse-parallel-bindings env bindings))
- (nenv (car env-ast))
- (bresults (cdr env-ast)))
- (dynamic-parse-action-named-let-expression
- vres bresults
- (dynamic-parse-body (extend-env-with-env
- (extend-env-with-binding env vbind)
- nenv) body)))
- (error 'dynamic-parse-named-let "Illegal named let-expression: ~s" args)))
- ; dynamic-parse-parallel-bindings
- (define (dynamic-parse-parallel-bindings env bindings)
- ; returns a pair consisting of an environment
- ; and a list of pairs (variable . asg)
- ; ***Note***: the list of pairs is returned in reverse unzipped form!
- (if (list-of-list-of-2s? bindings)
- (let* ((env-formals-asg
- (dynamic-parse-formal* (map car bindings)))
- (nenv (car env-formals-asg))
- (bresults (cdr env-formals-asg))
- (exprs-asg
- (dynamic-parse-expression* env (map cadr bindings))))
- (cons nenv (cons bresults exprs-asg)))
- (error 'dynamic-parse-parallel-bindings
- "Not a list of bindings: ~s" bindings)))
- ; dynamic-parse-let*
- (define (dynamic-parse-let* env args)
- (if (pair? args)
- (let* ((bindings (car args))
- (body (cdr args))
- (env-ast (dynamic-parse-sequential-bindings env bindings))
- (nenv (car env-ast))
- (bresults (cdr env-ast)))
- (dynamic-parse-action-let*-expression
- bresults
- (dynamic-parse-body (extend-env-with-env env nenv) body)))
- (error 'dynamic-parse-let* "Illegal bindings/body: ~s" args)))
- ; dynamic-parse-sequential-bindings
- (define (dynamic-parse-sequential-bindings env bindings)
- ; returns a pair consisting of an environment
- ; and a list of pairs (variable . asg)
- ;; ***Note***: the list of pairs is returned in reverse unzipped form!
- (letrec
- ((psb
- (lambda (f-env c-env var-defs expr-asgs binds)
- ;; f-env: forbidden environment
- ;; c-env: constructed environment
- ;; var-defs: results of formals
- ;; expr-asgs: results of corresponding expressions
- ;; binds: reminding bindings to process
- (cond
- ((null? binds)
- (cons f-env (cons var-defs expr-asgs)))
- ((pair? binds)
- (let ((fst-bind (car binds)))
- (if (list-of-2? fst-bind)
- (let* ((fbinding-bres
- (dynamic-parse-formal f-env (car fst-bind)))
- (fbind (car fbinding-bres))
- (bres (cdr fbinding-bres))
- (new-expr-asg
- (dynamic-parse-expression c-env (cadr fst-bind))))
- (psb
- (extend-env-with-binding f-env fbind)
- (extend-env-with-binding c-env fbind)
- (cons bres var-defs)
- (cons new-expr-asg expr-asgs)
- (cdr binds)))
- (error 'dynamic-parse-sequential-bindings
- "Illegal binding: ~s" fst-bind))))
- (else (error 'dynamic-parse-sequential-bindings
- "Illegal bindings: ~s" binds))))))
- (let ((env-vdefs-easgs (psb dynamic-empty-env env '() '() bindings)))
- (cons (car env-vdefs-easgs)
- (cons (reverse (cadr env-vdefs-easgs))
- (reverse (cddr env-vdefs-easgs)))))))
- ; dynamic-parse-letrec
- (define (dynamic-parse-letrec env args)
- (if (pair? args)
- (let* ((bindings (car args))
- (body (cdr args))
- (env-ast (dynamic-parse-recursive-bindings env bindings))
- (nenv (car env-ast))
- (bresults (cdr env-ast)))
- (dynamic-parse-action-letrec-expression
- bresults
- (dynamic-parse-body (extend-env-with-env env nenv) body)))
- (error 'dynamic-parse-letrec "Illegal bindings/body: ~s" args)))
- ; dynamic-parse-recursive-bindings
- (define (dynamic-parse-recursive-bindings env bindings)
- ;; ***Note***: the list of pairs is returned in reverse unzipped form!
- (if (list-of-list-of-2s? bindings)
- (let* ((env-formals-asg
- (dynamic-parse-formal* (map car bindings)))
- (formals-env
- (car env-formals-asg))
- (formals-res
- (cdr env-formals-asg))
- (exprs-asg
- (dynamic-parse-expression*
- (extend-env-with-env env formals-env)
- (map cadr bindings))))
- (cons
- formals-env
- (cons formals-res exprs-asg)))
- (error 'dynamic-parse-recursive-bindings "Illegal bindings: ~s" bindings)))
- ; dynamic-parse-do
- (define (dynamic-parse-do env args)
- ;; parses do-expressions
- ;; ***Note***: Not implemented!
- (error 'dynamic-parse-do "Nothing yet..."))
- ; dynamic-parse-quasiquote
- (define (dynamic-parse-quasiquote env args)
- ;; ***Note***: Not implemented!
- (error 'dynamic-parse-quasiquote "Nothing yet..."))
- ;; Command
- ; dynamic-parse-command
- (define (dynamic-parse-command env c)
- (if (pair? c)
- (let ((op (car c))
- (args (cdr c)))
- (case op
- ((define) (dynamic-parse-define env args))
- ; ((begin) (dynamic-parse-command* env args)) ;; AKW
- ((begin) (dynamic-parse-action-begin-expression (dynamic-parse-command* env args)))
- (else (dynamic-parse-expression env c))))
- (dynamic-parse-expression env c)))
- ; dynamic-parse-command*
- (define (dynamic-parse-command* env commands)
- ;; parses a sequence of commands
- (if (list? commands)
- (map (lambda (command) (dynamic-parse-command env command)) commands)
- (error 'dynamic-parse-command* "Invalid sequence of commands: ~s" commands)))
- ; dynamic-parse-define
- (define (dynamic-parse-define env args)
- ;; three cases -- see IEEE Scheme, sect. 5.2
- ;; ***Note***: the parser admits forms (define (x . y) ...)
- ;; ***Note***: Variables are treated as applied occurrences!
- (if (pair? args)
- (let ((pattern (car args))
- (exp-or-body (cdr args)))
- (cond
- ((symbol? pattern)
- (if (list-of-1? exp-or-body)
- (dynamic-parse-action-definition
- (dynamic-parse-variable env pattern)
- (dynamic-parse-expression env (car exp-or-body)))
- (error 'dynamic-parse-define "Not a single expression: ~s" exp-or-body)))
- ((pair? pattern)
- (let* ((function-name (car pattern))
- (function-arg-names (cdr pattern))
- (env-ast (dynamic-parse-formals function-arg-names))
- (formals-env (car env-ast))
- (formals-ast (cdr env-ast)))
- (dynamic-parse-action-function-definition
- (dynamic-parse-variable env function-name)
- formals-ast
- (dynamic-parse-body (extend-env-with-env env formals-env) exp-or-body))))
- (else (error 'dynamic-parse-define "Not a valid pattern: ~s" pattern))))
- (error 'dynamic-parse-define "Not a valid definition: ~s" args)))
- ;; Auxiliary routines
- ; forall?
- (define (forall? pred list)
- (if (null? list)
- #t
- (and (pred (car list)) (forall? pred (cdr list)))))
- ; list-of-1?
- (define (list-of-1? l)
- (and (pair? l) (null? (cdr l))))
- ; list-of-2?
- (define (list-of-2? l)
- (and (pair? l) (pair? (cdr l)) (null? (cddr l))))
- ; list-of-3?
- (define (list-of-3? l)
- (and (pair? l) (pair? (cdr l)) (pair? (cddr l)) (null? (cdddr l))))
- ; list-of-list-of-2s?
- (define (list-of-list-of-2s? e)
- (cond
- ((null? e)
- #t)
- ((pair? e)
- (and (list-of-2? (car e)) (list-of-list-of-2s? (cdr e))))
- (else #f)))
- ;; File processing
- ; dynamic-parse-from-port
- (define (dynamic-parse-from-port port)
- (let ((next-input (read port)))
- (if (eof-object? next-input)
- '()
- (dynamic-parse-action-commands
- (dynamic-parse-command dynamic-empty-env next-input)
- (dynamic-parse-from-port port)))))
- ; dynamic-parse-file
- (define (dynamic-parse-file file-name)
- (let ((input-port (open-input-file file-name)))
- (dynamic-parse-from-port input-port)))
- ;----------------------------------------------------------------------------
- ; Implementation of Union/find data structure in Scheme
- ;----------------------------------------------------------------------------
- ;; for union/find the following attributes are necessary: rank, parent
- ;; (see Tarjan, "Data structures and network algorithms", 1983)
- ;; In the Scheme realization an element is represented as a single
- ;; cons cell; its address is the element itself; the car field contains
- ;; the parent, the cdr field is an address for a cons
- ;; cell containing the rank (car field) and the information (cdr field)
- ;; general union/find data structure
- ;;
- ;; gen-element: Info -> Elem
- ;; find: Elem -> Elem
- ;; link: Elem! x Elem! -> Elem
- ;; asymm-link: Elem! x Elem! -> Elem
- ;; info: Elem -> Info
- ;; set-info!: Elem! x Info -> Void
- (define (gen-element info)
- ; generates a new element: the parent field is initialized to '(),
- ; the rank field to 0
- (cons '() (cons 0 info)))
- (define info (lambda (l) (cddr l)))
- ; returns the information stored in an element
- (define (set-info! elem info)
- ; sets the info-field of elem to info
- (set-cdr! (cdr elem) info))
- ; (define (find! x)
- ; ; finds the class representative of x and sets the parent field
- ; ; directly to the class representative (a class representative has
- ; ; '() as its parent) (uses path halving)
- ; ;(display "Find!: ")
- ; ;(display (pretty-print (info x)))
- ; ;(newline)
- ; (let ((px (car x)))
- ; (if (null? px)
- ; x
- ; (let ((ppx (car px)))
- ; (if (null? ppx)
- ; px
- ; (begin
- ; (set-car! x ppx)
- ; (find! ppx)))))))
- (define (find! elem)
- ; finds the class representative of elem and sets the parent field
- ; directly to the class representative (a class representative has
- ; '() as its parent)
- ;(display "Find!: ")
- ;(display (pretty-print (info elem)))
- ;(newline)
- (let ((p-elem (car elem)))
- (if (null? p-elem)
- elem
- (let ((rep-elem (find! p-elem)))
- (set-car! elem rep-elem)
- rep-elem))))
- (define (link! elem-1 elem-2)
- ; links class elements by rank
- ; they must be distinct class representatives
- ; returns the class representative of the merged equivalence classes
- ;(display "Link!: ")
- ;(display (pretty-print (list (info elem-1) (info elem-2))))
- ;(newline)
- (let ((rank-1 (cadr elem-1))
- (rank-2 (cadr elem-2)))
- (cond
- ((= rank-1 rank-2)
- (set-car! (cdr elem-2) (+ rank-2 1))
- (set-car! elem-1 elem-2)
- elem-2)
- ((> rank-1 rank-2)
- (set-car! elem-2 elem-1)
- elem-1)
- (else
- (set-car! elem-1 elem-2)
- elem-2))))
- (define asymm-link! (lambda (l x) (set-car! l x)))
- ;(define (asymm-link! elem-1 elem-2)
- ; links elem-1 onto elem-2 no matter what rank;
- ; does not update the rank of elem-2 and does not return a value
- ; the two arguments must be distinct
- ;(display "AsymmLink: ")
- ;(display (pretty-print (list (info elem-1) (info elem-2))))
- ;(newline)
- ;(set-car! elem-1 elem-2))
- ;----------------------------------------------------------------------------
- ; Type management
- ;----------------------------------------------------------------------------
- ; introduces type variables and types for Scheme,
- ;; type TVar (type variables)
- ;;
- ;; gen-tvar: () -> TVar
- ;; gen-type: TCon x TVar* -> TVar
- ;; dynamic: TVar
- ;; tvar-id: TVar -> Symbol
- ;; tvar-def: TVar -> Type + Null
- ;; tvar-show: TVar -> Symbol*
- ;;
- ;; set-def!: !TVar x TCon x TVar* -> Null
- ;; equiv!: !TVar x !TVar -> Null
- ;;
- ;;
- ;; type TCon (type constructors)
- ;;
- ;; ...
- ;;
- ;; type Type (types)
- ;;
- ;; gen-type: TCon x TVar* -> Type
- ;; type-con: Type -> TCon
- ;; type-args: Type -> TVar*
- ;;
- ;; boolean: TVar
- ;; character: TVar
- ;; null: TVar
- ;; pair: TVar x TVar -> TVar
- ;; procedure: TVar x TVar* -> TVar
- ;; charseq: TVar
- ;; symbol: TVar
- ;; array: TVar -> TVar
- ; Needed packages: union/find
- ;(load "union-fi.so")
- ; TVar
- (define counter 0)
- ; counter for generating tvar id's
- (define (gen-id)
- ; generates a new id (for printing purposes)
- (set! counter (+ counter 1))
- counter)
- (define (gen-tvar)
- ; generates a new type variable from a new symbol
- ; uses union/find elements with two info fields
- ; a type variable has exactly four fields:
- ; car: TVar (the parent field; initially null)
- ; cadr: Number (the rank field; is always nonnegative)
- ; caddr: Symbol (the type variable identifier; used only for printing)
- ; cdddr: Type (the leq field; initially null)
- (gen-element (cons (gen-id) '())))
- (define (gen-type tcon targs)
- ; generates a new type variable with an associated type definition
- (gen-element (cons (gen-id) (cons tcon targs))))
- (define dynamic (gen-element (cons 0 '())))
- ; the special type variable dynamic
- ; Generic operations
- (define (tvar-id tvar)
- ; returns the (printable) symbol representing the type variable
- (car (info tvar)))
- (define (tvar-def tvar)
- ; returns the type definition (if any) of the type variable
- (cdr (info tvar)))
- (define (set-def! tvar tcon targs)
- ; sets the type definition part of tvar to type
- (set-cdr! (info tvar) (cons tcon targs))
- '())
- (define (reset-def! tvar)
- ; resets the type definition part of tvar to nil
- (set-cdr! (info tvar) '()))
- (define type-con (lambda (l) (car l)))
- ; returns the type constructor of a type definition
- (define type-args (lambda (l) (cdr l)))
- ; returns the type variables of a type definition
- (define (tvar->string tvar)
- ; converts a tvar's id to a string
- (if (eqv? (tvar-id tvar) 0)
- "Dynamic"
- (string-append "t#" (number->string (tvar-id tvar) 10))))
- (define (tvar-show tv)
- ; returns a printable list representation of type variable tv
- (let* ((tv-rep (find! tv))
- (tv-def (tvar-def tv-rep)))
- (cons (tvar->string tv-rep)
- (if (null? tv-def)
- '()
- (cons 'is (type-show tv-def))))))
- (define (type-show type)
- ; returns a printable list representation of type definition type
- (cond
- ((eqv? (type-con type) ptype-con)
- (let ((new-tvar (gen-tvar)))
- (cons ptype-con
- (cons (tvar-show new-tvar)
- (tvar-show ((type-args type) new-tvar))))))
- (else
- (cons (type-con type)
- (map (lambda (tv)
- (tvar->string (find! tv)))
- (type-args type))))))
- ; Special type operations
- ; type constructor literals
- (define boolean-con 'boolean)
- (define char-con 'char)
- (define null-con 'null)
- (define number-con 'number)
- (define pair-con 'pair)
- (define procedure-con 'procedure)
- (define string-con 'string)
- (define symbol-con 'symbol)
- (define vector-con 'vector)
- ; type constants and type constructors
- (define (null)
- ; ***Note***: Temporarily changed to be a pair!
- ; (gen-type null-con '())
- (pair (gen-tvar) (gen-tvar)))
- (define (boolean)
- (gen-type boolean-con '()))
- (define (character)
- (gen-type char-con '()))
- (define (number)
- (gen-type number-con '()))
- (define (charseq)
- (gen-type string-con '()))
- (define (symbol)
- (gen-type symbol-con '()))
- (define (pair tvar-1 tvar-2)
- (gen-type pair-con (list tvar-1 tvar-2)))
- (define (array tvar)
- (gen-type vector-con (list tvar)))
- (define (procedure arg-tvar res-tvar)
- (gen-type procedure-con (list arg-tvar res-tvar)))
- ; equivalencing of type variables
- (define (equiv! tv1 tv2)
- (let* ((tv1-rep (find! tv1))
- (tv2-rep (find! tv2))
- (tv1-def (tvar-def tv1-rep))
- (tv2-def (tvar-def tv2-rep)))
- (cond
- ((eqv? tv1-rep tv2-rep)
- '())
- ((eqv? tv2-rep dynamic)
- (equiv-with-dynamic! tv1-rep))
- ((eqv? tv1-rep dynamic)
- (equiv-with-dynamic! tv2-rep))
- ((null? tv1-def)
- (if (null? tv2-def)
- ; both tv1 and tv2 are distinct type variables
- (link! tv1-rep tv2-rep)
- ; tv1 is a type variable, tv2 is a (nondynamic) type
- (asymm-link! tv1-rep tv2-rep)))
- ((null? tv2-def)
- ; tv1 is a (nondynamic) type, tv2 is a type variable
- (asymm-link! tv2-rep tv1-rep))
- ((eqv? (type-con tv1-def) (type-con tv2-def))
- ; both tv1 and tv2 are (nondynamic) types with equal numbers of
- ; arguments
- (link! tv1-rep tv2-rep)
- (map equiv! (type-args tv1-def) (type-args tv2-def)))
- (else
- ; tv1 and tv2 are types with distinct type constructors or different
- ; numbers of arguments
- (equiv-with-dynamic! tv1-rep)
- (equiv-with-dynamic! tv2-rep))))
- '())
- (define (equiv-with-dynamic! tv)
- (let ((tv-rep (find! tv)))
- (if (not (eqv? tv-rep dynamic))
- (let ((tv-def (tvar-def tv-rep)))
- (asymm-link! tv-rep dynamic)
- (if (not (null? tv-def))
- (map equiv-with-dynamic! (type-args tv-def))))))
- '())
- ;----------------------------------------------------------------------------
- ; Polymorphic type management
- ;----------------------------------------------------------------------------
- ; introduces parametric polymorphic types
- ;; forall: (Tvar -> Tvar) -> TVar
- ;; fix: (Tvar -> Tvar) -> Tvar
- ;;
- ;; instantiate-type: TVar -> TVar
- ; type constructor literal for polymorphic types
- (define ptype-con 'forall)
- (define (forall tv-func)
- (gen-type ptype-con tv-func))
- (define (forall2 tv-func2)
- (forall (lambda (tv1)
- (forall (lambda (tv2)
- (tv-func2 tv1 tv2))))))
- (define (forall3 tv-func3)
- (forall (lambda (tv1)
- (forall2 (lambda (tv2 tv3)
- (tv-func3 tv1 tv2 tv3))))))
- (define (forall4 tv-func4)
- (forall (lambda (tv1)
- (forall3 (lambda (tv2 tv3 tv4)
- (tv-func4 tv1 tv2 tv3 tv4))))))
- (define (forall5 tv-func5)
- (forall (lambda (tv1)
- (forall4 (lambda (tv2 tv3 tv4 tv5)
- (tv-func5 tv1 tv2 tv3 tv4 tv5))))))
- ; (polymorphic) instantiation
- (define (instantiate-type tv)
- ; instantiates type tv and returns a generic instance
- (let* ((tv-rep (find! tv))
- (tv-def (tvar-def tv-rep)))
- (cond
- ((null? tv-def)
- tv-rep)
- ((eqv? (type-con tv-def) ptype-con)
- (instantiate-type ((type-args tv-def) (gen-tvar))))
- (else
- tv-rep))))
- (define (fix tv-func)
- ; forms a recursive type: the fixed point of type mapping tv-func
- (let* ((new-tvar (gen-tvar))
- (inst-tvar (tv-func new-tvar))
- (inst-def (tvar-def inst-tvar)))
- (if (null? inst-def)
- (error 'fix "Illegal recursive type: ~s"
- (list (tvar-show new-tvar) '= (tvar-show inst-tvar)))
- (begin
- (set-def! new-tvar
- (type-con inst-def)
- (type-args inst-def))
- new-tvar))))
-
- ;----------------------------------------------------------------------------
- ; Constraint management
- ;----------------------------------------------------------------------------
- ; constraints
- (define gen-constr (lambda (a b) (cons a b)))
- ; generates an equality between tvar1 and tvar2
- (define constr-lhs (lambda (c) (car c)))
- ; returns the left-hand side of a constraint
- (define constr-rhs (lambda (c) (cdr c)))
- ; returns the right-hand side of a constraint
- (define (constr-show c)
- (cons (tvar-show (car c))
- (cons '=
- (cons (tvar-show (cdr c)) '()))))
- ; constraint set management
- (define global-constraints '())
- (define (init-global-constraints!)
- (set! global-constraints '()))
- (define (add-constr! lhs rhs)
- (set! global-constraints
- (cons (gen-constr lhs rhs) global-constraints))
- '())
- (define (glob-constr-show)
- ; returns printable version of global constraints
- (map constr-show global-constraints))
- ; constraint normalization
- ; Needed packages: type management
- ;(load "typ-mgmt.so")
- (define (normalize-global-constraints!)
- (normalize! global-constraints)
- (init-global-constraints!))
- (define (normalize! constraints)
- (map (lambda (c)
- (equiv! (constr-lhs c) (constr-rhs c))) constraints))
- ; ----------------------------------------------------------------------------
- ; Abstract syntax definition and parse actions
- ; ----------------------------------------------------------------------------
- ; Needed packages: ast-gen.ss
- ;(load "ast-gen.ss")
- ;; Abstract syntax
- ;;
- ;; VarDef
- ;;
- ;; Identifier = Symbol - SyntacticKeywords
- ;; SyntacticKeywords = { ... } (see Section 7.1, IEEE Scheme Standard)
- ;;
- ;; Datum
- ;;
- ;; null-const: Null -> Datum
- ;; boolean-const: Bool -> Datum
- ;; char-const: Char -> Datum
- ;; number-const: Number -> Datum
- ;; string-const: String -> Datum
- ;; vector-const: Datum* -> Datum
- ;; pair-const: Datum x Datum -> Datum
- ;;
- ;; Expr
- ;;
- ;; Datum < Expr
- ;;
- ;; var-def: Identifier -> VarDef
- ;; variable: VarDef -> Expr
- ;; identifier: Identifier -> Expr
- ;; procedure-call: Expr x Expr* -> Expr
- ;; lambda-expression: Formals x Body -> Expr
- ;; conditional: Expr x Expr x Expr -> Expr
- ;; assignment: Variable x Expr -> Expr
- ;; cond-expression: CondClause+ -> Expr
- ;; case-expression: Expr x CaseClause* -> Expr
- ;; and-expression: Expr* -> Expr
- ;; or-expression: Expr* -> Expr
- ;; let-expression: (VarDef* x Expr*) x Body -> Expr
- ;; named-let-expression: VarDef x (VarDef* x Expr*) x Body -> Expr
- ;; let*-expression: (VarDef* x Expr*) x Body -> Expr
- ;; letrec-expression: (VarDef* x Expr*) x Body -> Expr
- ;; begin-expression: Expr+ -> Expr
- ;; do-expression: IterDef* x CondClause x Expr* -> Expr
- ;; empty: -> Expr
- ;;
- ;; VarDef* < Formals
- ;;
- ;; simple-formal: VarDef -> Formals
- ;; dotted-formals: VarDef* x VarDef -> Formals
- ;;
- ;; Body = Definition* x Expr+ (reversed)
- ;; CondClause = Expr x Expr+
- ;; CaseClause = Datum* x Expr+
- ;; IterDef = VarDef x Expr x Expr
- ;;
- ;; Definition
- ;;
- ;; definition: Identifier x Expr -> Definition
- ;; function-definition: Identifier x Formals x Body -> Definition
- ;; begin-command: Definition* -> Definition
- ;;
- ;; Expr < Command
- ;; Definition < Command
- ;;
- ;; Program = Command*
- ;; Abstract syntax operators
- ; Datum
- (define null-const 0)
- (define boolean-const 1)
- (define char-const 2)
- (define number-const 3)
- (define string-const 4)
- (define symbol-const 5)
- (define vector-const 6)
- (define pair-const 7)
- ; Bindings
- (define var-def 8)
- (define null-def 29)
- (define pair-def 30)
- ; Expr
- (define variable 9)
- (define identifier 10)
- (define procedure-call 11)
- (define lambda-expression 12)
- (define conditional 13)
- (define assignment 14)
- (define cond-expression 15)
- (define case-expression 16)
- (define and-expression 17)
- (define or-expression 18)
- (define let-expression 19)
- (define named-let-expression 20)
- (define let*-expression 21)
- (define letrec-expression 22)
- (define begin-expression 23)
- (define do-expression 24)
- (define empty 25)
- (define null-arg 31)
- (define pair-arg 32)
- ; Command
- (define definition 26)
- (define function-definition 27)
- (define begin-command 28)
- ;; Parse actions for abstract syntax construction
- (define (dynamic-parse-action-null-const)
- ;; dynamic-parse-action for '()
- (ast-gen null-const '()))
- (define (dynamic-parse-action-boolean-const e)
- ;; dynamic-parse-action for #f and #t
- (ast-gen boolean-const e))
- (define (dynamic-parse-action-char-const e)
- ;; dynamic-parse-action for character constants
- (ast-gen char-const e))
- (define (dynamic-parse-action-number-const e)
- ;; dynamic-parse-action for number constants
- (ast-gen number-const e))
- (define (dynamic-parse-action-string-const e)
- ;; dynamic-parse-action for string literals
- (ast-gen string-const e))
- (define (dynamic-parse-action-symbol-const e)
- ;; dynamic-parse-action for symbol constants
- (ast-gen symbol-const e))
- (define (dynamic-parse-action-vector-const e)
- ;; dynamic-parse-action for vector literals
- (ast-gen vector-const e))
- (define (dynamic-parse-action-pair-const e1 e2)
- ;; dynamic-parse-action for pairs
- (ast-gen pair-const (cons e1 e2)))
- (define (dynamic-parse-action-var-def e)
- ;; dynamic-parse-action for defining occurrences of variables;
- ;; e is a symbol
- (ast-gen var-def e))
- (define (dynamic-parse-action-null-formal)
- ;; dynamic-parse-action for null-list of formals
- (ast-gen null-def '()))
- (define (dynamic-parse-action-pair-formal d1 d2)
- ;; dynamic-parse-action for non-null list of formals;
- ;; d1 is the result of parsing the first formal,
- ;; d2 the result of parsing the remaining formals
- (ast-gen pair-def (cons d1 d2)))
- (define (dynamic-parse-action-variable e)
- ;; dynamic-parse-action for applied occurrences of variables
- ;; ***Note***: e is the result of a dynamic-parse-action on the
- ;; corresponding variable definition!
- (ast-gen variable e))
- (define (dynamic-parse-action-identifier e)
- ;; dynamic-parse-action for undeclared identifiers (free variable
- ;; occurrences)
- ;; ***Note***: e is a symbol (legal identifier)
- (ast-gen identifier e))
-
- (define (dynamic-parse-action-null-arg)
- ;; dynamic-parse-action for a null list of arguments in a procedure call
- (ast-gen null-arg '()))
- (define (dynamic-parse-action-pair-arg a1 a2)
- ;; dynamic-parse-action for a non-null list of arguments in a procedure call
- ;; a1 is the result of parsing the first argument,
- ;; a2 the result of parsing the remaining arguments
- (ast-gen pair-arg (cons a1 a2)))
- (define (dynamic-parse-action-procedure-call op args)
- ;; dynamic-parse-action for procedure calls: op function, args list of arguments
- (ast-gen procedure-call (cons op args)))
- (define (dynamic-parse-action-lambda-expression formals body)
- ;; dynamic-parse-action for lambda-abstractions
- (ast-gen lambda-expression (cons formals body)))
- (define (dynamic-parse-action-conditional test then-branch else-branch)
- ;; dynamic-parse-action for conditionals (if-then-else expressions)
- (ast-gen conditional (cons test (cons then-branch else-branch))))
- (define (dynamic-parse-action-empty)
- ;; dynamic-parse-action for missing or empty field
- (ast-gen empty '()))
- (define (dynamic-parse-action-assignment lhs rhs)
- ;; dynamic-parse-action for assignment
- (ast-gen assignment (cons lhs rhs)))
- (define (dynamic-parse-action-begin-expression body)
- ;; dynamic-parse-action for begin-expression
- (ast-gen begin-expression body))
- (define (dynamic-parse-action-cond-expression clauses)
- ;; dynamic-parse-action for cond-expressions
- (ast-gen cond-expression clauses))
- (define (dynamic-parse-action-and-expression args)
- ;; dynamic-parse-action for and-expressions
- (ast-gen and-expression args))
- (define (dynamic-parse-action-or-expression args)
- ;; dynamic-parse-action for or-expressions
- (ast-gen or-expression args))
- (define (dynamic-parse-action-case-expression key clauses)
- ;; dynamic-parse-action for case-expressions
- (ast-gen case-expression (cons key clauses)))
- (define (dynamic-parse-action-let-expression bindings body)
- ;; dynamic-parse-action for let-expressions
- (ast-gen let-expression (cons bindings body)))
- (define (dynamic-parse-action-named-let-expression variable bindings body)
- ;; dynamic-parse-action for named-let expressions
- (ast-gen named-let-expression (cons variable (cons bindings body))))
- (define (dynamic-parse-action-let*-expression bindings body)
- ;; dynamic-parse-action for let-expressions
- (ast-gen let*-expression (cons bindings body)))
- (define (dynamic-parse-action-letrec-expression bindings body)
- ;; dynamic-parse-action for let-expressions
- (ast-gen letrec-expression (cons bindings body)))
- (define (dynamic-parse-action-definition variable expr)
- ;; dynamic-parse-action for simple definitions
- (ast-gen definition (cons variable expr)))
- (define (dynamic-parse-action-function-definition variable formals body)
- ;; dynamic-parse-action for function definitions
- (ast-gen function-definition (cons variable (cons formals body))))
- (define dynamic-parse-action-commands (lambda (a b) (cons a b)))
- ;; dynamic-parse-action for processing a command result followed by a the
- ;; result of processing the remaining commands
- ;; Pretty-printing abstract syntax trees
- (define (ast-show ast)
- ;; converts abstract syntax tree to list representation (Scheme program)
- ;; ***Note***: check translation of constructors to numbers at the top of the file
- (let ((syntax-op (ast-con ast))
- (syntax-arg (ast-arg ast)))
- (case syntax-op
- ((0 1 2 3 4 8 10) syntax-arg)
- ((29 31) '())
- ((30 32) (cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg))))
- ((5) (list 'quote syntax-arg))
- ((6) (list->vector (map ast-show syntax-arg)))
- ((7) (list 'cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg))))
- ((9) (ast-arg syntax-arg))
- ((11) (cons (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg))))
- ((12) (cons 'lambda (cons (ast-show (car syntax-arg))
- (map ast-show (cdr syntax-arg)))))
- ((13) (cons 'if (cons (ast-show (car syntax-arg))
- (cons (ast-show (cadr syntax-arg))
- (let ((alt (cddr syntax-arg)))
- (if (eqv? (ast-con alt) empty)
- '()
- (list (ast-show alt))))))))
- ((14) (list 'set! (ast-show (car syntax-arg)) (ast-show (cdr syntax-arg))))
- ((15) (cons 'cond
- (map (lambda (cc)
- (let ((guard (car cc))
- (body (cdr cc)))
- (cons
- (if (eqv? (ast-con guard) empty)
- 'else
- (ast-show guard))
- (map ast-show body))))
- syntax-arg)))
- ((16) (cons 'case
- (cons (ast-show (car syntax-arg))
- (map (lambda (cc)
- (let ((data (car cc)))
- (if (and (pair? data)
- (eqv? (ast-con (car data)) empty))
- (cons 'else
- (map ast-show (cdr cc)))
- (cons (map datum-show data)
- (map ast-show (cdr cc))))))
- (cdr syntax-arg)))))
- ((17) (cons 'and (map ast-show syntax-arg)))
- ((18) (cons 'or (map ast-show syntax-arg)))
- ((19) (cons 'let
- (cons (map
- (lambda (vd e)
- (list (ast-show vd) (ast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map ast-show (cdr syntax-arg)))))
- ((20) (cons 'let
- (cons (ast-show (car syntax-arg))
- (cons (map
- (lambda (vd e)
- (list (ast-show vd) (ast-show e)))
- (caadr syntax-arg)
- (cdadr syntax-arg))
- (map ast-show (cddr syntax-arg))))))
- ((21) (cons 'let*
- (cons (map
- (lambda (vd e)
- (list (ast-show vd) (ast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map ast-show (cdr syntax-arg)))))
- ((22) (cons 'letrec
- (cons (map
- (lambda (vd e)
- (list (ast-show vd) (ast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map ast-show (cdr syntax-arg)))))
- ((23) (cons 'begin
- (map ast-show syntax-arg)))
- ((24) (error 'ast-show "Do expressions not handled! (~s)" syntax-arg))
- ((25) (error 'ast-show "This can't happen: empty encountered!"))
- ((26) (list 'define
- (ast-show (car syntax-arg))
- (ast-show (cdr syntax-arg))))
- ((27) (cons 'define
- (cons
- (cons (ast-show (car syntax-arg))
- (ast-show (cadr syntax-arg)))
- (map ast-show (cddr syntax-arg)))))
- ((28) (cons 'begin
- (map ast-show syntax-arg)))
- (else (error 'ast-show "Unknown abstract syntax operator: ~s"
- syntax-op)))))
- ;; ast*-show
- (define (ast*-show p)
- ;; shows a list of abstract syntax trees
- (map ast-show p))
- ;; datum-show
- (define (datum-show ast)
- ;; prints an abstract syntax tree as a datum
- (case (ast-con ast)
- ((0 1 2 3 4 5) (ast-arg ast))
- ((6) (list->vector (map datum-show (ast-arg ast))))
- ((7) (cons (datum-show (car (ast-arg ast))) (datum-show (cdr (ast-arg ast)))))
- (else (error 'datum-show "This should not happen!"))))
- ; write-to-port
- (define (write-to-port prog port)
- ; writes a program to a port
- (for-each
- (lambda (command)
- (pretty-print command port)
- (newline port))
- prog)
- '())
- ; write-file
- (define (write-to-file prog filename)
- ; write a program to a file
- (let ((port (open-output-file filename)))
- (write-to-port prog port)
- (close-output-port port)
- '()))
- ; ----------------------------------------------------------------------------
- ; Typed abstract syntax tree management: constraint generation, display, etc.
- ; ----------------------------------------------------------------------------
- ;; Abstract syntax operations, incl. constraint generation
- (define (ast-gen syntax-op arg)
- ; generates all attributes and performs semantic side effects
- (let ((ntvar
- (case syntax-op
- ((0 29 31) (null))
- ((1) (boolean))
- ((2) (character))
- ((3) (number))
- ((4) (charseq))
- ((5) (symbol))
- ((6) (let ((aux-tvar (gen-tvar)))
- (for-each (lambda (t)
- (add-constr! t aux-tvar))
- (map ast-tvar arg))
- (array aux-tvar)))
- ((7 30 32) (let ((t1 (ast-tvar (car arg)))
- (t2 (ast-tvar (cdr arg))))
- (pair t1 t2)))
- ((8) (gen-tvar))
- ((9) (ast-tvar arg))
- ((10) (let ((in-env (dynamic-lookup arg dynamic-top-level-env)))
- (if in-env
- (instantiate-type (binding-value in-env))
- (let ((new-tvar (gen-tvar)))
- (set! dynamic-top-level-env (extend-env-with-binding
- dynamic-top-level-env
- (gen-binding arg new-tvar)))
- new-tvar))))
- ((11) (let ((new-tvar (gen-tvar)))
- (add-constr! (procedure (ast-tvar (cdr arg)) new-tvar)
- (ast-tvar (car arg)))
- new-tvar))
- ((12) (procedure (ast-tvar (car arg))
- (ast-tvar (tail (cdr arg)))))
- ((13) (let ((t-test (ast-tvar (car arg)))
- (t-consequent (ast-tvar (cadr arg)))
- (t-alternate (ast-tvar (cddr arg))))
- (add-constr! (boolean) t-test)
- (add-constr! t-consequent t-alternate)
- t-consequent))
- ((14) (let ((var-tvar (ast-tvar (car arg)))
- (exp-tvar (ast-tvar (cdr arg))))
- (add-constr! var-tvar exp-tvar)
- var-tvar))
- ((15) (let ((new-tvar (gen-tvar)))
- (for-each (lambda (body)
- (add-constr! (ast-tvar (tail body)) new-tvar))
- (map cdr arg))
- (for-each (lambda (e)
- (add-constr! (boolean) (ast-tvar e)))
- (map car arg))
- new-tvar))
- ((16) (let* ((new-tvar (gen-tvar))
- (t-key (ast-tvar (car arg)))
- (case-clauses (cdr arg)))
- (for-each (lambda (exprs)
- (for-each (lambda (e)
- (add-constr! (ast-tvar e) t-key))
- exprs))
- (map car case-clauses))
- (for-each (lambda (body)
- (add-constr! (ast-tvar (tail body)) new-tvar))
- (map cdr case-clauses))
- new-tvar))
- ((17 18) (for-each (lambda (e)
- (add-constr! (boolean) (ast-tvar e)))
- arg)
- (boolean))
- ((19 21 22) (let ((var-def-tvars (map ast-tvar (caar arg)))
- (def-expr-types (map ast-tvar (cdar arg)))
- (body-type (ast-tvar (tail (cdr arg)))))
- (for-each add-constr! var-def-tvars def-expr-types)
- body-type))
- ((20) (let ((var-def-tvars (map ast-tvar (caadr arg)))
- (def-expr-types (map ast-tvar (cdadr arg)))
- (body-type (ast-tvar (tail (cddr arg))))
- (named-var-type (ast-tvar (car arg))))
- (for-each add-constr! var-def-tvars def-expr-types)
- (add-constr! (procedure (convert-tvars var-def-tvars) body-type)
- named-var-type)
- body-type))
- ((23) (ast-tvar (tail arg)))
- ((24) (error 'ast-gen
- "Do-expressions not handled! (Argument: ~s) arg"))
- ((25) (gen-tvar))
- ((26) (let ((t-var (ast-tvar (car arg)))
- (t-exp (ast-tvar (cdr arg))))
- (add-constr! t-var t-exp)
- t-var))
- ((27) (let ((t-var (ast-tvar (car arg)))
- (t-formals (ast-tvar (cadr arg)))
- (t-body (ast-tvar (tail (cddr arg)))))
- (add-constr! (procedure t-formals t-body) t-var)
- t-var))
- ((28) (gen-tvar))
- (else (error 'ast-gen "Can't handle syntax operator: ~s" syntax-op)))))
- (cons syntax-op (cons ntvar arg))))
- (define ast-con car)
- ;; extracts the ast-constructor from an abstract syntax tree
- (define ast-arg cddr)
- ;; extracts the ast-argument from an abstract syntax tree
- (define ast-tvar cadr)
- ;; extracts the tvar from an abstract syntax tree
- ;; tail
- (define (tail l)
- ;; returns the tail of a nonempty list
- (if (null? (cdr l))
- (car l)
- (tail (cdr l))))
- ; convert-tvars
- (define (convert-tvars tvar-list)
- ;; converts a list of tvars to a single tvar
- (cond
- ((null? tvar-list) (null))
- ((pair? tvar-list) (pair (car tvar-list)
- (convert-tvars (cdr tvar-list))))
- (else (error 'convert-tvars "Not a list of tvars: ~s" tvar-list))))
- ;; Pretty-printing abstract syntax trees
- (define (tast-show ast)
- ;; converts abstract syntax tree to list representation (Scheme program)
- (let ((syntax-op (ast-con ast))
- (syntax-tvar (tvar-show (ast-tvar ast)))
- (syntax-arg (ast-arg ast)))
- (cons
- (case syntax-op
- ((0 1 2 3 4 8 10) syntax-arg)
- ((29 31) '())
- ((30 32) (cons (tast-show (car syntax-arg))
- (tast-show (cdr syntax-arg))))
- ((5) (list 'quote syntax-arg))
- ((6) (list->vector (map tast-show syntax-arg)))
- ((7) (list 'cons (tast-show (car syntax-arg))
- (tast-show (cdr syntax-arg))))
- ((9) (ast-arg syntax-arg))
- ((11) (cons (tast-show (car syntax-arg)) (tast-show (cdr syntax-arg))))
- ((12) (cons 'lambda (cons (tast-show (car syntax-arg))
- (map tast-show (cdr syntax-arg)))))
- ((13) (cons 'if (cons (tast-show (car syntax-arg))
- (cons (tast-show (cadr syntax-arg))
- (let ((alt (cddr syntax-arg)))
- (if (eqv? (ast-con alt) empty)
- '()
- (list (tast-show alt))))))))
- ((14) (list 'set! (tast-show (car syntax-arg))
- (tast-show (cdr syntax-arg))))
- ((15) (cons 'cond
- (map (lambda (cc)
- (let ((guard (car cc))
- (body (cdr cc)))
- (cons
- (if (eqv? (ast-con guard) empty)
- 'else
- (tast-show guard))
- (map tast-show body))))
- syntax-arg)))
- ((16) (cons 'case
- (cons (tast-show (car syntax-arg))
- (map (lambda (cc)
- (let ((data (car cc)))
- (if (and (pair? data)
- (eqv? (ast-con (car data)) empty))
- (cons 'else
- (map tast-show (cdr cc)))
- (cons (map datum-show data)
- (map tast-show (cdr cc))))))
- (cdr syntax-arg)))))
- ((17) (cons 'and (map tast-show syntax-arg)))
- ((18) (cons 'or (map tast-show syntax-arg)))
- ((19) (cons 'let
- (cons (map
- (lambda (vd e)
- (list (tast-show vd) (tast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map tast-show (cdr syntax-arg)))))
- ((20) (cons 'let
- (cons (tast-show (car syntax-arg))
- (cons (map
- (lambda (vd e)
- (list (tast-show vd) (tast-show e)))
- (caadr syntax-arg)
- (cdadr syntax-arg))
- (map tast-show (cddr syntax-arg))))))
- ((21) (cons 'let*
- (cons (map
- (lambda (vd e)
- (list (tast-show vd) (tast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map tast-show (cdr syntax-arg)))))
- ((22) (cons 'letrec
- (cons (map
- (lambda (vd e)
- (list (tast-show vd) (tast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map tast-show (cdr syntax-arg)))))
- ((23) (cons 'begin
- (map tast-show syntax-arg)))
- ((24) (error 'tast-show "Do expressions not handled! (~s)" syntax-arg))
- ((25) (error 'tast-show "This can't happen: empty encountered!"))
- ((26) (list 'define
- (tast-show (car syntax-arg))
- (tast-show (cdr syntax-arg))))
- ((27) (cons 'define
- (cons
- (cons (tast-show (car syntax-arg))
- (tast-show (cadr syntax-arg)))
- (map tast-show (cddr syntax-arg)))))
- ((28) (cons 'begin
- (map tast-show syntax-arg)))
- (else (error 'tast-show "Unknown abstract syntax operator: ~s"
- syntax-op)))
- syntax-tvar)))
- ;; tast*-show
- (define (tast*-show p)
- ;; shows a list of abstract syntax trees
- (map tast-show p))
- ;; counters for tagging/untagging
- (define untag-counter 0)
- (define no-untag-counter 0)
- (define tag-counter 0)
- (define no-tag-counter 0)
- (define may-untag-counter 0)
- (define no-may-untag-counter 0)
- (define (reset-counters!)
- (set! untag-counter 0)
- (set! no-untag-counter 0)
- (set! tag-counter 0)
- (set! no-tag-counter 0)
- (set! may-untag-counter 0)
- (set! no-may-untag-counter 0))
- (define (counters-show)
- (list
- (cons tag-counter no-tag-counter)
- (cons untag-counter no-untag-counter)
- (cons may-untag-counter no-may-untag-counter)))
- ;; tag-show
- (define (tag-show tvar-rep prog)
- ; display prog with tagging operation
- (if (eqv? tvar-rep dynamic)
- (begin
- (set! tag-counter (+ tag-counter 1))
- (list 'tag prog))
- (begin
- (set! no-tag-counter (+ no-tag-counter 1))
- (list 'no-tag prog))))
- ;; untag-show
- (define (untag-show tvar-rep prog)
- ; display prog with untagging operation
- (if (eqv? tvar-rep dynamic)
- (begin
- (set! untag-counter (+ untag-counter 1))
- (list 'untag prog))
- (begin
- (set! no-untag-counter (+ no-untag-counter 1))
- (list 'no-untag prog))))
- (define (may-untag-show tvar-rep prog)
- ; display possible untagging in actual arguments
- (if (eqv? tvar-rep dynamic)
- (begin
- (set! may-untag-counter (+ may-untag-counter 1))
- (list 'may-untag prog))
- (begin
- (set! no-may-untag-counter (+ no-may-untag-counter 1))
- (list 'no-may-untag prog))))
- ;; tag-ast-show
- (define (tag-ast-show ast)
- ;; converts typed and normalized abstract syntax tree to
- ;; a Scheme program with explicit tagging and untagging operations
- (let ((syntax-op (ast-con ast))
- (syntax-tvar (find! (ast-tvar ast)))
- (syntax-arg (ast-arg ast)))
- (case syntax-op
- ((0 1 2 3 4)
- (tag-show syntax-tvar syntax-arg))
- ((8 10) syntax-arg)
- ((29 31) '())
- ((30) (cons (tag-ast-show (car syntax-arg))
- (tag-ast-show (cdr syntax-arg))))
- ((32) (cons (may-untag-show (find! (ast-tvar (car syntax-arg)))
- (tag-ast-show (car syntax-arg)))
- (tag-ast-show (cdr syntax-arg))))
- ((5) (tag-show syntax-tvar (list 'quote syntax-arg)))
- ((6) (tag-show syntax-tvar (list->vector (map tag-ast-show syntax-arg))))
- ((7) (tag-show syntax-tvar (list 'cons (tag-ast-show (car syntax-arg))
- (tag-ast-show (cdr syntax-arg)))))
- ((9) (ast-arg syntax-arg))
- ((11) (let ((proc-tvar (find! (ast-tvar (car syntax-arg)))))
- (cons (untag-show proc-tvar
- (tag-ast-show (car syntax-arg)))
- (tag-ast-show (cdr syntax-arg)))))
- ((12) (tag-show syntax-tvar
- (cons 'lambda (cons (tag-ast-show (car syntax-arg))
- (map tag-ast-show (cdr syntax-arg))))))
- ((13) (let ((test-tvar (find! (ast-tvar (car syntax-arg)))))
- (cons 'if (cons (untag-show test-tvar
- (tag-ast-show (car syntax-arg)))
- (cons (tag-ast-show (cadr syntax-arg))
- (let ((alt (cddr syntax-arg)))
- (if (eqv? (ast-con alt) empty)
- '()
- (list (tag-ast-show alt)))))))))
- ((14) (list 'set! (tag-ast-show (car syntax-arg))
- (tag-ast-show (cdr syntax-arg))))
- ((15) (cons 'cond
- (map (lambda (cc)
- (let ((guard (car cc))
- (body (cdr cc)))
- (cons
- (if (eqv? (ast-con guard) empty)
- 'else
- (untag-show (find! (ast-tvar guard))
- (tag-ast-show guard)))
- (map tag-ast-show body))))
- syntax-arg)))
- ((16) (cons 'case
- (cons (tag-ast-show (car syntax-arg))
- (map (lambda (cc)
- (let ((data (car cc)))
- (if (and (pair? data)
- (eqv? (ast-con (car data)) empty))
- (cons 'else
- (map tag-ast-show (cdr cc)))
- (cons (map datum-show data)
- (map tag-ast-show (cdr cc))))))
- (cdr syntax-arg)))))
- ((17) (cons 'and (map
- (lambda (ast)
- (let ((bool-tvar (find! (ast-tvar ast))))
- (untag-show bool-tvar (tag-ast-show ast))))
- syntax-arg)))
- ((18) (cons 'or (map
- (lambda (ast)
- (let ((bool-tvar (find! (ast-tvar ast))))
- (untag-show bool-tvar (tag-ast-show ast))))
- syntax-arg)))
- ((19) (cons 'let
- (cons (map
- (lambda (vd e)
- (list (tag-ast-show vd) (tag-ast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map tag-ast-show (cdr syntax-arg)))))
- ((20) (cons 'let
- (cons (tag-ast-show (car syntax-arg))
- (cons (map
- (lambda (vd e)
- (list (tag-ast-show vd) (tag-ast-show e)))
- (caadr syntax-arg)
- (cdadr syntax-arg))
- (map tag-ast-show (cddr syntax-arg))))))
- ((21) (cons 'let*
- (cons (map
- (lambda (vd e)
- (list (tag-ast-show vd) (tag-ast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map tag-ast-show (cdr syntax-arg)))))
- ((22) (cons 'letrec
- (cons (map
- (lambda (vd e)
- (list (tag-ast-show vd) (tag-ast-show e)))
- (caar syntax-arg)
- (cdar syntax-arg))
- (map tag-ast-show (cdr syntax-arg)))))
- ((23) (cons 'begin
- (map tag-ast-show syntax-arg)))
- ((24) (error 'tag-ast-show "Do expressions not handled! (~s)" syntax-arg))
- ((25) (error 'tag-ast-show "This can't happen: empty encountered!"))
- ((26) (list 'define
- (tag-ast-show (car syntax-arg))
- (tag-ast-show (cdr syntax-arg))))
- ((27) (let ((func-tvar (find! (ast-tvar (car syntax-arg)))))
- (list 'define
- (tag-ast-show (car syntax-arg))
- (tag-show func-tvar
- (cons 'lambda
- (cons (tag-ast-show (cadr syntax-arg))
- (map tag-ast-show (cddr syntax-arg))))))))
- ((28) (cons 'begin
- (map tag-ast-show syntax-arg)))
- (else (error 'tag-ast-show "Unknown abstract syntax operator: ~s"
- syntax-op)))))
- ; tag-ast*-show
- (define (tag-ast*-show p)
- ; display list of commands/expressions with tagging/untagging
- ; operations
- (map tag-ast-show p))
- ; ----------------------------------------------------------------------------
- ; Top level type environment
- ; ----------------------------------------------------------------------------
- ; Needed packages: type management (monomorphic and polymorphic)
- ;(load "typ-mgmt.ss")
- ;(load "ptyp-mgm.ss")
- ; type environment for miscellaneous
- (define misc-env
- (list
- (cons 'quote (forall (lambda (tv) tv)))
- (cons 'eqv? (forall (lambda (tv) (procedure (convert-tvars (list tv tv))
- (boolean)))))
- (cons 'eq? (forall (lambda (tv) (procedure (convert-tvars (list tv tv))
- (boolean)))))
- (cons 'equal? (forall (lambda (tv) (procedure (convert-tvars (list tv tv))
- (boolean)))))
- ))
- ; type environment for input/output
- (define io-env
- (list
- (cons 'open-input-file (procedure (convert-tvars (list (charseq))) dynamic))
- (cons 'eof-object? (procedure (convert-tvars (list dynamic)) (boolean)))
- (cons 'read (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) dynamic))))
- (cons 'write (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) dynamic))))
- (cons 'display (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) dynamic))))
- (cons 'newline (procedure (null) dynamic))
- (cons 'pretty-print (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) dynamic))))))
- ; type environment for Booleans
- (define boolean-env
- (list
- (cons 'boolean? (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) (boolean)))))
- ;(cons #f (boolean))
- ; #f doesn't exist in Chez Scheme, but gets mapped to null!
- (cons #t (boolean))
- (cons 'not (procedure (convert-tvars (list (boolean))) (boolean)))
- ))
- ; type environment for pairs and lists
- (define (list-type tv)
- (fix (lambda (tv2) (pair tv tv2))))
- (define list-env
- (list
- (cons 'pair? (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars (list (pair tv1 tv2)))
- (boolean)))))
- (cons 'null? (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars (list (pair tv1 tv2)))
- (boolean)))))
- (cons 'list? (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars (list (pair tv1 tv2)))
- (boolean)))))
- (cons 'cons (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars (list tv1 tv2))
- (pair tv1 tv2)))))
- (cons 'car (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars (list (pair tv1 tv2)))
- tv1))))
- (cons 'cdr (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars (list (pair tv1 tv2)))
- tv2))))
- (cons 'set-car! (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars (list (pair tv1 tv2)
- tv1))
- dynamic))))
- (cons 'set-cdr! (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars (list (pair tv1 tv2)
- tv2))
- dynamic))))
- (cons 'caar (forall3 (lambda (tv1 tv2 tv3)
- (procedure (convert-tvars
- (list (pair (pair tv1 tv2) tv3)))
- tv1))))
- (cons 'cdar (forall3 (lambda (tv1 tv2 tv3)
- (procedure (convert-tvars
- (list (pair (pair tv1 tv2) tv3)))
- tv2))))
- (cons 'cadr (forall3 (lambda (tv1 tv2 tv3)
- (procedure (convert-tvars
- (list (pair tv1 (pair tv2 tv3))))
- tv2))))
- (cons 'cddr (forall3 (lambda (tv1 tv2 tv3)
- (procedure (convert-tvars
- (list (pair tv1 (pair tv2 tv3))))
- tv3))))
- (cons 'caaar (forall4
- (lambda (tv1 tv2 tv3 tv4)
- (procedure (convert-tvars
- (list (pair (pair (pair tv1 tv2) tv3) tv4)))
- tv1))))
- (cons 'cdaar (forall4
- (lambda (tv1 tv2 tv3 tv4)
- (procedure (convert-tvars
- (list (pair (pair (pair tv1 tv2) tv3) tv4)))
- tv2))))
- (cons 'cadar (forall4
- (lambda (tv1 tv2 tv3 tv4)
- (procedure (convert-tvars
- (list (pair (pair tv1 (pair tv2 tv3)) tv4)))
- tv2))))
- (cons 'cddar (forall4
- (lambda (tv1 tv2 tv3 tv4)
- (procedure (convert-tvars
- (list (pair (pair tv1 (pair tv2 tv3)) tv4)))
- tv3))))
- (cons 'caadr (forall4
- (lambda (tv1 tv2 tv3 tv4)
- (procedure (convert-tvars
- (list (pair tv1 (pair (pair tv2 tv3) tv4))))
- tv2))))
- (cons 'cdadr (forall4
- (lambda (tv1 tv2 tv3 tv4)
- (procedure (convert-tvars
- (list (pair tv1 (pair (pair tv2 tv3) tv4))))
- tv3))))
- (cons 'caddr (forall4
- (lambda (tv1 tv2 tv3 tv4)
- (procedure (convert-tvars
- (list (pair tv1 (pair tv2 (pair tv3 tv4)))))
- tv3))))
- (cons 'cdddr (forall4
- (lambda (tv1 tv2 tv3 tv4)
- (procedure (convert-tvars
- (list (pair tv1 (pair tv2 (pair tv3 tv4)))))
- tv4))))
- (cons 'cadddr
- (forall5 (lambda (tv1 tv2 tv3 tv4 tv5)
- (procedure (convert-tvars
- (list (pair tv1
- (pair tv2
- (pair tv3
- (pair tv4 tv5))))))
- tv4))))
- (cons 'cddddr
- (forall5 (lambda (tv1 tv2 tv3 tv4 tv5)
- (procedure (convert-tvars
- (list (pair tv1
- (pair tv2
- (pair tv3
- (pair tv4 tv5))))))
- tv5))))
- (cons 'list (forall (lambda (tv)
- (procedure tv tv))))
- (cons 'length (forall (lambda (tv)
- (procedure (convert-tvars (list (list-type tv)))
- (number)))))
- (cons 'append (forall (lambda (tv)
- (procedure (convert-tvars (list (list-type tv)
- (list-type tv)))
- (list-type tv)))))
- (cons 'reverse (forall (lambda (tv)
- (procedure (convert-tvars (list (list-type tv)))
- (list-type tv)))))
- (cons 'list-ref (forall (lambda (tv)
- (procedure (convert-tvars (list (list-type tv)
- (number)))
- tv))))
- (cons 'memq (forall (lambda (tv)
- (procedure (convert-tvars (list tv
- (list-type tv)))
- (boolean)))))
- (cons 'memv (forall (lambda (tv)
- (procedure (convert-tvars (list tv
- (list-type tv)))
- (boolean)))))
- (cons 'member (forall (lambda (tv)
- (procedure (convert-tvars (list tv
- (list-type tv)))
- (boolean)))))
- (cons 'assq (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars
- (list tv1
- (list-type (pair tv1 tv2))))
- (pair tv1 tv2)))))
- (cons 'assv (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars
- (list tv1
- (list-type (pair tv1 tv2))))
- (pair tv1 tv2)))))
- (cons 'assoc (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars
- (list tv1
- (list-type (pair tv1 tv2))))
- (pair tv1 tv2)))))
- ))
- (define symbol-env
- (list
- (cons 'symbol? (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) (boolean)))))
- (cons 'symbol->string (procedure (convert-tvars (list (symbol))) (charseq)))
- (cons 'string->symbol (procedure (convert-tvars (list (charseq))) (symbol)))
- ))
- (define number-env
- (list
- (cons 'number? (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) (boolean)))))
- (cons '+ (procedure (convert-tvars (list (number) (number))) (number)))
- (cons '- (procedure (convert-tvars (list (number) (number))) (number)))
- (cons '* (procedure (convert-tvars (list (number) (number))) (number)))
- (cons '/ (procedure (convert-tvars (list (number) (number))) (number)))
- (cons 'number->string (procedure (convert-tvars (list (number))) (charseq)))
- (cons 'string->number (procedure (convert-tvars (list (charseq))) (number)))
- ))
- (define char-env
- (list
- (cons 'char? (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) (boolean)))))
- (cons 'char->integer (procedure (convert-tvars (list (character)))
- (number)))
- (cons 'integer->char (procedure (convert-tvars (list (number)))
- (character)))
- ))
- (define string-env
- (list
- (cons 'string? (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) (boolean)))))
- ))
- (define vector-env
- (list
- (cons 'vector? (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) (boolean)))))
- (cons 'make-vector (forall (lambda (tv)
- (procedure (convert-tvars (list (number)))
- (array tv)))))
- (cons 'vector-length (forall (lambda (tv)
- (procedure (convert-tvars (list (array tv)))
- (number)))))
- (cons 'vector-ref (forall (lambda (tv)
- (procedure (convert-tvars (list (array tv)
- (number)))
- tv))))
- (cons 'vector-set! (forall (lambda (tv)
- (procedure (convert-tvars (list (array tv)
- (number)
- tv))
- dynamic))))
- ))
- (define procedure-env
- (list
- (cons 'procedure? (forall (lambda (tv)
- (procedure (convert-tvars (list tv)) (boolean)))))
- (cons 'map (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars
- (list (procedure (convert-tvars
- (list tv1)) tv2)
- (list-type tv1)))
- (list-type tv2)))))
- (cons 'foreach (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars
- (list (procedure (convert-tvars
- (list tv1)) tv2)
- (list-type tv1)))
- (list-type tv2)))))
- (cons 'call-with-current-continuation
- (forall2 (lambda (tv1 tv2)
- (procedure (convert-tvars
- (list (procedure
- (convert-tvars
- (list (procedure (convert-tvars
- (list tv1)) tv2)))
- tv2)))
- tv2))))
- ))
- ; global top level environment
- (define (global-env)
- (append misc-env
- io-env
- boolean-env
- symbol-env
- number-env
- char-env
- string-env
- vector-env
- procedure-env
- list-env))
- (define dynamic-top-level-env (global-env))
- (define (init-dynamic-top-level-env!)
- (set! dynamic-top-level-env (global-env))
- '())
- (define (dynamic-top-level-env-show)
- ; displays the top level environment
- (map (lambda (binding)
- (cons (key-show (binding-key binding))
- (cons ': (tvar-show (binding-value binding)))))
- (env->list dynamic-top-level-env)))
- ; ----------------------------------------------------------------------------
- ; Dynamic type inference for Scheme
- ; ----------------------------------------------------------------------------
- ; Needed packages:
- (define (ic!) (init-global-constraints!))
- (define (pc) (glob-constr-show))
- (define (lc) (length global-constraints))
- (define (n!) (normalize-global-constraints!))
- (define (pt) (dynamic-top-level-env-show))
- (define (it!) (init-dynamic-top-level-env!))
- (define (io!) (set! tag-ops 0) (set! no-ops 0))
- (define (i!) (ic!) (it!) (io!) '())
- (define tag-ops 0)
- (define no-ops 0)
- ; This wasn't intended to be an i/o benchmark,
- ; so let's read the file just once.
- (define *forms*
- (call-with-input-file
- "dynamic-input.sch"
- (lambda (port)
- (define (loop forms)
- (let ((form (read port)))
- (if (eof-object? form)
- (reverse forms)
- (loop (cons form forms)))))
- (loop '()))))
- (define (dynamic-parse-forms forms)
- (if (null? forms)
- '()
- (let ((next-input (car forms)))
- (dynamic-parse-action-commands
- (dynamic-parse-command dynamic-empty-env next-input)
- (dynamic-parse-forms (cdr forms))))))
- (define doit
- (lambda ()
- (i!)
- (let ((foo (dynamic-parse-forms *forms*)))
- (normalize-global-constraints!)
- (reset-counters!)
- (tag-ast*-show foo)
- (counters-show))))
- (define (dynamic-benchmark . rest)
- (let ((n (if (null? rest) 1 (car rest))))
- (run-benchmark "dynamic"
- n
- doit
- (lambda (result)
- #t))))
- ; eof
|