123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
- ;;;
- ;;; Port Author: Andrew Whatson
- ;;;
- ;;; Original Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
- ;;;
- ;;; scheme48-1.9.2/scheme/bcomp/node.scm
- (define-module (prescheme bcomp node)
- #:use-module (srfi srfi-9)
- #:use-module (prescheme scheme48)
- #:use-module (prescheme bcomp mtype)
- #:use-module (prescheme record-discloser)
- #:export (make-node
- node?
- node-operator
- node-operator-id
- node-form
- node-ref
- node-set!
- node-predicate
- make-similar-node
- force-node
- name->qualified
- get-operator
- make-operator-table
- operator-name
- operator-nargs
- operator-table-ref
- operator-define!
- operator-lookup
- operator-type
- operator-uid
- operator?
- operators-table ;;config.scm comp-package.scm
- lambda-node?
- flat-lambda-node?
- name-node?
- call-node?
- literal-node?
- quote-node?
- define-node?
- loophole-node?
- operator/flat-lambda
- operator/lambda
- operator/set!
- operator/call
- operator/begin
- operator/name
- operator/letrec
- operator/letrec*
- operator/pure-letrec
- operator/literal
- operator/quote
- operator/unassigned
- operator/unspecific
- operator/define
- operator/define-syntax
- operator/primitive-procedure
- operator/structure-ref))
- ;; --------------------
- ;; Operators (= special operators and primitives)
- (define-record-type :operator
- (make-operator type nargs uid name)
- operator?
- (type operator-type set-operator-type!)
- (nargs operator-nargs)
- (uid operator-uid)
- (name operator-name))
- (define-record-discloser :operator
- (lambda (s)
- (list 'operator
- (operator-name s)
- (if (symbol? (operator-type s))
- (operator-type s)
- (type->sexp (operator-type s) #t)))))
- (define usual-operator-type
- (procedure-type any-arguments-type value-type #f))
- (define (get-operator name . type-option)
- (let ((type (if (null? type-option) #f (car type-option)))
- (probe (table-ref operators-table name)))
- (if (operator? probe)
- (let ((previous-type (operator-type probe)))
- (cond ((not type))
- ((not previous-type)
- (set-operator-type! probe type))
- ((symbol? type) ;; 'leaf or 'internal
- (if (not (eq? type previous-type))
- (warning 'get-operator
- "operator type inconsistency" name type previous-type)))
- ((subtype? type previous-type) ;;Improvement
- (set-operator-type! probe type))
- ((not (subtype? previous-type type))
- (warning 'get-operator
- "operator type inconsistency"
- name
- (type->sexp previous-type 'foo)
- (type->sexp type 'foo))))
- probe)
- (let* ((uid *operator-uid*)
- (op (make-operator type
- (if (and type
- (not (symbol? type))
- (fixed-arity-procedure-type? type))
- (procedure-type-arity type)
- #f)
- uid
- name)))
- (if (>= uid number-of-operators)
- (warning 'get-operator
- "too many operators" (operator-name op) (operator-type op)))
- (set! *operator-uid* (+ *operator-uid* 1))
- (table-set! operators-table (operator-name op) op)
- (vector-set! the-operators uid op)
- op))))
- (define *operator-uid* 0)
- (define operators-table (make-table))
- (define number-of-operators 400) ;;Fixed-size limits bad, but speed good
- (define the-operators (make-vector number-of-operators #f))
- ;; --------------------
- ;; Operator tables (for fast dispatch)
- (define (make-operator-table default)
- (make-vector number-of-operators default))
- (define operator-table-ref vector-ref)
- (define (operator-lookup table op)
- (operator-table-ref table (operator-uid op)))
- (define (operator-define! table name type proc)
- (vector-set! table
- (operator-uid (get-operator name type))
- proc))
- ;; --------------------
- ;; Nodes
- ;; A node is an annotated expression (or definition or other form).
- ;; The FORM component of a node is an S-expression of the same form as
- ;; the S-expression representation of the expression. E.g. for
- ;; literals, the form is the literal value; for variables the form is
- ;; the variable name; for IF expressions the form is a 4-element list
- ;; (<if> test con alt). Nodes also have a tag identifying what kind
- ;; of node it is (literal, variable, if, etc.) and a property list.
- (define-record-type :node
- (really-make-node uid form plist)
- node?
- (uid node-operator-id)
- (form node-form)
- (plist node-plist set-node-plist!))
- (define-record-discloser :node
- (lambda (n) (list (operator-name (node-operator n)) (node-form n))))
- (define (make-node operator form)
- (really-make-node (operator-uid operator) form '()))
- (define (node-ref node key)
- (let ((probe (assq key (node-plist node))))
- (if probe (cdr probe) #f)))
- ;; removes property if value is #f
- (define (node-set! node key value) ;;gross
- (if value
- (let ((probe (assq key (node-plist node))))
- (if probe
- (set-cdr! probe value)
- (set-node-plist! node (cons (cons key value) (node-plist node)))))
- (let loop ((l (node-plist node)) (prev #f))
- (cond ((null? l) 'lose)
- ((eq? key (caar l))
- (if prev
- (set-cdr! prev (cdr l))
- (set-node-plist! node (cdr l))))
- (else (loop (cdr l) l))))))
- (define (node-operator node)
- (vector-ref the-operators (node-operator-id node)))
- (define (node-predicate name . type-option)
- (let ((id (operator-uid (apply get-operator name type-option))))
- (lambda (node)
- (= (node-operator-id node) id))))
- (define (make-similar-node node form)
- (if (equal? form (node-form node))
- node
- (make-node (node-operator node) form)))
- ;; Top-level nodes are often delayed.
- (define (force-node node)
- (if (node? node)
- node
- (force node)))
- ;; Node predicates and operators.
- (define lambda-node? (node-predicate 'lambda syntax-type))
- (define flat-lambda-node? (node-predicate 'flat-lambda syntax-type))
- (define call-node? (node-predicate 'call))
- (define name-node? (node-predicate 'name 'leaf))
- (define literal-node? (node-predicate 'literal 'leaf))
- (define quote-node? (node-predicate 'quote syntax-type))
- (define define-node? (node-predicate 'define))
- (define loophole-node? (node-predicate 'loophole))
- (define operator/flat-lambda (get-operator 'flat-lambda))
- (define operator/lambda (get-operator 'lambda syntax-type))
- (define operator/set! (get-operator 'set! syntax-type))
- (define operator/call (get-operator 'call 'internal))
- (define operator/begin (get-operator 'begin syntax-type))
- (define operator/name (get-operator 'name 'leaf))
- (define operator/letrec (get-operator 'letrec))
- (define operator/letrec* (get-operator 'letrec*))
- (define operator/pure-letrec (get-operator 'pure-letrec))
- (define operator/literal (get-operator 'literal))
- (define operator/quote (get-operator 'quote syntax-type))
- (define operator/unassigned (get-operator 'unassigned))
- (define operator/unspecific (get-operator 'unspecific (proc () unspecific-type)))
- (define operator/define (get-operator 'define syntax-type))
- (define operator/define-syntax (get-operator 'define-syntax syntax-type))
- (define operator/primitive-procedure
- (get-operator 'primitive-procedure syntax-type))
- (define operator/structure-ref (get-operator 'structure-ref syntax-type))
|