home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-26 | 9.8 KB | 334 lines | [TEXT/gamI] |
- ;==============================================================================
-
- ; file: "env.scm"
-
- ;------------------------------------------------------------------------------
- ;
- ; Environment manipulation and declaration handling package:
- ;
- ;------------------------------------------------------------------------------
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Environment manipulation:
- ; ------------------------
-
- ; structure that represents variables:
-
- (define (make-var
-
- name ; symbol that denotes the variable
- bound ; procedure node that binds the variable (#f if global)
- refs ; set of nodes that reference this variable
- sets ; set of nodes that assign a value to this variable
- source) ; source where variable is first encountered
-
- (vector var-tag name bound refs sets source #f))
-
- (define (var? x)
- (and (vector? x)
- (> (vector-length x) 0)
- (eq? (vector-ref x 0) var-tag)))
-
- (define (var-name x) (vector-ref x 1))
- (define (var-bound x) (vector-ref x 2))
- (define (var-refs x) (vector-ref x 3))
- (define (var-sets x) (vector-ref x 4))
- (define (var-source x) (vector-ref x 5))
- (define (var-info x) (vector-ref x 6))
- (define (var-name-set! x y) (vector-set! x 1 y))
- (define (var-bound-set! x y) (vector-set! x 2 y))
- (define (var-refs-set! x y) (vector-set! x 3 y))
- (define (var-sets-set! x y) (vector-set! x 4 y))
- (define (var-source-set! x y) (vector-set! x 5 y))
- (define (var-info-set! x y) (vector-set! x 6 y))
-
- (define var-tag (list 'VAR-TAG))
-
- (define (var-copy var)
- (make-var (var-name var)
- #t
- (set-empty)
- (set-empty)
- (var-source var)))
-
-
- ; temporary variables are used to name intermediate values
-
- (define (make-temp-var name)
- (make-var name #t (set-empty) (set-empty) #f))
-
- (define (temp-var? var)
- (eq? (var-bound var) #t))
-
- ; special variable used to denote the return address of a procedure
-
- (define ret-var (make-temp-var 'ret))
- (define ret-var-set (set-singleton ret-var))
-
- ; special variable used to denote the pointer to the closed variables
-
- (define closure-env-var (make-temp-var 'closure-env))
-
- ; special variable used to denote empty slots
-
- (define empty-var (make-temp-var #f))
-
-
- ; structure that represents environments:
-
- (define make-global-environment #f)
- (set! make-global-environment
- (lambda () (env-frame #f '())))
-
- (define (env-frame env vars)
- (vector (cons vars #f) ; variables in this frame
- '() ; macro definitions
- '() ; declarations
- env)) ; parent env
-
- (define (env-new-var! env name source)
- (let* ((glob (not (env-parent-ref env)))
- (var (make-var name (not glob) (set-empty) (set-empty) source)))
- (env-vars-set! env (cons var (env-vars-ref env)))
- var))
-
- (define (env-macro env name def)
- (let ((name* (if (full-name? name)
- name
- (let ((prefix (env-namespace-prefix env name)))
- (if prefix (make-full-name prefix name) name)))))
- (vector (vector-ref env 0)
- (cons (cons name* def) (env-macros-ref env))
- (env-decls-ref env)
- (env-parent-ref env))))
-
- (define (env-declare env decl)
- (vector (vector-ref env 0)
- (env-macros-ref env)
- (cons decl (env-decls-ref env))
- (env-parent-ref env)))
-
- (define (env-vars-ref env) (car (vector-ref env 0)))
- (define (env-vars-set! env vars) (set-car! (vector-ref env 0) vars))
- (define (env-macros-ref env) (vector-ref env 1))
- (define (env-decls-ref env) (vector-ref env 2))
- (define (env-parent-ref env) (vector-ref env 3))
-
- (define (env-namespace-prefix env name)
- (let loop ((decls (env-decls-ref env)))
- (if (pair? decls)
- (let ((decl (car decls)))
- (if (eq? (car decl) NAMESPACE-sym)
- (let ((syms (cddr decl)))
- (if (or (null? syms) (memq name syms))
- (cadr decl)
- (loop (cdr decls))))
- (loop (cdr decls))))
- #f)))
-
- (define (env-lookup env name stop-at-first-frame? proc)
-
- (define (search env name full?)
- (if full?
- (search* env name full?)
- (let ((prefix (env-namespace-prefix env name)))
- (if prefix
- (search* env (make-full-name prefix name) #t)
- (search* env name full?)))))
-
- (define (search* env name full?)
-
- (define (search-macros macros)
- (if (pair? macros)
- (let ((m (car macros)))
- (if (eq? (car m) name)
- (proc env name (cdr m))
- (search-macros (cdr macros))))
- (search-vars (env-vars-ref env))))
-
- (define (search-vars vars)
- (if (pair? vars)
- (let ((v (car vars)))
- (if (eq? (var-name v) name)
- (proc env name v)
- (search-vars (cdr vars))))
- (let ((env* (env-parent-ref env)))
- (if (or stop-at-first-frame? (not env*))
- (proc env name #f)
- (search env* name full?)))))
-
- (search-macros (env-macros-ref env)))
-
- (search env name (full-name? name)))
-
- (define (valid-prefix? str) ; non-null name followed by a "#" at end is
- (let ((l (string-length str))) ; valid as is the special prefix ""
- (or (= l 0)
- (and (>= l 2)
- (char=? (string-ref str (- l 1)) #\#)))))
-
- (define (full-name? sym) ; full name if it contains a "#"
- (let ((str (symbol->string sym)))
- (let loop ((i (- (string-length str) 1)))
- (if (< i 0)
- #f
- (if (char=? (string-ref str i) #\#)
- #t
- (loop (- i 1)))))))
-
- (define (make-full-name prefix sym)
- (if (= (string-length prefix) 0)
- sym
- (string->canonical-symbol (string-append prefix (symbol->string sym)))))
-
- (define (env-lookup-var env name source)
- (env-lookup env name #f
- (lambda (env name x)
- (if x
- (if (var? x)
- x
- (compiler-internal-error
- "env-lookup-var, name is that of a macro" name))
- (env-new-var! env name source)))))
-
- (define (env-define-var env name source)
- (env-lookup env name #t
- (lambda (env name x)
- (if x
- (if (var? x)
- (pt-syntax-error source "Duplicate definition of a variable")
- (compiler-internal-error
- "env-define-var, name is that of a macro" name))
- (env-new-var! env name source)))))
-
- (define (env-lookup-global-var env name)
- (let ((env* (env-global-env env)))
-
- (define (search-vars vars)
- (if (pair? vars)
- (let ((v (car vars)))
- (if (eq? (var-name v) name)
- v
- (search-vars (cdr vars))))
- (env-new-var! env* name #f)))
-
- (search-vars (env-vars-ref env*))))
-
- (define (env-global-variables env)
- (env-vars-ref (env-global-env env)))
-
- (define (env-global-env env)
- (let loop ((env env))
- (let ((env* (env-parent-ref env)))
- (if env*
- (loop env*)
- env))))
-
- (define (env-lookup-macro env name)
- (env-lookup env name #f
- (lambda (env name x)
- (if (or (not x) (var? x)) #f x))))
-
- (define (env-declarations env)
- env)
-
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ;
- ; Declarations:
- ; ------------
- ;
- ; A declaration has the form: (##declare <item1> <item2> ...)
- ;
- ; an <item> can be one of 6 types:
- ;
- ; - flag declaration : (<id>)
- ; - parameterized declaration : (<id> <parameter>)
- ; - boolean declaration : (<id>) or (NOT <id>)
- ; - namable declaration : (<id> <name>...)
- ; - namable boolean declaration: (<id> <name>...) or (NOT <id> <name>...)
- ; - namable string declaration : (<id> <string> <name>...)
-
- ; Declarations table (for parsing):
-
- (define flag-declarations '())
- (define parameterized-declarations '())
- (define boolean-declarations '())
- (define namable-declarations '())
- (define namable-boolean-declarations '())
- (define namable-string-declarations '())
-
- (define (define-flag-decl name type)
- (set! flag-declarations (cons (cons name type) flag-declarations))
- '())
-
- (define (define-parameterized-decl name)
- (set! parameterized-declarations (cons name parameterized-declarations))
- '())
-
- (define (define-boolean-decl name)
- (set! boolean-declarations (cons name boolean-declarations))
- '())
-
- (define (define-namable-decl name type)
- (set! namable-declarations (cons (cons name type) namable-declarations))
- '())
-
- (define (define-namable-boolean-decl name)
- (set! namable-boolean-declarations (cons name namable-boolean-declarations))
- '())
-
- (define (define-namable-string-decl name)
- (set! namable-string-declarations (cons name namable-string-declarations))
- '())
-
- ; Declaration constructors:
-
- (define (flag-decl source type val)
- (list type val))
-
- (define (parameterized-decl source id parm)
- (list id parm))
-
- (define (boolean-decl source id pos)
- (list id pos))
-
- (define (namable-decl source type val names)
- (cons type (cons val names)))
-
- (define (namable-boolean-decl source id pos names)
- (cons id (cons pos names)))
-
- (define (namable-string-decl source id str names)
- (if (and (eq? id NAMESPACE-sym) (not (valid-prefix? str)))
- (pt-syntax-error source "Illegal namespace"))
- (cons id (cons str names)))
-
- ; Declaration querying:
-
- (define (declaration-value name element default decls)
- (if (not decls)
- default
- (let loop ((l (env-decls-ref decls)))
- (if (pair? l)
- (let ((d (car l)))
- (if (and (eq? (car d) name)
- (or (null? (cddr d)) (memq element (cddr d))))
- (cadr d)
- (loop (cdr l))))
- (declaration-value name element default (env-parent-ref decls))))))
-
-
- ; Namespace declaration:
- ;
- ; (namespace <space>) set namespace for all plain identifiers
- ; (namespace <space> <var1> ...) only for given variables
-
- (define NAMESPACE-sym (string->canonical-symbol "NAMESPACE"))
-
- (define-namable-string-decl NAMESPACE-sym)
-
-
- ;==============================================================================
-