implementing list splicing

This commit is contained in:
Danny Yoo 2011-04-10 18:49:18 -04:00
parent 286e68920b
commit 9831504245
7 changed files with 175 additions and 54 deletions

View File

@ -171,6 +171,8 @@ EOF
empty] empty]
[(SetFrameCallee!? op) [(SetFrameCallee!? op)
empty] empty]
[(SpliceListIntoStack!? op)
empty]
[(FixClosureShellMap!? op) [(FixClosureShellMap!? op)
empty])) empty]))
@ -485,7 +487,10 @@ EOF
", "))] ", "))]
[(SetFrameCallee!? op) [(SetFrameCallee!? op)
(format "MACHINE.control[MACHINE.control.length-1].proc = ~a;" (format "MACHINE.control[MACHINE.control.length-1].proc = ~a;"
(assemble-oparg (SetFrameCallee!-proc op)))])) (assemble-oparg (SetFrameCallee!-proc op)))]
[(SpliceListIntoStack!? op)
(format "RUNTIME.spliceListIntoStack(MACHINE, ~a);"
(assemble-oparg (SpliceListIntoStack!-depth op)))]))

View File

@ -166,14 +166,13 @@
;; Push the procedure into proc. ;; Push the procedure into proc.
(make-AssignImmediateStatement 'proc (make-EnvLexicalReference 0 #f)) (make-AssignImmediateStatement 'proc (make-EnvLexicalReference 0 #f))
(make-PopEnvironment (make-Const 1) (make-PopEnvironment (make-Const 1) (make-Const 0))
(make-Const 0))
;; Correct the number of arguments to be passed. ;; Correct the number of arguments to be passed.
(make-AssignPrimOpStatement 'val (make-AssignImmediateStatement 'argcount (make-SubtractArg (make-Reg 'argcount)
(make-CallKernelPrimitiveProcedure 'sub1 (make-Const 1)))
(list (make-Reg 'val)) ;; Splice in the list argument.
(list 'number) (make-PerformStatement (make-SpliceListIntoStack! (make-SubtractArg (make-Reg 'argcount)
(list #f))) (make-Const 1))))
after-apply-code after-apply-code
(make-AssignPrimOpStatement (make-PrimitivesReference 'apply) (make-AssignPrimOpStatement (make-PrimitivesReference 'apply)

View File

@ -260,6 +260,12 @@
#:transparent) #:transparent)
;; Splices the list structure that lives in env[depth] into position.
;; Depth must evaluate to a natural.
(define-struct: SpliceListIntoStack! ([depth : OpArg])
#:transparent)
(define-struct: FixClosureShellMap! (;; depth: where the closure shell is located in the environment (define-struct: FixClosureShellMap! (;; depth: where the closure shell is located in the environment
[depth : Natural] [depth : Natural]
@ -283,6 +289,7 @@
FixClosureShellMap! FixClosureShellMap!
SetFrameCallee! SetFrameCallee!
SpliceListIntoStack!
RestoreEnvironment! RestoreEnvironment!
RestoreControl!)) RestoreControl!))

View File

@ -233,7 +233,24 @@
} }
raise(new Error("restoreControl: unable to find tag " + tag)); raise(new Error("restoreControl: unable to find tag " + tag));
} };
// Splices the list argument in the environment. Adjusts MACHINE.argcount
// appropriately.
var spliceListIntoStack = function(MACHINE, depth) {
var lst = MACHINE.env[MACHINE.env.length - 1 - depth];
var vals = [];
while(lst !== NULL) {
vals.push(lst[0]);
lst = lst[1];
}
vals.reverse();
MACHINE.env.splice.apply(MACHINE.env,
[MACHINE.env.length - 1 - depth, 1].concat(vals));
MACHINE.argcount = MACHINE.argcount + vals.length - 1;
};
// An arity is either a primitive number, an ArityAtLeast instance, // An arity is either a primitive number, an ArityAtLeast instance,
@ -848,6 +865,10 @@
exports['captureControl'] = captureControl; exports['captureControl'] = captureControl;
exports['restoreControl'] = restoreControl; exports['restoreControl'] = restoreControl;
exports['trampoline'] = trampoline;
exports['spliceListIntoStack'] = spliceListIntoStack;
exports['isNumber'] = isNumber; exports['isNumber'] = isNumber;
exports['isPair'] = isPair; exports['isPair'] = isPair;
exports['isVector'] = isVector; exports['isVector'] = isVector;
@ -860,6 +881,6 @@
exports['heir'] = heir; exports['heir'] = heir;
exports['makeClassPredicate'] = makeClassPredicate; exports['makeClassPredicate'] = makeClassPredicate;
exports['trampoline'] = trampoline;
}).call(this); }).call(this);

View File

@ -21,7 +21,7 @@
(require/typed "simulator-helpers.rkt" (require/typed "simulator-helpers.rkt"
[ensure-primitive-value-box (SlotValue -> (Boxof PrimitiveValue))] [ensure-primitive-value-box (SlotValue -> (Boxof PrimitiveValue))]
[ensure-primitive-value (SlotValue -> PrimitiveValue)] [ensure-primitive-value (SlotValue -> PrimitiveValue)]
[ensure-list (Any -> PrimitiveValue)] [ensure-list (Any -> (U Null MutablePair))]
[racket->PrimitiveValue (Any -> PrimitiveValue)]) [racket->PrimitiveValue (Any -> PrimitiveValue)])
@ -291,6 +291,24 @@
(set-CallFrame-proc! frame proc-value) (set-CallFrame-proc! frame proc-value)
'ok)] 'ok)]
[(SpliceListIntoStack!? op)
(let*: ([stack-index : Natural (ensure-natural (evaluate-oparg m (SpliceListIntoStack!-depth op)))]
[arg-list : (Listof PrimitiveValue)
(mutable-pair-list->list
(ensure-list (env-ref m stack-index)))])
(set-machine-env! m (append (take (machine-env m) stack-index)
arg-list
(drop (machine-env m) (add1 stack-index))))
(set-machine-stack-size! m (ensure-natural (+ (machine-stack-size m)
(length arg-list)
-1)))
(set-machine-argcount! m
(ensure-natural
(+ (ensure-natural (machine-argcount m))
(length arg-list)
-1)))
'ok)]
[(RestoreControl!? op) [(RestoreControl!? op)
(let: ([tag-value : ContinuationPromptTagValue (let: ([tag-value : ContinuationPromptTagValue
@ -312,6 +330,24 @@
'ok]))) 'ok])))
(: mutable-pair-list->list ((U Null MutablePair) -> (Listof PrimitiveValue)))
(define (mutable-pair-list->list mlst)
(cond
[(null? mlst)
'()]
[else
(cons (MutablePair-h mlst)
(mutable-pair-list->list (let ([t (MutablePair-t mlst)])
(cond
[(null? t)
t]
[(MutablePair? t)
t]
[else
(error 'mutable-pair-list->list "Not a list: ~s" t)]))))]))
(: arity-match? (Arity Natural -> Boolean)) (: arity-match? (Arity Natural -> Boolean))
(define (arity-match? an-arity n) (define (arity-match? an-arity n)
(cond (cond

View File

@ -368,3 +368,26 @@
,(make-PerformStatement (make-CheckToplevelBound! 0 0))) ,(make-PerformStatement (make-CheckToplevelBound! 0 0)))
"MACHINE.env[0][0]") "MACHINE.env[0][0]")
"Shriram") "Shriram")
(test (E-many `(,(make-PushEnvironment 1 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f)
(make-Const '(1 2 3)))
,(make-AssignImmediateStatement 'argcount (make-Const 1))
,(make-PerformStatement (make-SpliceListIntoStack! (make-Const 0))))
"MACHINE.argcount + ',' + MACHINE.env[0] + ',' + MACHINE.env[1] + ',' + MACHINE.env[2]")
"3,3,2,1")
(test (E-many `(,(make-PushEnvironment 3 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f)
(make-Const "hello"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f)
(make-Const "world"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f)
(make-Const '(1 2 3)))
,(make-AssignImmediateStatement 'argcount (make-Const 3))
,(make-PerformStatement (make-SpliceListIntoStack! (make-Const 2))))
"MACHINE.argcount + ',' + MACHINE.env[0] + ',' + MACHINE.env[1] + ',' + MACHINE.env[2] + ',' + MACHINE.env[3] + ',' + MACHINE.env[4]")
"5,3,2,1,world,hello")

View File

@ -33,11 +33,11 @@
;; run: machine -> machine ;; run: machine -> machine
;; Run the machine to completion. ;; Run the machine to completion.
(define (run m) (define (run! m)
(cond (cond
[(can-step? m) [(can-step? m)
(step! m) (step! m)
(run m)] (run! m)]
[else [else
m])) m]))
@ -72,13 +72,13 @@
(let* ([m (new-machine `(,(make-PushEnvironment 1 #f) (let* ([m (new-machine `(,(make-PushEnvironment 1 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const 42))) ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const 42)))
#f)] #f)]
[m (run m)]) [m (run! m)])
(test (machine-env m) '(42))) (test (machine-env m) '(42)))
;; Assigning to a boxed environment reference ;; Assigning to a boxed environment reference
(let* ([m (new-machine `(,(make-PushEnvironment 1 #t) (let* ([m (new-machine `(,(make-PushEnvironment 1 #t)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #t) (make-Const 42))))] ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #t) (make-Const 42))))]
[m (run m)]) [m (run! m)])
(test (machine-env m) (list (box 42)))) (test (machine-env m) (list (box 42))))
@ -89,13 +89,13 @@
,(make-PushEnvironment 1 #f) ,(make-PushEnvironment 1 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f)
(make-EnvLexicalReference 1 #t))))] (make-EnvLexicalReference 1 #t))))]
[m (run m)]) [m (run! m)])
(test (machine-env m) (list 42 (box 42)))) (test (machine-env m) (list 42 (box 42))))
(let* ([m (new-machine `(,(make-PushEnvironment 1 #t) (let* ([m (new-machine `(,(make-PushEnvironment 1 #t)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #t) (make-Const 42)) ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #t) (make-Const 42))
,(make-PushEnvironment 1 #f)))] ,(make-PushEnvironment 1 #f)))]
[m (run m)]) [m (run! m)])
(test (machine-env m) (list (make-undefined) (test (machine-env m) (list (make-undefined)
(box 42)))) (box 42))))
(let* ([m (new-machine `(,(make-PushEnvironment 1 #t) (let* ([m (new-machine `(,(make-PushEnvironment 1 #t)
@ -103,7 +103,7 @@
,(make-PushEnvironment 1 #f) ,(make-PushEnvironment 1 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f)
(make-EnvLexicalReference 1 #f))))] (make-EnvLexicalReference 1 #f))))]
[m (run m)]) [m (run! m)])
(test (machine-env m) (list (box 42) (test (machine-env m) (list (box 42)
(box 42)))) (box 42))))
@ -113,54 +113,54 @@
;; Assigning to another environment reference ;; Assigning to another environment reference
(let* ([m (new-machine `(,(make-PushEnvironment 2 #f) (let* ([m (new-machine `(,(make-PushEnvironment 2 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const 42))))] ,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const 42))))]
[m (run m)]) [m (run! m)])
(test (machine-env m) `(,(make-undefined) 42))) (test (machine-env m) `(,(make-undefined) 42)))
;; Assigning to another environment reference ;; Assigning to another environment reference
(let* ([m (new-machine `(,(make-PushEnvironment 2 #f) (let* ([m (new-machine `(,(make-PushEnvironment 2 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const 42))))] ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const 42))))]
[m (run m)]) [m (run! m)])
(test (machine-env m) `(42 ,(make-undefined)))) (test (machine-env m) `(42 ,(make-undefined))))
;; PushEnv ;; PushEnv
(let ([m (new-machine `(,(make-PushEnvironment 20 #f)))]) (let ([m (new-machine `(,(make-PushEnvironment 20 #f)))])
(test (machine-env (run m)) (build-list 20 (lambda (i) (make-undefined))))) (test (machine-env (run! m)) (build-list 20 (lambda (i) (make-undefined)))))
;; PopEnv ;; PopEnv
(let ([m (new-machine `(,(make-PushEnvironment 20 #f) (let ([m (new-machine `(,(make-PushEnvironment 20 #f)
,(make-PopEnvironment (make-Const 20) (make-Const 0))))]) ,(make-PopEnvironment (make-Const 20) (make-Const 0))))])
(test (machine-env (run m)) '())) (test (machine-env (run! m)) '()))
(let* ([m (new-machine `(,(make-PushEnvironment 3 #f) (let* ([m (new-machine `(,(make-PushEnvironment 3 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const "hewie")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const "hewie"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const "dewey")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const "dewey"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const "louie")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const "louie"))
,(make-PopEnvironment (make-Const 1) (make-Const 0))))]) ,(make-PopEnvironment (make-Const 1) (make-Const 0))))])
(test (machine-env (run m)) '("dewey" "louie"))) (test (machine-env (run! m)) '("dewey" "louie")))
(let* ([m (new-machine `(,(make-PushEnvironment 3 #f) (let* ([m (new-machine `(,(make-PushEnvironment 3 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const "hewie")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const "hewie"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const "dewey")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const "dewey"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const "louie")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const "louie"))
,(make-PopEnvironment (make-Const 1) (make-Const 1))))]) ,(make-PopEnvironment (make-Const 1) (make-Const 1))))])
(test (machine-env (run m)) '("hewie" "louie"))) (test (machine-env (run! m)) '("hewie" "louie")))
(let* ([m (new-machine `(,(make-PushEnvironment 3 #f) (let* ([m (new-machine `(,(make-PushEnvironment 3 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const "hewie")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const "hewie"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const "dewey")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const "dewey"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const "louie")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const "louie"))
,(make-PopEnvironment (make-Const 1) (make-Const 2))))]) ,(make-PopEnvironment (make-Const 1) (make-Const 2))))])
(test (machine-env (run m)) '("hewie" "dewey"))) (test (machine-env (run! m)) '("hewie" "dewey")))
(let* ([m (new-machine `(,(make-PushEnvironment 3 #f) (let* ([m (new-machine `(,(make-PushEnvironment 3 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const "hewie")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f) (make-Const "hewie"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const "dewey")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f) (make-Const "dewey"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const "louie")) ,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const "louie"))
,(make-PopEnvironment (make-Const 2) (make-Const 1))))]) ,(make-PopEnvironment (make-Const 2) (make-Const 1))))])
(test (machine-env (run m)) '("hewie"))) (test (machine-env (run! m)) '("hewie")))
@ -172,7 +172,7 @@
,(make-PushControlFrame 'bar) ,(make-PushControlFrame 'bar)
baz baz
))]) ))])
(test (machine-control (run m)) (test (machine-control (run! m))
(list (make-CallFrame 'bar #f) (list (make-CallFrame 'bar #f)
(make-CallFrame 'foo #f)))) (make-CallFrame 'foo #f))))
@ -187,7 +187,7 @@
baz baz
,(make-PopControlFrame) ,(make-PopControlFrame)
))]) ))])
(test (machine-control (run m)) (test (machine-control (run! m))
(list (make-CallFrame 'foo #f)))) (list (make-CallFrame 'foo #f))))
(let ([m (new-machine `(,(make-AssignImmediateStatement 'proc (make-Const #f)) (let ([m (new-machine `(,(make-AssignImmediateStatement 'proc (make-Const #f))
@ -198,7 +198,7 @@
baz baz
,(make-PopControlFrame) ,(make-PopControlFrame)
,(make-PopControlFrame)))]) ,(make-PopControlFrame)))])
(test (machine-control (run m)) (test (machine-control (run! m))
(list))) (list)))
@ -213,7 +213,7 @@
on-false on-false
,(make-AssignImmediateStatement 'val (make-Const 'not-ok)) ,(make-AssignImmediateStatement 'val (make-Const 'not-ok))
end))]) end))])
(test (machine-val (run m)) (test (machine-val (run! m))
'ok)) 'ok))
;; TestAndBranch: try the false branch ;; TestAndBranch: try the false branch
(let ([m (new-machine `(,(make-AssignImmediateStatement 'val (make-Const #f)) (let ([m (new-machine `(,(make-AssignImmediateStatement 'val (make-Const #f))
@ -223,7 +223,7 @@
on-false on-false
,(make-AssignImmediateStatement 'val (make-Const 'ok)) ,(make-AssignImmediateStatement 'val (make-Const 'ok))
end))]) end))])
(test (machine-val (run m)) (test (machine-val (run! m))
'ok)) 'ok))
;; Test for primitive procedure ;; Test for primitive procedure
(let ([m (new-machine `(,(make-AssignImmediateStatement 'val (make-Const '+)) (let ([m (new-machine `(,(make-AssignImmediateStatement 'val (make-Const '+))
@ -233,7 +233,7 @@
on-true on-true
,(make-AssignImmediateStatement 'val (make-Const 'not-ok)) ,(make-AssignImmediateStatement 'val (make-Const 'not-ok))
end))]) end))])
(test (machine-val (run m)) (test (machine-val (run! m))
'ok)) 'ok))
;; Give a primitive procedure in val ;; Give a primitive procedure in val
(let ([m (new-machine `(,(make-AssignImmediateStatement 'val (make-Const (lookup-primitive '+))) (let ([m (new-machine `(,(make-AssignImmediateStatement 'val (make-Const (lookup-primitive '+)))
@ -243,7 +243,7 @@
on-true on-true
,(make-AssignImmediateStatement 'val (make-Const 'ok)) ,(make-AssignImmediateStatement 'val (make-Const 'ok))
end))]) end))])
(test (machine-val (run m)) (test (machine-val (run! m))
'ok)) 'ok))
;; Give a primitive procedure in proc, but test val ;; Give a primitive procedure in proc, but test val
(let ([m (new-machine `(,(make-AssignImmediateStatement 'proc (make-Const (lookup-primitive '+))) (let ([m (new-machine `(,(make-AssignImmediateStatement 'proc (make-Const (lookup-primitive '+)))
@ -253,7 +253,7 @@
on-true on-true
,(make-AssignImmediateStatement 'val (make-Const 'a-procedure)) ,(make-AssignImmediateStatement 'val (make-Const 'a-procedure))
end))]) end))])
(test (machine-val (run m)) (test (machine-val (run! m))
'not-a-procedure)) 'not-a-procedure))
;; Give a primitive procedure in proc and test proc ;; Give a primitive procedure in proc and test proc
(let ([m (new-machine `(,(make-AssignImmediateStatement 'proc (make-Const (lookup-primitive '+))) (let ([m (new-machine `(,(make-AssignImmediateStatement 'proc (make-Const (lookup-primitive '+)))
@ -263,7 +263,7 @@
on-true on-true
,(make-AssignImmediateStatement 'val (make-Const 'a-procedure)) ,(make-AssignImmediateStatement 'val (make-Const 'a-procedure))
end))]) end))])
(test (machine-val (run m)) (test (machine-val (run! m))
'a-procedure)) 'a-procedure))
@ -272,7 +272,7 @@
;; AssignPrimOpStatement ;; AssignPrimOpStatement
(let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(+ - * =)))))]) (let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(+ - * =)))))])
(test (first (machine-env (run m))) (test (first (machine-env (run! m)))
(make-toplevel '(+ - * =) (make-toplevel '(+ - * =)
(list (lookup-primitive '+) (list (lookup-primitive '+)
(lookup-primitive '-) (lookup-primitive '-)
@ -282,20 +282,20 @@
(let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(some-variable))) (let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(some-variable)))
,(make-AssignImmediateStatement 'val (make-Const "Danny")) ,(make-AssignImmediateStatement 'val (make-Const "Danny"))
,(make-AssignImmediateStatement (make-EnvPrefixReference 0 0) (make-Reg 'val))))]) ,(make-AssignImmediateStatement (make-EnvPrefixReference 0 0) (make-Reg 'val))))])
(test (machine-env (run m)) (test (machine-env (run! m))
(list (make-toplevel '(some-variable) (list "Danny"))))) (list (make-toplevel '(some-variable) (list "Danny")))))
(let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(some-variable another))) (let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(some-variable another)))
,(make-AssignImmediateStatement 'val (make-Const "Danny")) ,(make-AssignImmediateStatement 'val (make-Const "Danny"))
,(make-AssignImmediateStatement (make-EnvPrefixReference 0 1) (make-Reg 'val))))]) ,(make-AssignImmediateStatement (make-EnvPrefixReference 0 1) (make-Reg 'val))))])
(test (machine-env (run m)) (test (machine-env (run! m))
(list (make-toplevel '(some-variable another) (list (make-undefined) "Danny"))))) (list (make-toplevel '(some-variable another) (list (make-undefined) "Danny")))))
(let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(some-variable))) (let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(some-variable)))
,(make-AssignImmediateStatement 'val (make-Const "Danny")) ,(make-AssignImmediateStatement 'val (make-Const "Danny"))
,(make-PushEnvironment 5 #f) ,(make-PushEnvironment 5 #f)
,(make-AssignImmediateStatement (make-EnvPrefixReference 5 0) (make-Reg 'val))))]) ,(make-AssignImmediateStatement (make-EnvPrefixReference 5 0) (make-Reg 'val))))])
(test (machine-env (run m)) (test (machine-env (run! m))
(list (make-undefined) (make-undefined) (make-undefined) (make-undefined) (make-undefined) (list (make-undefined) (make-undefined) (make-undefined) (make-undefined) (make-undefined)
(make-toplevel '(some-variable) (list "Danny"))))) (make-toplevel '(some-variable) (list "Danny")))))
@ -309,7 +309,7 @@
(with-handlers ((exn:fail? (lambda (exn) (with-handlers ((exn:fail? (lambda (exn)
(void)))) (void))))
(run m) (run! m)
(raise "I expected an error"))) (raise "I expected an error")))
;; check-toplevel-bound shouldn't fail here. ;; check-toplevel-bound shouldn't fail here.
@ -317,7 +317,7 @@
,(make-AssignImmediateStatement 'val (make-Const "Danny")) ,(make-AssignImmediateStatement 'val (make-Const "Danny"))
,(make-AssignImmediateStatement (make-EnvPrefixReference 0 0) (make-Reg 'val)) ,(make-AssignImmediateStatement (make-EnvPrefixReference 0 0) (make-Reg 'val))
,(make-PerformStatement (make-CheckToplevelBound! 0 0))))]) ,(make-PerformStatement (make-CheckToplevelBound! 0 0))))])
(void (run m))) (void (run! m)))
@ -336,7 +336,7 @@
procedure-entry)) procedure-entry))
0 0
(make-hash))]) (make-hash))])
(test (machine-env (run m)) (test (machine-env (run! m))
;; Check that the environment has installed the expected closure values. ;; Check that the environment has installed the expected closure values.
(list 1 2 3 true false))) (list 1 2 3 true false)))
@ -352,7 +352,7 @@
(list->vector `(,(make-AssignPrimOpStatement 'val (make-GetCompiledProcedureEntry)))) (list->vector `(,(make-AssignPrimOpStatement 'val (make-GetCompiledProcedureEntry))))
0 0
(make-hash))]) (make-hash))])
(test (machine-val (run m)) (test (machine-val (run! m))
'procedure-entry)) 'procedure-entry))
@ -364,7 +364,7 @@
procedure-entry procedure-entry
end end
))]) ))])
(test (machine-val (run m)) (test (machine-val (run! m))
(make-closure 'procedure-entry 0 (list) 'procedure-entry))) (make-closure 'procedure-entry 0 (list) 'procedure-entry)))
;; make-compiled-procedure: Capturing a few variables. ;; make-compiled-procedure: Capturing a few variables.
@ -382,7 +382,7 @@
procedure-entry procedure-entry
end end
))]) ))])
(test (machine-val (run m)) (test (machine-val (run! m))
(make-closure 'procedure-entry 0 (list 'larry 'moe) (make-closure 'procedure-entry 0 (list 'larry 'moe)
'procedure-entry))) 'procedure-entry)))
@ -404,7 +404,7 @@
procedure-entry procedure-entry
end end
))]) ))])
(test (machine-val (run m)) (test (machine-val (run! m))
(make-closure 'procedure-entry 0 (list (make-toplevel '(x y z) (list "x" "y" "z"))) (make-closure 'procedure-entry 0 (list (make-toplevel '(x y z) (list "x" "y" "z")))
'procedure-entry))) 'procedure-entry)))
@ -432,7 +432,7 @@
procedure-entry procedure-entry
end end
))]) ))])
(test (machine-val (run m)) (test (machine-val (run! m))
(make-closure 'procedure-entry (make-closure 'procedure-entry
0 0
(list (make-toplevel '(x y z) (list "x" "y" "z")) (list (make-toplevel '(x y z) (list "x" "y" "z"))
@ -444,7 +444,7 @@
;; Test toplevel lookup ;; Test toplevel lookup
(let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(+))) (let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(+)))
,(make-AssignImmediateStatement 'val (make-EnvPrefixReference 0 0))))]) ,(make-AssignImmediateStatement 'val (make-EnvPrefixReference 0 0))))])
(test (machine-val (run m)) (test (machine-val (run! m))
(lookup-primitive '+))) (lookup-primitive '+)))
;; Test lexical lookup ;; Test lexical lookup
@ -455,7 +455,7 @@
,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const 'moe)) ,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const 'moe))
,(make-AssignImmediateStatement 'val (make-EnvLexicalReference 0 #f))))]) ,(make-AssignImmediateStatement 'val (make-EnvLexicalReference 0 #f))))])
(test (machine-val (run m)) (test (machine-val (run! m))
'larry)) 'larry))
;; Another lexical lookup test ;; Another lexical lookup test
(let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(+))) (let ([m (new-machine `(,(make-PerformStatement (make-ExtendEnvironment/Prefix! '(+)))
@ -465,7 +465,7 @@
,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const 'moe)) ,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f) (make-Const 'moe))
,(make-AssignImmediateStatement 'val (make-EnvLexicalReference 1 #f))))]) ,(make-AssignImmediateStatement 'val (make-EnvLexicalReference 1 #f))))])
(test (machine-val (run m)) (test (machine-val (run! m))
'curly)) 'curly))
;; ApplyPrimitiveProcedure ;; ApplyPrimitiveProcedure
@ -478,10 +478,10 @@
,(make-AssignImmediateStatement 'argcount (make-Const 2)) ,(make-AssignImmediateStatement 'argcount (make-Const 2))
,(make-AssignPrimOpStatement 'val (make-ApplyPrimitiveProcedure)) ,(make-AssignPrimOpStatement 'val (make-ApplyPrimitiveProcedure))
after))]) after))])
(test (machine-val (run m)) (test (machine-val (run! m))
(+ 126389 42)) (+ 126389 42))
(test (machine-env (run m)) (test (machine-env (run! m))
(list 126389 42 (make-toplevel '(+) (list (lookup-primitive '+)))))) (list 126389 42 (make-toplevel '(+) (list (lookup-primitive '+))))))
@ -490,5 +490,35 @@
foo foo
,(make-PushControlFrame 'foo) ,(make-PushControlFrame 'foo)
,(make-AssignPrimOpStatement 'proc (make-GetControlStackLabel))))]) ,(make-AssignPrimOpStatement 'proc (make-GetControlStackLabel))))])
(test (machine-proc (run m)) (test (machine-proc (run! m))
'foo)) 'foo))
;; Splicing
(let ([m (new-machine `(,(make-PushEnvironment 1 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f)
(make-Const '(1 2 3)))
,(make-AssignImmediateStatement 'argcount (make-Const 1))
,(make-PerformStatement (make-SpliceListIntoStack! (make-Const 0)))))])
(run! m)
(test (machine-argcount m)
3)
(test (machine-env m)
'(1 2 3)))
(let ([m (new-machine `(,(make-PushEnvironment 3 #f)
,(make-AssignImmediateStatement (make-EnvLexicalReference 0 #f)
(make-Const "hello"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 1 #f)
(make-Const "world"))
,(make-AssignImmediateStatement (make-EnvLexicalReference 2 #f)
(make-Const '(1 2 3)))
,(make-AssignImmediateStatement 'argcount (make-Const 3))
,(make-PerformStatement (make-SpliceListIntoStack! (make-Const 2)))))])
(run! m)
(test (machine-argcount m)
5)
(test (machine-env m)
'("hello" "world" 1 2 3)))