⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dynamic.scm

📁 Scheme跨平台编译器
💻 SCM
📖 第 1 页 / 共 5 页
字号:
;;; DYNAMIC -- Obtained from Andrew Wright.;; 08/06/01 (felix): renamed "null" to "null2" because stupid MZC can't; handle redefinitions of primitives.;;;; 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)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -