Hi All,
I need help tracking down the cause of this error:
LANF+closure: meta not found in: ab
The meta ab is introduced in the language LFE2 and is not removed until the language LANF+closure.
However in the pass
(define-pass finish-closure-conversion : LANF (T free-ht labels-ht) -> LANF+closure ...)
which has LANF as input language I get an error that ab is not defined as meta.
The "minimal" example is below.
Any help is appreciated - I am stuck.
#lang racket
(require nanopass/base)
(struct variable (id) #:transparent)
(struct datum (stx value) #:transparent)
(define (unparse-variable x) (syntax->datum (variable-id x)))
(define (unparse-datum d) (datum-value d))
(define-language LFE ; FE = Fully Expanded
(entry TopLevelForm)
(terminals
((variable (x xd)) . => . unparse-variable)
((datum (d)) . => . unparse-datum)
(syntax (s)))
(Formals (f)
(x ...)
(x0 x1 ... . xd)
x)
(TopLevelForm (t)
; turns out it is best keep unique tags (Expr also has a begin)
(topbegin s t ...) => (begin t ...)
(#%expression s e) => (#%expression e)
g)
(GeneralTopLevelForm (g)
e
(define-values s (x ...) e) => (define-values (x ...) e)
(define-syntaxes s (x ...) e) => (define-syntaxes (x ...) e)
(#%require s rrs ...) => (#%require s rrs ...))
(RawRequireSpec (rrs) rrmp) ; todo
;(RawRequireSpec (rrs) ps) ; todo <- the correct one
;(PhaselessSpec (ps) rmp) ; todo
;(RawModulePath (rmp) rrmp) ; todo
(RawRootModulePath (rrmp) (quote x))
(Expr (e)
x
(λ s f e ...) => (λ f e ...) ; #%plain-lambda
(case-lambda s (f e0 e ...) ...) => (case-lambda (f e0 e ...) ...)
(if s e0 e1 e2) => (if e0 e1 e2)
(begin s e0 e1 ...) => (begin e0 e1 ...)
(begin0 s e0 e1 ...) => (begin0 e0 e1 ...)
(let-values s ([(x ...) e] ...) e0 e1 ...) => (let-values ([(x ...) e] ...) e0 e1 ...)
(letrec-values s ([(x ...) e] ...) e0 e1 ...) => (letrec-values ([(x ...) e] ...) e0 e1 ...)
(set! s x e) => (set! x e)
(quote s d) => (quote d)
(quote-syntax s d) => (quote-syntax d)
(wcm s e0 e1 e2) => (with-continuation-mark e0 e1 e2)
(app s e0 e1 ...) => (e0 e1 ...) ; (#%plain-app e0 e1 ...)
(top s x) => (#%top . x)))
(define-language LFE1 (extends LFE)
(Expr (e)
(- (λ s f e ...)
(let-values s ([(x ...) e] ...) e0 e1 ...)
(letrec-values s ([(x ...) e] ...) e0 e1 ...)
(case-lambda s (f e0 e ...) ...))
(+ (λ s f e) => (λ f e)
(let-values s ([(x ...) e] ...) e0) => (let-values ([(x ...) e] ...) e0)
(letrec-values s ([(x ...) e] ...) e0) => (letrec-values ([(x ...) e] ...) e0)
(case-lambda s (f e) ...) => (case-lambda (f e) ...))))
(define-language LFE2 (extends LFE1)
(Abstraction (ab)
(+ (λ s f e) => (λ f e)))
(Expr (e)
(- (λ s f e)
(case-lambda s (f e) ...))
(+ ab
(case-lambda s ab ...) => (case-lambda ab ...))))
(define-language LFE3 (extends LFE2)
(terminals
(+ (primitive (pr))))
(CaseAbstraction (cab)
(+ (case-lambda s ab ...) => (case-lambda ab ...)))
(Expr (e)
(- (case-lambda s ab ...)
(app s e0 e1 ...))
(+ cab
(primapp s pr e1 ...) => (primapp pr e1 ...)
(closedapp s ab e1 ...) => (closedapp ab e1 ...)
(app s e0 e1 ...) => (app e0 e1 ...))))
(define-language LANF (extends LFE3)
;; Atomic Expressions
;; - always terminates
;; - cause no errors
;; - have no side effects
;; Note: Application of pure primitives could be added here
(AExpr (ae)
(+ x
ab
cab
(quote s d) => (quote d)
(quote-syntax s d) => (quote-syntax d)
(top s x) => (#%top . x)))
;; Complex Expressions
;; - defer execution to at most one subexpression
;; - may not terminate
;; - may not error
;; - may have side effects
(CExpr (ce)
(+ ae
(if s ae0 e1 e2) => (if ae0 e1 e2)
(set! s x ae) => (set! x ae)
(wcm s ae0 ae1 e) => (with-continuation-mark ae0 ae1 e)
(app s ae ae1 ...) => (app ae ae1 ...)
(primapp s pr ae1 ...) => (primapp pr ae1 ...)
(closedapp s ab ae1 ...) => (closedapp ab ae1 ...)
(begin s e0 e1 ...) => (begin e0 e1 ...)
(begin0 s e0 e1 ...) => (begin0 e0 e1 ...)))
(Expr (e)
(-
; atomic
x
ab
cab
(quote s d)
(quote-syntax s d)
(top s x)
; complex
(if s e0 e1 e2)
(set! s x e)
(wcm s e0 e1 e2)
(primapp s pr e1 ...)
(closedapp s ab e1 ...)
(app s e0 e1 ...)
(begin s e0 e1 ...)
(begin0 s e0 e1 ...)
; expr
;
(let-values s ([(x ...) e] ...) e0)
(letrec-values s ([(x ...) e] ...) e0))
(+ ; ae ; not needed, an ae is also an ce
ce
(let-values s ([(x ...) ce] ...) e) => (let-values ([(x ...) ce] ...) e)
(letrec-values s ([(x ...) ce] ...) e) => (letrec-values ([(x ...) ce] ...) e))))
(define (natural? v) (and (integer? v) (not (negative? v))))
(define-language LANF+closure (extends LANF)
(terminals
;(- (primitive (pr)))
;(+ (closure+primitive (pr)))
(- (variable (x xd)))
(+ (variable (x xd l)) => unparse-variable) ; l for label
(+ (natural (i)))) ; i for index
(Abstraction (ab)
(- (λ s f e)))
(CaseAbstraction (cab)
(- (case-lambda s ab ...)))
(ClosureAllocation (ca)
(+ (closure s l ae1 ...) => (closure l ae1 ...)))
(CaseClosureAllocation (cca)
(+ (case-closure s ca ...) => (case-closure ca ...)))
(AExpr (ae)
(- ab
cab)
(+ ca
cca
(free-ref x i)))
(CExpr (ce)
(- (closedapp s ab ae1 ...))
(+ (closedapp s ca ae1 ...) => (closedapp ca ae1 ...)))
(ConvertedAbstraction (cab)
(+ (λ s f e) => (λ f e)))
(ConvertedCaseAbstraction (ccab)
(+ (case-lambda s (f e) ...) => (case-lambda (f e) ...)))
(TopLevelForm (t)
(+ (define-label l cab))))
(define-pass finish-closure-conversion : LANF (T free-ht labels-ht) -> LANF+closure ()
(definitions
(define h #'fcc)
(define (label-of ab) (hash-ref labels-ht ab))
(define (free-of ab) (hash-ref free-ht ab))
(define (index-of x free)
(define (x? y) (id=? x y))
(list-index x? free))
; the converted abstractions are lifted to the top-level
(define lifted-abstractions (make-hasheq))
(define (lift! label formals body)
(define cab
(with-output-language (LANF+closure ConvertedAbstraction)
`(λ ,h ,formals ,body)))
(hash-set! lifted-abstractions label cab))
(define current-free (make-parameter empty-set)))
(TopLevelForm : TopLevelForm (T) -> TopLevelForm ())
(Expr : Expr (E) -> Expr ())
(Abstraction : Abstraction (AB) -> ClosureAllocation ()
[(λ ,s ,[f] ,e)
(define l (label-of AB))
(let ([xs (map AExpr (free-of AB))]
[e (parameterize ([current-free (free-of AB)])
(Expr e))])
(lift! l f e)
`(closure ,h ,l ,xs ...))])
(CaseAbstraction : CaseAbstraction (CAB) -> CaseClosureAllocation ()
[(case-lambda ,s ,[ab] ...) ; <---- ERROR: LANF+closure: meta not found in: ab
`(case-closure ,h ,ab ...)])
(AExpr : AExpr (AE) -> AExpr ()
[,x ; note: x is kept for debugging purposes
(define xs (current-free)) ; set by the enclosing abstraction
(match (index-of x xs)
[#f x] ; refers to argument
[i `(free-ref ,x ,(index-of x xs))])])
(begin
(let ([T (TopLevelForm T)])
(with-output-language (LANF+closure TopLevelForm)
; the lifted (converted) abstractions are added to the top-level
(define dl (for/list ([(l cab) lifted-abstractions])
`(define-label ,l ,cab)))
`(topbegin ,h ,dl ... ,T)))))
--
--
Jens Axel Søgaard