From be89ec9f0f7b3948e33e523e89eec8c45baee1c8 Mon Sep 17 00:00:00 2001 From: dyoo Date: Thu, 3 Mar 2011 16:58:09 -0500 Subject: [PATCH] testing goto in the simulator --- il-structs.rkt | 1 + simulator-structs.rkt | 6 ++++-- simulator.rkt | 35 ++++++++++++++++++++++++++++++++--- test-simulator.rkt | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 test-simulator.rkt diff --git a/il-structs.rkt b/il-structs.rkt index 385debc..ad40525 100644 --- a/il-structs.rkt +++ b/il-structs.rkt @@ -11,6 +11,7 @@ (define-type AtomicRegisterSymbol (U 'val 'proc)) (define-type RegisterSymbol (U StackRegisterSymbol AtomicRegisterSymbol)) +(define-predicate AtomicRegisterSymbol? AtomicRegisterSymbol) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/simulator-structs.rkt b/simulator-structs.rkt index dd98d8a..3720819 100644 --- a/simulator-structs.rkt +++ b/simulator-structs.rkt @@ -12,9 +12,11 @@ [pc : Natural] ;; program counter [text : (Vectorof Statement)] ;; text of the program - )) + ) + #:transparent) -(define-struct: frame ([return : Symbol])) +(define-struct: frame ([return : Symbol]) + #:transparent) diff --git a/simulator.rkt b/simulator.rkt index eb59843..fba079a 100644 --- a/simulator.rkt +++ b/simulator.rkt @@ -16,11 +16,14 @@ (: can-step? (machine -> Boolean)) +;; Produces true if we can make a further step in the simulation. (define (can-step? m) - #t) + (< (machine-pc m) + (vector-length (machine-text m)))) (: step (machine -> machine)) +;; Take one simulation step. (define (step m) (let: ([i : Statement (current-instruction m)]) (cond @@ -33,7 +36,7 @@ [(PerformStatement? i) (error 'step)] [(GotoStatement? i) - (error 'step)] + (step-goto m i)] [(TestAndBranchStatement? i) (error 'step)] [(PopEnvironment? i) @@ -46,8 +49,33 @@ (error 'step)]))) +(: step-goto (machine GotoStatement -> machine)) +(define (step-goto m a-goto) + (let: ([t : (U Label Reg) (GotoStatement-target a-goto)]) + (cond [(Label? t) + (jump m (Label-name t))] + [(Reg? t) + (let: ([reg : RegisterSymbol (Reg-name t)]) + (cond [(AtomicRegisterSymbol? reg) + (cond [(eq? reg 'val) + (jump m (ensure-symbol (machine-val m)))] + [(eq? reg 'proc) + (jump m (ensure-symbol (machine-proc m)))])] + [else + (error 'step-goto "Register '~s is supposed to be either 'val or 'proc" + reg)]))]))) +(: ensure-symbol (Any -> Symbol)) +;; Make sure the value is a symbol. +(define (ensure-symbol v) + (cond + [(symbol? v) + v] + [else + (error 'ensure-symbol)])) + + (: current-instruction (machine -> Statement)) (define (current-instruction m) @@ -128,10 +156,11 @@ (: jump (machine Symbol -> machine)) +;; Jumps directly to the instruction right after the given label. (define (jump m l) (match m [(struct machine (val proc env control pc text)) - (make-machine val proc env control (vector-find text l) text)])) + (make-machine val proc env control (add1 (vector-find text l)) text)])) (: vector-find (All (A) (Vectorof A) A -> Natural)) diff --git a/test-simulator.rkt b/test-simulator.rkt new file mode 100644 index 0000000..137bc8a --- /dev/null +++ b/test-simulator.rkt @@ -0,0 +1,34 @@ +#lang racket + +(require "il-structs.rkt" + "simulator-structs.rkt" + "simulator.rkt") + + +(define-syntax (test stx) + (syntax-case stx () + [(_ actual exp) + (with-syntax ([stx stx]) + (syntax/loc #'stx + (let ([results actual]) + (unless (equal? actual exp) + (raise-syntax-error #f (format "Expected ~s, got ~s" exp results) + #'stx)))))])) + + +;; take n steps in evaluating the machine. +(define (step-n m n) + (cond + [(= n 0) + m] + [else + (step-n (step m) (sub1 n))])) + + +(let ([m (new-machine `(hello world ,(make-GotoStatement (make-Label 'hello))))]) + (test (machine-pc (step-n m 0)) 0) + (test (machine-pc (step-n m 1)) 1) + (test (machine-pc (step-n m 2)) 2) + (test (machine-pc (step-n m 3)) 1) + (test (machine-pc (step-n m 4)) 2) + (test (machine-pc (step-n m 5)) 1)) \ No newline at end of file