# -*- tcl -*- me_cpucore.test # ### ### ### ######### ######### ######### # ### ### ### ######### ######### ######### ## Assembler test me-cpucore-asm-${impl}-1.0 {asm, wrong args} -body { grammar::me::cpu::core::asm } -result {wrong # args: should be "grammar::me::cpu::core::asm code"} \ -returnCodes error test me-cpucore-asm-${impl}-1.1 {asm, wrong args} -body { grammar::me::cpu::core::asm a b } -result {wrong # args: should be "grammar::me::cpu::core::asm code"} \ -returnCodes error test me-cpucore-asm-${impl}-2.0 {asm, empty} -body { grammar::me::cpu::core::asm {} # No instructions, empty string pool, no token map } -result {{} {} {}} set n -1 foreach {cmd cargs expected} $asm_table { set asm [list [linsert $cargs 0 branchlabel $cmd]] incr n test me-cpucore-asm-${impl}-3.$n "asm, $cmd" -body { canon_code [grammar::me::cpu::core::asm $asm] } -result $expected } set n -1 foreach {cmd cargs expected} $badasm_table { set asm [list [linsert $cargs 0 branchlabel $cmd]] incr n test me-cpucore-asm-${impl}-4.$n "asm, bad $cmd" -body { grammar::me::cpu::core::asm $asm } -result $expected -returnCodes error } # ### ### ### ######### ######### ######### ## Disassembler test me-cpucore-disasm-${impl}-1.0 {disasm, wrong args} -body { grammar::me::cpu::core::disasm } -result {wrong # args: should be "grammar::me::cpu::core::disasm code"} \ -returnCodes error test me-cpucore-disasm-${impl}-1.1 {disasm, wrong args} -body { grammar::me::cpu::core::disasm a b } -result {wrong # args: should be "grammar::me::cpu::core::disasm code"} \ -returnCodes error test me-cpucore-disasm-${impl}-2.0 {disasm, empty} -body { # No instructions, empty string pool, no token map grammar::me::cpu::core::disasm {{} {} {}} } -result {} set n -1 foreach {cmd cargs code} $asm_table { set asm [list [linsert $cargs 0 branchlabel $cmd]] incr n # We have to distinguish between regular instructions and # instruction jumping somewhere. For the latter we have to perform # a bit of fixup to get our expections of the branch labeling # right. set pos [lsearch -exact $cargs branchlabel] if {$pos >= 0} { set expected [list [linsert [lreplace $cargs $pos $pos bra0] 0 bra0 $cmd]] } else { set expected [list [linsert $cargs 0 {} $cmd]] } test me-cpucore-disasm-${impl}-3.$n "disasm, $cmd" -body { grammar::me::cpu::core::disasm $code } -result $expected } set n -1 foreach {insns expected} $badmach_table { incr n test me-cpucore-disasm-${impl}-4.$n "disasm, error" -body { grammar::me::cpu::core::disasm $insns } -result $expected -returnCodes error } # ### ### ### ######### ######### ######### ## State creation. test me-cpucore-new-${impl}-1.0 {new, wrong args} -body { grammar::me::cpu::core::new } -result {wrong # args: should be "grammar::me::cpu::core::new code"} \ -returnCodes error test me-cpucore-new-${impl}-1.1 {new, wrong args} -body { grammar::me::cpu::core::new a b } -result {wrong # args: should be "grammar::me::cpu::core::new code"} \ -returnCodes error test me-cpucore-run-${impl}-2.0 run -setup { set state [grammar::me::cpu::core::new {{} {} {}}] } -returnCodes error -body { grammar::me::cpu::core::run state } -result {No instructions to execute} set n -1 foreach {cmd cargs expected} $asm_table { set asm [list [linsert $cargs 0 branchlabel $cmd]] incr n test me-cpucore-new-${impl}-3.$n "new, $cmd, code" -body { grammar::me::cpu::core::code \ [grammar::me::cpu::core::new \ [canon_code [grammar::me::cpu::core::asm $asm]]] } -result $expected test me-cpucore-new-${impl}-4.$n "new, $cmd, state" -body { cpusubst [cpustate \ [grammar::me::cpu::core::new \ [canon_code [grammar::me::cpu::core::asm $asm]]]] \ cd {} } -result {cd {} pc 0 ht 0 eo 0 tc {} at -1 cc {} ok 0 sv {} er {} ls {} as {} ms {} es {} rs {} nc {}} } set n -1 foreach {insns expected} $badmach_table { incr n test me-cpucore-new-${impl}-5.$n "new error" -body { grammar::me::cpu::core::new $insns } -result $expected -returnCodes error } # ### ### ### ######### ######### ######### ## State manipulation - Add tokens test me-cpucore-put-${impl}-1.0 {put, wrong args} -body { grammar::me::cpu::core::put } -result {wrong # args: should be "grammar::me::cpu::core::put statevar tok lex line col"} \ -returnCodes error test me-cpucore-put-${impl}-1.1 {put, wrong args} -body { grammar::me::cpu::core::put a } -result {wrong # args: should be "grammar::me::cpu::core::put statevar tok lex line col"} \ -returnCodes error test me-cpucore-put-${impl}-1.2 {put, wrong args} -body { grammar::me::cpu::core::put a b } -result {wrong # args: should be "grammar::me::cpu::core::put statevar tok lex line col"} \ -returnCodes error test me-cpucore-put-${impl}-1.3 {put, wrong args} -body { grammar::me::cpu::core::put a b c } -result {wrong # args: should be "grammar::me::cpu::core::put statevar tok lex line col"} \ -returnCodes error test me-cpucore-put-${impl}-1.4 {put, wrong args} -body { grammar::me::cpu::core::put a b c d } -result {wrong # args: should be "grammar::me::cpu::core::put statevar tok lex line col"} \ -returnCodes error test me-cpucore-put-${impl}-1.5 {put, wrong args} -body { grammar::me::cpu::core::put a b c d e f } -result {wrong # args: should be "grammar::me::cpu::core::put statevar tok lex line col"} \ -returnCodes error test me-cpucore-put-${impl}-2.0 put -setup { set base [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] set next $base } -body { grammar::me::cpu::core::put next ID ident 1 0 grammar::me::cpu::core::put next NUM 12345 1 5 cpudelta $base $next } -result {tc {{ID ident 1 0} {NUM 12345 1 5}}} test me-cpucore-put-${impl}-3.0 {put after eof} -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::eof state } -returnCodes error -body { grammar::me::cpu::core::put state ID ident 1 0 } -result {Cannot add input data after eof} # ### ### ### ######### ######### ######### ## State manipulation - Set eof test me-cpucore-eof-${impl}-1.0 {eof, wrong args} -body { grammar::me::cpu::core::eof } -result {wrong # args: should be "grammar::me::cpu::core::eof statevar"} \ -returnCodes error test me-cpucore-eof-${impl}-1.1 {eof, wrong args} -body { grammar::me::cpu::core::eof a b } -result {wrong # args: should be "grammar::me::cpu::core::eof statevar"} \ -returnCodes error test me-cpucore-eof-${impl}-2.0 eof -setup { set base [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] set next $base } -body { grammar::me::cpu::core::eof next cpudelta $base $next } -result {eo 1} # ### ### ### ######### ######### ######### ## State accessors - line/col retrieval test me-cpucore-lc-${impl}-1.0 {lc, wrong args} -body { grammar::me::cpu::core::lc } -result {wrong # args: should be "grammar::me::cpu::core::lc state loc"} \ -returnCodes error test me-cpucore-lc-${impl}-1.1 {lc, wrong args} -body { grammar::me::cpu::core::lc a } -result {wrong # args: should be "grammar::me::cpu::core::lc state loc"} \ -returnCodes error test me-cpucore-lc-${impl}-1.2 {lc, wrong args} -body { grammar::me::cpu::core::lc a b c } -result {wrong # args: should be "grammar::me::cpu::core::lc state loc"} \ -returnCodes error test me-cpucore-lc-${impl}-2.0 lc -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::lc $state 0 } -result {1 5} test me-cpucore-lc-${impl}-3.0 {lc, bad index} -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::lc $state -1 } -result {Illegal location -1} -returnCodes error test me-cpucore-lc-${impl}-3.1 {lc, bad index} -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::lc $state 1 } -result {Illegal location 1} -returnCodes error test me-cpucore-lc-${impl}-3.2 {lc, bad index} -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] } -body { grammar::me::cpu::core::lc $state 0 } -result {Illegal location 0} -returnCodes error # ### ### ### ######### ######### ######### ## State accessors - Token retrieval test me-cpucore-tok-${impl}-1.0 {tok, wrong args} -body { grammar::me::cpu::core::tok } -result [tcltest::wrongNumArgs grammar::me::cpu::core::tok {state args} 0] \ -returnCodes error test me-cpucore-tok-${impl}-1.1 {tok, wrong args} -body { grammar::me::cpu::core::tok a b c d } -result {wrong # args: should be "grammar::me::cpu::core::tok state ?from ?to??"} \ -returnCodes error test me-cpucore-tok-${impl}-2.0 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] } -body { grammar::me::cpu::core::tok $state } -result {} test me-cpucore-tok-${impl}-2.1 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state } -result {{NUM 12345 1 5}} test me-cpucore-tok-${impl}-2.2 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state ID lalal 0 0 grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state } -result {{ID lalal 0 0} {NUM 12345 1 5}} test me-cpucore-tok-${impl}-3.0 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] } -body { grammar::me::cpu::core::tok $state 0 } -result {Illegal location 0} -returnCodes error test me-cpucore-tok-${impl}-3.1 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state -1 } -result {Illegal location -1} -returnCodes error test me-cpucore-tok-${impl}-3.2 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state 1 } -result {Illegal location 1} -returnCodes error test me-cpucore-tok-${impl}-3.3 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state 0 } -result {{NUM 12345 1 5}} test me-cpucore-tok-${impl}-3.4 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state ID lalal 0 0 grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state 0 } -result {{ID lalal 0 0}} test me-cpucore-tok-${impl}-4.0 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state -1 0 } -result {Illegal start location -1} -returnCodes error test me-cpucore-tok-${impl}-4.1 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state 1 0 } -result {Illegal start location 1} -returnCodes error test me-cpucore-tok-${impl}-4.2 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state 0 -1 } -result {Illegal end location -1} -returnCodes error test me-cpucore-tok-${impl}-4.3 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state 0 1 } -result {Illegal end location 1} -returnCodes error test me-cpucore-tok-${impl}-4.4 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state ID lalal 0 0 grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state 1 0 } -result {Illegal empty location range 1 .. 0} -returnCodes error test me-cpucore-tok-${impl}-4.5 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state ID lalal 0 0 grammar::me::cpu::core::put state NUM 12345 1 5 } -body { grammar::me::cpu::core::tok $state 0 1 } -result {{ID lalal 0 0} {NUM 12345 1 5}} test me-cpucore-tok-${impl}-4.6 tok -setup { set state [grammar::me::cpu::core::new [canon_code [grammar::me::cpu::core::asm {}]]] grammar::me::cpu::core::put state ID lalal 0 0 grammar::me::cpu::core::put state ID lalal 0 0 } -body { grammar::me::cpu::core::tok $state 0 0 } -result {{ID lalal 0 0}} # ### ### ### ######### ######### ######### ## Checking the instruction semantics test me-cpucore-run-${impl}-1.0 {run, wrong args} -body { grammar::me::cpu::core::run } -result {wrong # args: should be "grammar::me::cpu::core::run statevar ?steps?"} \ -returnCodes error test me-cpucore-run-${impl}-1.1 {run, wrong args} -body { grammar::me::cpu::core::run a b c } -result {wrong # args: should be "grammar::me::cpu::core::run statevar ?steps?"} \ -returnCodes error set n -1 foreach {description input eof stepsSetup steps code expectedDelta} $semantics { incr n if 0 { puts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ puts $description puts "INPUT $input" puts "EOF $eof" puts "CODE $stepsSetup $steps $code" puts $expectedDelta } test me-cpucore-run-${impl}-2.$n "run $description" -setup { set state [grammar::me::cpu::core::new $code] foreach token $input { eval [linsert $token 0 grammar::me::cpu::core::put state] } if {$eof} { grammar::me::cpu::core::eof state } if {$stepsSetup} { grammar::me::cpu::core::run state $stepsSetup } set save $state } -body { grammar::me::cpu::core::run state $steps cpudelta $save $state } -result $expectedDelta } return