need letrec next

This commit is contained in:
Danny Yoo 2011-03-10 00:07:42 -05:00
parent a3cf629321
commit fd25182d42
3 changed files with 54 additions and 19 deletions

View File

@ -47,7 +47,9 @@
target
linkage)]
[(App? exp)
(compile-application exp cenv target linkage)]))
(compile-application exp cenv target linkage)]
#;[(Letrec? exp)
(compile-letrec exp cenv target linkage)]))
@ -120,20 +122,7 @@
(: lexical-environment-pop-depth (CompileTimeEnvironment Linkage -> Natural))
;; Computes how much of the environment we need to pop.
(define (lexical-environment-pop-depth cenv linkage)
(length cenv)
#;(cond
[(empty? cenv)
0]
[else
(let: ([entry : CompileTimeEnvironmentEntry (first cenv)])
(cond
[(Prefix? entry)
(+ 1 (lexical-environment-pop-depth (rest cenv) linkage))]
[(symbol? entry)
(cond
(+ 1 (lexical-environment-pop-depth (rest cenv) linkage)))]
[(eq? entry #f)
(+ 1 (lexical-environment-pop-depth (rest cenv) linkage))]))]))
(length cenv))
@ -286,6 +275,43 @@
(compile (Lam-body exp) extended-cenv 'val 'return))))
#;(: compile-letrec (Letrec CompileTimeEnvironment Target Linkage -> InstructionSequence))
#;(define (compile-letrec exp cenv target linkage)
(let* ([after-let (make-label 'afterLet)]
[let-linkage (if (eq? linkage 'next)
after-let
linkage)]
[extended-cenv : CompileTimeEnvironment
(extend-lexical-environment/names
'()
(reverse (Letrec-names exp)))]
[lam-codes : (Listof InstructionSequence)
(let: ([n : Natural (length (Letrec-procs exp))])
(map (lambda: ([lam : Lam]
[target : Target])
(compile-lambda lam extended-cenv target 'next))
(Letrec-procs exp)
(build-list (length (Letrec-procs exp))
(lambda: ([i : Natural])
(make-EnvLexicalReference (- n 1 i))))))]
[body-code : InstructionSequence
(compile (Letrec-body exp) extended-cenv target let-linkage)]
(append-instruction-sequences
(end-with-linkage let-linkage cenv
(make-instruction-sequence `(;; create space for the lambdas
,(make-PushEnvironment n)
;; install each one of them in place
(apply append-instruction-sequences lam-codes)
;; mutate each of the lambda's shells so they're correct
;; evaluate the body
body-code
;; pop the temporary space
)))
after-let))))
;; FIXME: I need to implement important special cases.
;; 1. We may be able to open-code if the operator is primitive

View File

@ -5,7 +5,7 @@
;; Expressions
(define-type ExpressionCore (U Top Constant Var Branch Def Lam Seq App))
(define-type ExpressionCore (U Top Constant Var Branch Def Lam Seq App #;Letrec))
(define-struct: Top ([prefix : Prefix]
[code : ExpressionCore]) #:transparent)
@ -22,6 +22,10 @@
(define-struct: App ([operator : ExpressionCore]
[operands : (Listof ExpressionCore)]) #:transparent)
#;(define-struct: Letrec ([names : (Listof Symbol)]
[procs : (Listof Lam)]
[body : ExpressionCore]))
(: last-exp? ((Listof Expression) -> Boolean))
(define (last-exp? seq)
(null? (cdr seq)))

View File

@ -14,8 +14,8 @@
(define (loop exp)
(cond
[(Top? exp)
(list-difference (Prefix-names (Top-prefix exp))
(loop (Top-code exp)))]
(list-difference (loop (Top-code exp))
(Prefix-names (Top-prefix exp)))]
[(Constant? exp)
empty]
@ -39,7 +39,12 @@
[(App? exp)
(append (loop (App-operator exp))
(apply append (map loop (App-operands exp))))]))
(apply append (map loop (App-operands exp))))]
#;[(Letrec? exp)
(list-difference (append (apply append (map loop (Letrec-procs exp)))
(loop (Letrec-body exp)))
(Letrec-names exp))]))
(unique/eq? (loop exp)))