diff --git a/simulator.rkt b/simulator.rkt index b4bec13..126a95b 100644 --- a/simulator.rkt +++ b/simulator.rkt @@ -41,7 +41,7 @@ [(TestAndBranchStatement? i) (error 'step)] [(PopEnvironment? i) - (error 'step)] + (step-pop-environment m i)] [(PushEnvironment? i) (step-push-environment m i)] [(PushControlFrame? i) @@ -89,8 +89,16 @@ (loop (env-push m (void)) (sub1 n))]))) +(: step-pop-environment (machine PopEnvironment -> machine)) +(define (step-pop-environment machine stmt) + (env-pop machine + (PopEnvironment-n stmt) + (PopEnvironment-skip stmt))) -;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (: evaluate-oparg (machine OpArg -> Any)) diff --git a/test-simulator.rkt b/test-simulator.rkt index 82bdcdc..db48d7f 100644 --- a/test-simulator.rkt +++ b/test-simulator.rkt @@ -79,3 +79,42 @@ ,(make-AssignImmediateStatement (make-EnvLexicalReference 0) (make-Const 42))))] [m (run m)]) (test (machine-env m) `(42 ,(void)))) + + +;; PushEnv +(let ([m (new-machine `(,(make-PushEnvironment 20)))]) + (test (machine-env (run m)) (build-list 20 (lambda (i) (void))))) + + +;; PopEnv +(let ([m (new-machine `(,(make-PushEnvironment 20) + ,(make-PopEnvironment 20 0)))]) + (test (machine-env (run m)) '())) + +(let* ([m (new-machine `(,(make-PushEnvironment 3) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 0) (make-Const "hewie")) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 1) (make-Const "dewey")) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 2) (make-Const "louie")) + ,(make-PopEnvironment 1 0)))]) + (test (machine-env (run m)) '("dewey" "louie"))) + +(let* ([m (new-machine `(,(make-PushEnvironment 3) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 0) (make-Const "hewie")) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 1) (make-Const "dewey")) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 2) (make-Const "louie")) + ,(make-PopEnvironment 1 1)))]) + (test (machine-env (run m)) '("hewie" "louie"))) + +(let* ([m (new-machine `(,(make-PushEnvironment 3) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 0) (make-Const "hewie")) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 1) (make-Const "dewey")) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 2) (make-Const "louie")) + ,(make-PopEnvironment 1 2)))]) + (test (machine-env (run m)) '("hewie" "dewey"))) + +(let* ([m (new-machine `(,(make-PushEnvironment 3) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 0) (make-Const "hewie")) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 1) (make-Const "dewey")) + ,(make-AssignImmediateStatement (make-EnvLexicalReference 2) (make-Const "louie")) + ,(make-PopEnvironment 2 1)))]) + (test (machine-env (run m)) '("hewie")))