testing parse
This commit is contained in:
parent
a794c9cf68
commit
7e30883490
|
@ -33,25 +33,30 @@
|
||||||
[alternative : ExpressionCore]) #:transparent)
|
[alternative : ExpressionCore]) #:transparent)
|
||||||
|
|
||||||
(define-struct: Lam ([num-parameters : Natural]
|
(define-struct: Lam ([num-parameters : Natural]
|
||||||
[body : ExpressionCore]) #:transparent)
|
[body : ExpressionCore]
|
||||||
|
[closure-map : (Listof EnvReference)]) #:transparent)
|
||||||
|
|
||||||
(define-struct: Seq ([actions : (Listof ExpressionCore)]) #:transparent)
|
(define-struct: Seq ([actions : (Listof ExpressionCore)]) #:transparent)
|
||||||
(define-struct: App ([operator : ExpressionCore]
|
(define-struct: App ([operator : ExpressionCore]
|
||||||
[operands : (Listof ExpressionCore)]) #:transparent)
|
[operands : (Listof ExpressionCore)]) #:transparent)
|
||||||
|
|
||||||
(define-struct: Let1 ([rhs : ExpressionCore ]
|
(define-struct: Let1 ([rhs : ExpressionCore]
|
||||||
[body : ExpressionCore])
|
[body : ExpressionCore])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
(define-struct: Let ([count : Natural]
|
(define-struct: Let ([count : Natural]
|
||||||
[rhss : (Listof ExpressionCore)]
|
[rhss : (Listof ExpressionCore)]
|
||||||
[body : ExpressionCore])
|
[body : ExpressionCore])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
(define-struct: LetRec ([count : Natural]
|
(define-struct: LetRec ([count : Natural]
|
||||||
[rhss : (Listof ExpressionCore)]
|
[rhss : (Listof ExpressionCore)]
|
||||||
[body : ExpressionCore])
|
[body : ExpressionCore])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(: last-exp? ((Listof Expression) -> Boolean))
|
(: last-exp? ((Listof Expression) -> Boolean))
|
||||||
(define (last-exp? seq)
|
(define (last-exp? seq)
|
||||||
(null? (cdr seq)))
|
(null? (cdr seq)))
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
|
|
||||||
;; Find where the variable is located in the lexical environment
|
;; Find where the variable is located in the lexical environment
|
||||||
(: find-variable (Symbol CompileTimeEnvironment -> (U LexicalAddress False)))
|
(: find-variable (Symbol CompileTimeEnvironment -> LexicalAddress))
|
||||||
(define (find-variable name cenv)
|
(define (find-variable name cenv)
|
||||||
(: find-pos (Symbol (Listof (U Symbol False)) -> Natural))
|
(: find-pos (Symbol (Listof (U Symbol False)) -> Natural))
|
||||||
(define (find-pos sym los)
|
(define (find-pos sym los)
|
||||||
|
@ -23,11 +23,11 @@
|
||||||
0]
|
0]
|
||||||
[else
|
[else
|
||||||
(add1 (find-pos sym (cdr los)))]))
|
(add1 (find-pos sym (cdr los)))]))
|
||||||
(let: loop : (U LexicalAddress False)
|
(let: loop : LexicalAddress
|
||||||
([cenv : CompileTimeEnvironment cenv]
|
([cenv : CompileTimeEnvironment cenv]
|
||||||
[depth : Natural 0])
|
[depth : Natural 0])
|
||||||
(cond [(empty? cenv)
|
(cond [(empty? cenv)
|
||||||
#f]
|
(error 'find-variable "~s not in lexical environment" cenv)]
|
||||||
[else
|
[else
|
||||||
(let: ([elt : CompileTimeEnvironmentEntry (first cenv)])
|
(let: ([elt : CompileTimeEnvironmentEntry (first cenv)])
|
||||||
(cond
|
(cond
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
;; A toplevel prefix contains a list of toplevel variables. Some of the
|
;; A toplevel prefix contains a list of toplevel variables. Some of the
|
||||||
;; names may be masked out by #f.
|
;; names may be masked out by #f.
|
||||||
(define-struct: Prefix ([names : (Listof (U Symbol False))])
|
(define-struct: Prefix ([names : (Listof (U Symbol False))])
|
||||||
#:transparent
|
#:transparent)
|
||||||
#:mutable)
|
|
||||||
|
|
||||||
|
|
||||||
(define-struct: NamedBinding ([name : Symbol]))
|
(define-struct: NamedBinding ([name : Symbol]))
|
||||||
|
|
162
parse.rkt
162
parse.rkt
|
@ -3,15 +3,14 @@
|
||||||
(require "expression-structs.rkt"
|
(require "expression-structs.rkt"
|
||||||
"lexical-env.rkt"
|
"lexical-env.rkt"
|
||||||
"lexical-structs.rkt"
|
"lexical-structs.rkt"
|
||||||
|
"helpers.rkt"
|
||||||
racket/list)
|
racket/list)
|
||||||
|
|
||||||
(provide (rename-out (-parse parse)))
|
(provide (rename-out (-parse parse)))
|
||||||
|
|
||||||
(define (-parse exp)
|
(define (-parse exp)
|
||||||
(let* ([prefix (make-Prefix '())]
|
(let* ([prefix (make-Prefix (find-unbound-names exp))])
|
||||||
[cenv (list prefix)])
|
(make-Top prefix (parse exp (extend-lexical-environment '() prefix)))))
|
||||||
(let ([expr (parse exp cenv)])
|
|
||||||
(make-Top prefix expr))))
|
|
||||||
|
|
||||||
|
|
||||||
;; find-prefix: CompileTimeEnvironment -> Natural
|
;; find-prefix: CompileTimeEnvironment -> Natural
|
||||||
|
@ -25,21 +24,6 @@
|
||||||
(add1 (find-prefix (rest cenv)))]))
|
(add1 (find-prefix (rest cenv)))]))
|
||||||
|
|
||||||
|
|
||||||
;; find-variable*: Any CompileTimeEnvironment -> LexicalAddress
|
|
||||||
(define (find-variable* exp cenv)
|
|
||||||
(let ([address (find-variable exp cenv)])
|
|
||||||
(cond
|
|
||||||
[(eq? address #f)
|
|
||||||
(let* ([prefix-depth (find-prefix cenv)]
|
|
||||||
[prefix (list-ref cenv prefix-depth)])
|
|
||||||
(set-Prefix-names! prefix (append (Prefix-names prefix)
|
|
||||||
(list exp)))
|
|
||||||
(find-variable* exp cenv))]
|
|
||||||
[else
|
|
||||||
address])))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; parse: Any CompileTimeEnvironment -> ExpressionCore
|
;; parse: Any CompileTimeEnvironment -> ExpressionCore
|
||||||
;; Compile an expression.
|
;; Compile an expression.
|
||||||
(define (parse exp cenv)
|
(define (parse exp cenv)
|
||||||
|
@ -51,7 +35,7 @@
|
||||||
(make-Constant (text-of-quotation exp))]
|
(make-Constant (text-of-quotation exp))]
|
||||||
|
|
||||||
[(variable? exp)
|
[(variable? exp)
|
||||||
(let ([address (find-variable* exp cenv)])
|
(let ([address (find-variable exp cenv)])
|
||||||
(cond
|
(cond
|
||||||
[(EnvLexicalReference? address)
|
[(EnvLexicalReference? address)
|
||||||
(make-LocalRef (EnvLexicalReference-depth address))]
|
(make-LocalRef (EnvLexicalReference-depth address))]
|
||||||
|
@ -60,7 +44,7 @@
|
||||||
(EnvPrefixReference-pos address))]))]
|
(EnvPrefixReference-pos address))]))]
|
||||||
|
|
||||||
[(definition? exp)
|
[(definition? exp)
|
||||||
(let ([address (find-variable* exp cenv)])
|
(let ([address (find-variable (definition-variable exp) cenv)])
|
||||||
(cond
|
(cond
|
||||||
[(EnvLexicalReference? address)
|
[(EnvLexicalReference? address)
|
||||||
(error 'parse "Can't define except in toplevel context")]
|
(error 'parse "Can't define except in toplevel context")]
|
||||||
|
@ -79,23 +63,22 @@
|
||||||
(parse (desugar-cond exp) cenv)]
|
(parse (desugar-cond exp) cenv)]
|
||||||
|
|
||||||
[(lambda? exp)
|
[(lambda? exp)
|
||||||
;; Fixme: need to know what variables are treated as free here!
|
(let* ([unbound-names (find-unbound-names exp)]
|
||||||
(let* ([prefix (list-ref cenv (find-prefix cenv))]
|
[closure-references (collect-lexical-references
|
||||||
[prefix-length (length (Prefix-names prefix))]
|
(map (lambda (var)
|
||||||
[body-cenv (extend-lexical-environment/names
|
(find-variable var cenv))
|
||||||
'()
|
unbound-names))]
|
||||||
(lambda-parameters exp))])
|
[body-cenv (lexical-references->compile-time-environment
|
||||||
|
closure-references
|
||||||
|
cenv
|
||||||
|
(extend-lexical-environment/names '() (lambda-parameters exp))
|
||||||
|
unbound-names)])
|
||||||
(let ([lam-body (make-Seq (map (lambda (b)
|
(let ([lam-body (make-Seq (map (lambda (b)
|
||||||
(parse b (cons prefix body-cenv)))
|
(parse b body-cenv))
|
||||||
(lambda-body exp)))])
|
(lambda-body exp)))])
|
||||||
(cond [(= prefix-length (length (Prefix-names prefix)))
|
(make-Lam (length (lambda-parameters exp))
|
||||||
(make-Lam (length (lambda-parameters exp))
|
lam-body
|
||||||
lam-body)]
|
closure-references)))]
|
||||||
[else
|
|
||||||
(make-Lam (length (lambda-parameters exp))
|
|
||||||
(make-Seq (map (lambda (b)
|
|
||||||
(parse b body-cenv))
|
|
||||||
(lambda-body exp))))])))]
|
|
||||||
|
|
||||||
[(begin? exp)
|
[(begin? exp)
|
||||||
(let ([actions (map (lambda (e)
|
(let ([actions (map (lambda (e)
|
||||||
|
@ -108,13 +91,13 @@
|
||||||
(make-Seq actions)]))]
|
(make-Seq actions)]))]
|
||||||
|
|
||||||
[(named-let? exp)
|
[(named-let? exp)
|
||||||
(parse-named-let exp cenv)]
|
(parse (desugar-named-let exp) cenv)]
|
||||||
|
|
||||||
[(let? exp)
|
|
||||||
(parse-let exp cenv)]
|
|
||||||
|
|
||||||
[(let*? exp)
|
[(let*? exp)
|
||||||
(parse-let* exp cenv)]
|
(parse (desugar-let* exp) cenv)]
|
||||||
|
|
||||||
|
[(let? exp)
|
||||||
|
(parse-let exp cenv)]
|
||||||
|
|
||||||
[(letrec? exp)
|
[(letrec? exp)
|
||||||
(parse-letrec exp cenv)]
|
(parse-letrec exp cenv)]
|
||||||
|
@ -125,12 +108,73 @@
|
||||||
(make-App (parse (operator exp) cenv-with-scratch-space)
|
(make-App (parse (operator exp) cenv-with-scratch-space)
|
||||||
(map (lambda (rand) (parse rand cenv-with-scratch-space))
|
(map (lambda (rand) (parse rand cenv-with-scratch-space))
|
||||||
(operands exp))))]
|
(operands exp))))]
|
||||||
|
|
||||||
[else
|
[else
|
||||||
(error 'compile "Unknown expression type ~e" exp)]))
|
(error 'compile "Unknown expression type ~e" exp)]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; find-unbound-names: Any -> (Listof Symbol)
|
||||||
|
(define (find-unbound-names exp)
|
||||||
|
(cond
|
||||||
|
[(self-evaluating? exp)
|
||||||
|
'()]
|
||||||
|
|
||||||
|
[(quoted? exp)
|
||||||
|
'()]
|
||||||
|
|
||||||
|
[(variable? exp)
|
||||||
|
(list exp)]
|
||||||
|
|
||||||
|
[(definition? exp)
|
||||||
|
(let ([address (find-variable (definition-variable exp))])
|
||||||
|
(cons (definition-variable address)
|
||||||
|
(find-unbound-names (definition-value exp))))]
|
||||||
|
|
||||||
|
[(if? exp)
|
||||||
|
(append (find-unbound-names (if-predicate exp))
|
||||||
|
(find-unbound-names (if-consequent exp))
|
||||||
|
(find-unbound-names (if-alternative exp)))]
|
||||||
|
|
||||||
|
[(cond? exp)
|
||||||
|
(find-unbound-names (desugar-cond exp))]
|
||||||
|
|
||||||
|
[(lambda? exp)
|
||||||
|
(list-difference (apply append (map find-unbound-names (lambda-body exp)))
|
||||||
|
(lambda-parameters exp))]
|
||||||
|
|
||||||
|
[(begin? exp)
|
||||||
|
(apply append (map find-unbound-names (begin-actions exp)))]
|
||||||
|
|
||||||
|
[(named-let? exp)
|
||||||
|
(find-unbound-names (desugar-named-let exp))]
|
||||||
|
|
||||||
|
[(let*? exp)
|
||||||
|
(find-unbound-names (desugar-let* exp))]
|
||||||
|
|
||||||
|
[(let? exp)
|
||||||
|
(append (apply append (map find-unbound-names (let-rhss exp)))
|
||||||
|
(list-difference (apply append (map find-unbound-names (let-body exp)))
|
||||||
|
(let-variables exp)))]
|
||||||
|
|
||||||
|
[(letrec? exp)
|
||||||
|
(list-difference (append (apply append (map find-unbound-names (let-rhss exp)))
|
||||||
|
(apply append (map find-unbound-names (let-body exp))))
|
||||||
|
(let-variables exp))]
|
||||||
|
|
||||||
|
[(application? exp)
|
||||||
|
(append (find-unbound-names (operator exp))
|
||||||
|
(apply append (map find-unbound-names (operands exp))))]
|
||||||
|
|
||||||
|
[else
|
||||||
|
(error 'find-unbound-names "Unknown expression type ~e" exp)]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; expression selectors
|
;; expression selectors
|
||||||
|
|
||||||
(define (self-evaluating? exp)
|
(define (self-evaluating? exp)
|
||||||
|
@ -257,28 +301,26 @@
|
||||||
(parse `(begin ,@body) new-cenv)))])))
|
(parse `(begin ,@body) new-cenv)))])))
|
||||||
|
|
||||||
|
|
||||||
(define (parse-let* exp cenv)
|
(define (desugar-let* exp)
|
||||||
(parse
|
(let ([body (let-body exp)])
|
||||||
(let ([body (let-body exp)])
|
(let loop ([vars (let-variables exp)]
|
||||||
(let loop ([vars (let-variables exp)]
|
[rhss (let-rhss exp)])
|
||||||
[rhss (let-rhss exp)])
|
(cond
|
||||||
(cond
|
[(null? vars)
|
||||||
[(null? vars)
|
`(begin ,@body)]
|
||||||
`(begin ,@body)]
|
[else
|
||||||
[else
|
|
||||||
`(let ([,(car vars) ,(car rhss)])
|
`(let ([,(car vars) ,(car rhss)])
|
||||||
,(loop (cdr vars) (cdr rhss)))])))
|
,(loop (cdr vars) (cdr rhss)))]))))
|
||||||
cenv))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(define (parse-named-let exp cenv)
|
(define (desugar-named-let exp)
|
||||||
(parse
|
`(letrec [(,(named-let-name exp)
|
||||||
`(letrec [(,(named-let-name exp)
|
(lambda ,(named-let-variables exp)
|
||||||
(lambda ,(named-let-variables exp)
|
,@(named-let-body exp)))]
|
||||||
,@(named-let-body exp)))]
|
(,(named-let-name exp) ,@(named-let-rhss exp))))
|
||||||
(,(named-let-name exp) ,@(named-let-rhss exp)))
|
|
||||||
cenv))
|
|
||||||
|
|
||||||
|
|
||||||
(define (named-let? exp)
|
(define (named-let? exp)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user