hacking in a call-with-values form to see if i got apply-values right
This commit is contained in:
parent
b27f925dd4
commit
e1c406c6a1
|
@ -43,7 +43,9 @@
|
||||||
[(ControlStackLabel/MultipleValueReturn? v)
|
[(ControlStackLabel/MultipleValueReturn? v)
|
||||||
(assemble-control-stack-label/multiple-value-return v)]
|
(assemble-control-stack-label/multiple-value-return v)]
|
||||||
[(CompiledProcedureEntry? v)
|
[(CompiledProcedureEntry? v)
|
||||||
(assemble-compiled-procedure-entry v)]))
|
(assemble-compiled-procedure-entry v)]
|
||||||
|
[(ControlFrameTemporary? v)
|
||||||
|
(assemble-control-frame-temporary v)]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,10 +66,13 @@
|
||||||
[(PrimitivesReference? target)
|
[(PrimitivesReference? target)
|
||||||
(format "MACHINE.primitives[~s]" (symbol->string (PrimitivesReference-name target)))]
|
(format "MACHINE.primitives[~s]" (symbol->string (PrimitivesReference-name target)))]
|
||||||
[(ControlFrameTemporary? target)
|
[(ControlFrameTemporary? target)
|
||||||
(format "MACHINE.control[MACHINE.control.length-1].~a"
|
(assemble-control-frame-temporary target)]))
|
||||||
(ControlFrameTemporary-name target))]))
|
|
||||||
|
|
||||||
|
|
||||||
|
(: assemble-control-frame-temporary (ControlFrameTemporary -> String))
|
||||||
|
(define (assemble-control-frame-temporary t)
|
||||||
|
(format "MACHINE.control[MACHINE.control.length-1].~a"
|
||||||
|
(ControlFrameTemporary-name t)))
|
||||||
|
|
||||||
;; fixme: use js->string
|
;; fixme: use js->string
|
||||||
(: assemble-const (Const -> String))
|
(: assemble-const (Const -> String))
|
||||||
|
|
|
@ -220,4 +220,9 @@
|
||||||
|
|
||||||
,after-apply-code
|
,after-apply-code
|
||||||
,(make-AssignPrimOpStatement (make-PrimitivesReference 'apply)
|
,(make-AssignPrimOpStatement (make-PrimitivesReference 'apply)
|
||||||
(make-MakeCompiledProcedure apply-entry (make-ArityAtLeast 2) '() 'apply))))))
|
(make-MakeCompiledProcedure apply-entry (make-ArityAtLeast 2) '() 'apply))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
))
|
|
@ -84,7 +84,9 @@
|
||||||
[(ControlStackLabel/MultipleValueReturn? an-input)
|
[(ControlStackLabel/MultipleValueReturn? an-input)
|
||||||
empty]
|
empty]
|
||||||
[(CompiledProcedureEntry? an-input)
|
[(CompiledProcedureEntry? an-input)
|
||||||
(collect-input (CompiledProcedureEntry-proc an-input))]))
|
(collect-input (CompiledProcedureEntry-proc an-input))]
|
||||||
|
[(ControlFrameTemporary? an-input)
|
||||||
|
empty]))
|
||||||
|
|
||||||
(: collect-location ((U Reg Label) -> (Listof Symbol)))
|
(: collect-location ((U Reg Label) -> (Listof Symbol)))
|
||||||
(define (collect-location a-location)
|
(define (collect-location a-location)
|
||||||
|
|
52
compiler.rkt
52
compiler.rkt
|
@ -121,7 +121,10 @@
|
||||||
[(WithContMark? exp)
|
[(WithContMark? exp)
|
||||||
(append (loop (WithContMark-key exp) cenv)
|
(append (loop (WithContMark-key exp) cenv)
|
||||||
(loop (WithContMark-value exp) cenv)
|
(loop (WithContMark-value exp) cenv)
|
||||||
(loop (WithContMark-body exp) cenv))])))
|
(loop (WithContMark-body exp) cenv))]
|
||||||
|
[(ApplyValues? exp)
|
||||||
|
(append (loop (ApplyValues-proc exp) cenv)
|
||||||
|
(loop (ApplyValues-args-expr exp) cenv))])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,7 +181,9 @@
|
||||||
[(LetRec? exp)
|
[(LetRec? exp)
|
||||||
(compile-let-rec exp cenv target linkage)]
|
(compile-let-rec exp cenv target linkage)]
|
||||||
[(WithContMark? exp)
|
[(WithContMark? exp)
|
||||||
(compile-with-cont-mark exp cenv target linkage)]))
|
(compile-with-cont-mark exp cenv target linkage)]
|
||||||
|
[(ApplyValues? exp)
|
||||||
|
(compile-apply-values exp cenv target linkage)]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1416,6 +1421,44 @@
|
||||||
(in-other-context linkage)]))
|
(in-other-context linkage)]))
|
||||||
|
|
||||||
|
|
||||||
|
(: compile-apply-values (ApplyValues CompileTimeEnvironment Target Linkage -> InstructionSequence))
|
||||||
|
(define (compile-apply-values exp cenv target linkage)
|
||||||
|
(append-instruction-sequences
|
||||||
|
|
||||||
|
;; Save the procedure value temporarily in a control stack frame
|
||||||
|
(make-instruction-sequence
|
||||||
|
`(,(make-PushControlFrame/Generic)))
|
||||||
|
(compile (ApplyValues-proc exp)
|
||||||
|
cenv
|
||||||
|
(make-ControlFrameTemporary 'pendingApplyValuesProc)
|
||||||
|
next-linkage/expects-single)
|
||||||
|
|
||||||
|
;; Then evaluate the value producer in a context that expects
|
||||||
|
;; the return values to be placed onto the stack.
|
||||||
|
(compile (ApplyValues-args-expr exp)
|
||||||
|
cenv
|
||||||
|
'val
|
||||||
|
next-linkage/values-on-stack)
|
||||||
|
|
||||||
|
;; Retrieve the procedure off the temporary control frame.
|
||||||
|
(make-instruction-sequence
|
||||||
|
`(,(make-AssignImmediateStatement
|
||||||
|
'proc
|
||||||
|
(make-ControlFrameTemporary 'pendingApplyValuesProc))))
|
||||||
|
|
||||||
|
;; Pop off the temporary control frame
|
||||||
|
(make-instruction-sequence
|
||||||
|
`(,(make-PopControlFrame)))
|
||||||
|
|
||||||
|
;; Finally, do the generic call into the function.
|
||||||
|
(compile-general-procedure-call cenv (make-Reg 'argcount) target linkage)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(: append-instruction-sequences (InstructionSequence * -> InstructionSequence))
|
(: append-instruction-sequences (InstructionSequence * -> InstructionSequence))
|
||||||
(define (append-instruction-sequences . seqs)
|
(define (append-instruction-sequences . seqs)
|
||||||
|
@ -1594,6 +1637,9 @@
|
||||||
[(WithContMark? exp)
|
[(WithContMark? exp)
|
||||||
(make-WithContMark (adjust-expression-depth (WithContMark-key exp) n skip)
|
(make-WithContMark (adjust-expression-depth (WithContMark-key exp) n skip)
|
||||||
(adjust-expression-depth (WithContMark-value exp) n skip)
|
(adjust-expression-depth (WithContMark-value exp) n skip)
|
||||||
(adjust-expression-depth (WithContMark-body exp) n skip))]))
|
(adjust-expression-depth (WithContMark-body exp) n skip))]
|
||||||
|
[(ApplyValues? exp)
|
||||||
|
(make-ApplyValues (adjust-expression-depth (ApplyValues-proc exp) n skip)
|
||||||
|
(adjust-expression-depth (ApplyValues-args-expr exp) n skip))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
LetRec
|
LetRec
|
||||||
InstallValue
|
InstallValue
|
||||||
BoxEnv
|
BoxEnv
|
||||||
WithContMark))
|
WithContMark
|
||||||
|
ApplyValues))
|
||||||
|
|
||||||
(define-struct: Top ([prefix : Prefix]
|
(define-struct: Top ([prefix : Prefix]
|
||||||
[code : Expression]) #:transparent)
|
[code : Expression]) #:transparent)
|
||||||
|
@ -80,6 +81,12 @@
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
|
|
||||||
|
(define-struct: ApplyValues ([proc : Expression]
|
||||||
|
[args-expr : Expression])
|
||||||
|
#: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)))
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
ControlStackLabel
|
ControlStackLabel
|
||||||
ControlStackLabel/MultipleValueReturn
|
ControlStackLabel/MultipleValueReturn
|
||||||
CompiledProcedureEntry
|
CompiledProcedureEntry
|
||||||
))
|
ControlFrameTemporary))
|
||||||
|
|
||||||
|
|
||||||
;; Targets: these are the allowable lhs's for an assignment.
|
;; Targets: these are the allowable lhs's for an assignment.
|
||||||
|
@ -42,7 +42,9 @@
|
||||||
|
|
||||||
|
|
||||||
;; When we need to store a value temporarily in the top control frame, we can use this as a target.
|
;; When we need to store a value temporarily in the top control frame, we can use this as a target.
|
||||||
(define-struct: ControlFrameTemporary ([name : (U 'pendingContinuationMarkKey)])
|
(define-struct: ControlFrameTemporary ([name : (U 'pendingContinuationMarkKey ;; for continuation marks
|
||||||
|
'pendingApplyValuesProc ;; for apply-values
|
||||||
|
)])
|
||||||
#:transparent)
|
#:transparent)
|
||||||
|
|
||||||
|
|
||||||
|
@ -419,7 +421,7 @@
|
||||||
(define-struct: NextLinkage ([context : ValuesContext]))
|
(define-struct: NextLinkage ([context : ValuesContext]))
|
||||||
(define next-linkage/drop-multiple (make-NextLinkage 'drop-multiple))
|
(define next-linkage/drop-multiple (make-NextLinkage 'drop-multiple))
|
||||||
(define next-linkage/expects-single (make-NextLinkage 1))
|
(define next-linkage/expects-single (make-NextLinkage 1))
|
||||||
|
(define next-linkage/values-on-stack (make-NextLinkage 'keep-multiple))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,9 @@
|
||||||
[(ControlStackLabel/MultipleValueReturn? oparg)
|
[(ControlStackLabel/MultipleValueReturn? oparg)
|
||||||
oparg]
|
oparg]
|
||||||
[(CompiledProcedureEntry? oparg)
|
[(CompiledProcedureEntry? oparg)
|
||||||
(make-CompiledProcedureEntry (adjust-oparg-depth (CompiledProcedureEntry-proc oparg) n))]))
|
(make-CompiledProcedureEntry (adjust-oparg-depth (CompiledProcedureEntry-proc oparg) n))]
|
||||||
|
[(ControlFrameTemporary? oparg)
|
||||||
|
oparg]))
|
||||||
|
|
||||||
|
|
||||||
(define-predicate natural? Natural)
|
(define-predicate natural? Natural)
|
||||||
|
|
40
parse.rkt
40
parse.rkt
|
@ -151,7 +151,9 @@
|
||||||
(make-WithContMark (parse (with-continuation-mark-key exp) cenv #f)
|
(make-WithContMark (parse (with-continuation-mark-key exp) cenv #f)
|
||||||
(parse (with-continuation-mark-value exp) cenv #f)
|
(parse (with-continuation-mark-value exp) cenv #f)
|
||||||
(parse (with-continuation-mark-body exp) cenv #f))]
|
(parse (with-continuation-mark-body exp) cenv #f))]
|
||||||
|
|
||||||
|
[(call-with-values? exp)
|
||||||
|
(parse-call-with-values exp cenv)]
|
||||||
|
|
||||||
;; Remember, this needs to be the last case.
|
;; Remember, this needs to be the last case.
|
||||||
[(application? exp)
|
[(application? exp)
|
||||||
|
@ -282,6 +284,10 @@
|
||||||
(append (loop (with-continuation-mark-key exp))
|
(append (loop (with-continuation-mark-key exp))
|
||||||
(loop (with-continuation-mark-value exp))
|
(loop (with-continuation-mark-value exp))
|
||||||
(loop (with-continuation-mark-body exp)))]
|
(loop (with-continuation-mark-body exp)))]
|
||||||
|
|
||||||
|
[(call-with-values? exp)
|
||||||
|
(append (loop (call-with-values-producer exp))
|
||||||
|
(loop (call-with-values-consumer exp)))]
|
||||||
|
|
||||||
;; Remember: this needs to be the last case.
|
;; Remember: this needs to be the last case.
|
||||||
[(application? exp)
|
[(application? exp)
|
||||||
|
@ -351,6 +357,10 @@
|
||||||
(loop (with-continuation-mark-value exp))
|
(loop (with-continuation-mark-value exp))
|
||||||
(loop (with-continuation-mark-body exp)))]
|
(loop (with-continuation-mark-body exp)))]
|
||||||
|
|
||||||
|
[(call-with-values? exp)
|
||||||
|
(append (loop (call-with-values-producer exp))
|
||||||
|
(loop (call-with-values-consumer exp)))]
|
||||||
|
|
||||||
;; Remember, this needs to be the last case.
|
;; Remember, this needs to be the last case.
|
||||||
[(application? exp)
|
[(application? exp)
|
||||||
(append (loop (operator exp))
|
(append (loop (operator exp))
|
||||||
|
@ -582,6 +592,26 @@
|
||||||
#t))])))
|
#t))])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(define (parse-call-with-values exp cenv)
|
||||||
|
(cond
|
||||||
|
[(and (lambda? (call-with-values-producer exp))
|
||||||
|
(empty? (lambda-parameters (call-with-values-producer exp))))
|
||||||
|
(let ([producer (parse `(begin ,@(lambda-body (call-with-values-producer exp)))
|
||||||
|
cenv #f)]
|
||||||
|
[consumer-proc (parse (call-with-values-consumer exp) cenv #f)])
|
||||||
|
(make-ApplyValues consumer-proc producer))]
|
||||||
|
[else
|
||||||
|
(let ([producer (parse `(,(call-with-values-producer exp)) cenv #f)]
|
||||||
|
[consumer-proc (parse (call-with-values-consumer exp) cenv #f)])
|
||||||
|
(make-ApplyValues consumer-proc producer))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(define (desugar-let* exp)
|
(define (desugar-let* exp)
|
||||||
(let ([body (let-body exp)])
|
(let ([body (let-body exp)])
|
||||||
(let loop ([vars (let-variables exp)]
|
(let loop ([vars (let-variables exp)]
|
||||||
|
@ -604,6 +634,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(define (named-let? exp)
|
(define (named-let? exp)
|
||||||
(and (tagged-list? exp 'let)
|
(and (tagged-list? exp 'let)
|
||||||
(symbol? (cadr exp))))
|
(symbol? (cadr exp))))
|
||||||
|
@ -622,6 +653,13 @@
|
||||||
(cdddr exp))
|
(cdddr exp))
|
||||||
|
|
||||||
|
|
||||||
|
(define (call-with-values? exp)
|
||||||
|
(tagged-list? exp 'call-with-values))
|
||||||
|
(define (call-with-values-producer exp)
|
||||||
|
(cadr exp))
|
||||||
|
(define (call-with-values-consumer exp)
|
||||||
|
(caddr exp))
|
||||||
|
|
||||||
|
|
||||||
;; any -> boolean
|
;; any -> boolean
|
||||||
(define (let? exp)
|
(define (let? exp)
|
||||||
|
|
|
@ -746,7 +746,13 @@
|
||||||
|
|
||||||
[(CompiledProcedureEntry? an-oparg)
|
[(CompiledProcedureEntry? an-oparg)
|
||||||
(let ([proc (ensure-closure (evaluate-oparg m (CompiledProcedureEntry-proc an-oparg)))])
|
(let ([proc (ensure-closure (evaluate-oparg m (CompiledProcedureEntry-proc an-oparg)))])
|
||||||
(closure-label proc))]))
|
(closure-label proc))]
|
||||||
|
|
||||||
|
[(ControlFrameTemporary? an-oparg)
|
||||||
|
(let ([ht (frame-temps (control-top m))])
|
||||||
|
(hash-ref ht
|
||||||
|
(ControlFrameTemporary-name an-oparg)))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(: ensure-closure-or-false (SlotValue -> (U closure #f)))
|
(: ensure-closure-or-false (SlotValue -> (U closure #f)))
|
||||||
|
|
|
@ -486,4 +486,16 @@
|
||||||
(make-Top (make-Prefix '(x y z))
|
(make-Top (make-Prefix '(x y z))
|
||||||
(make-WithContMark (make-ToplevelRef 0 0)
|
(make-WithContMark (make-ToplevelRef 0 0)
|
||||||
(make-ToplevelRef 0 1)
|
(make-ToplevelRef 0 1)
|
||||||
(make-ToplevelRef 0 2))))
|
(make-ToplevelRef 0 2))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(test (parse '(call-with-values x y))
|
||||||
|
(make-Top (make-Prefix '(x y))
|
||||||
|
(make-ApplyValues (make-ToplevelRef 0 1)
|
||||||
|
(make-App (make-ToplevelRef 0 0) (list)))))
|
||||||
|
|
||||||
|
(test (parse '(call-with-values (lambda () x) y))
|
||||||
|
(make-Top (make-Prefix '(x y))
|
||||||
|
(make-ApplyValues (make-ToplevelRef 0 1)
|
||||||
|
(make-ToplevelRef 0 0))))
|
Loading…
Reference in New Issue
Block a user