diff options
Diffstat (limited to 'tests/assemble.test')
-rw-r--r-- | tests/assemble.test | 516 |
1 files changed, 516 insertions, 0 deletions
diff --git a/tests/assemble.test b/tests/assemble.test new file mode 100644 index 0000000..d0cbdaa --- /dev/null +++ b/tests/assemble.test @@ -0,0 +1,516 @@ +# Commands covered: assemble + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest 2.2 + namespace import -force ::tcltest::* +} +set assemble tcl::unsupported::assemble + +test assemble-1.1 {wrong # args} { + -body { $assemble 1 2 } + -result {wrong # args: should be "tcl::unsupported::assemble bytecodeList"} + -returnCodes error +} + +test assemble-1.2 {wrong arg formatting} { + -body { $assemble 1 } + -match glob + -returnCodes error + -result {bad instruction "1"*} +} + +test assemble-1.3 {empty body} { + -body { $assemble "" } + -result {} +} + +test assemble-1.4 {empty body} { + -body { + proc x y { + tcl::unsupported::assemble "" + } + x 1} + -result {} +} + +test assemble-1.5 {Testing push and add} { + -body { tcl::unsupported::assemble {{push 2} {push 2} {add}} } + -result {4} +} + +test assemble-1.6 {Testing push, dup, add} { + -body { tcl::unsupported::assemble {{push 2} {dup} {add}} } + -result {4} +} + +test assemble-1.6a {wrong # args} { + -body { + catch { + tcl::unsupported::assemble {{push 2 2} {dup} {add}} + } + set ::errorInfo + } + -match glob + -result {wrong # args: should be "push value" + processing source instruction at list index 0 ("push 2 2")*} +} + +test assemble-1.7 { Testing push, dup, mul, push, dup, mult, push, expon sequence } { + -body { tcl::unsupported::assemble {{push 3} dup mult {push 4} dup mult expon}} + -result {1853020188851841} +} + +test assemble-1.8 { Testing push, dup, mul, push, dup, mult, push, expon, pop sequence with unbalanced stack } {*}{ + -body { + list \ + [catch { + tcl::unsupported::assemble { + {push 3} + dup + mult + {push 4} + dup + mult + pop + expon} + } result] $result $::errorInfo + } + -result {1 {stack underflow} {stack underflow + between source instruction at list index 0 ("push 3") + and end of assembly code*}} + -match glob + -returnCodes ok +} +test assemble-1.8a {unbalanced stack} {*}{ + -body { + list \ + [catch { + tcl::unsupported::assemble { + {label a} + {pop} + {label b} + {pop} + } + } result] $result $::errorInfo + } + -result {1 {stack underflow} {stack underflow + between source instruction at list index 0 ("label a") + and source instruction at list index 2 ("label b")*}} + -match glob + -returnCodes ok +} + +# Tests for load and store + +test assemble-1.9 { Testing load within a proc } { + -body { proc x y { tcl::unsupported::assemble {{load y} dup mult }} + x 10 + } + -result {100} +} + +test assemble-1.10 { Testing store and load, saving the string "aString" to a variable and then + loading it from variable } { + -body { + proc x arg { + tcl::unsupported::assemble { + {push aString} {store arg} {pop} {load arg}} + } + x "not_aString" + } + -result {aString} + } + +test assemble-1.11 { Testing storeArray and loadArray } { + -body { set anArray(1,2) "not_aString" + proc x arg { + upvar $arg anArray + tcl::unsupported::assemble { + {push 1,2} + {push aString} + {storeArray anArray} + pop + {push 1,2} + {loadArray anArray} + } + } + x anArray + } + -cleanup {unset anArray} + -result {aString} +} + +test assemble-1.12 { Testing loadStk with a variable } { + -body { set vara 10 + tcl::unsupported::assemble {{push vara} loadStk dup mult {push 4} dup mult add}} + -cleanup {unset vara} + -result {116} +} + +test assemble-1.13 { Testing loadStk with an array variable } { + -body { set vararr(1,2) 10 + tcl::unsupported::assemble {{push vararr(1,2)} loadStk dup mult {push 4} dup mult add}} + -cleanup {unset vararr} + -result {116} +} + + +test assemble-1.14 { Testing loadStk and storeStk } { + -body { + set aVar 5 + tcl::unsupported::assemble { + {push aVar} + {push aString} + {storeStk} + pop + {push aVar} + loadStk + } + } + -cleanup {unset aVar} + -result {aString} +} + +test assemble-1.15 { Testing loadArrayStk and storeArrayStk } { + -body { + set aVar(1,2) 5 + tcl::unsupported::assemble { + {push aVar} + {push 1,2} + {push aString} + {storeArrayStk} + pop + {push aVar} + {push 1,2} + loadArrayStk + } + } + -cleanup {unset aVar} + -result {aString} +} + +# Tests for incr instructions + +test assemble-1.16 { Testing incr } { + -body { proc x arg { set i 5 + tcl::unsupported::assemble {{push 5} {incr i}} + } + x 1 + } + -result {10} +} + +test assemble-1.17 { Testing incrImm } { + -body { proc x arg { set i 5 + tcl::unsupported::assemble {{incrImm i 5}} + } + x 1 + } + -result {10} +} + +test assemble-1.18 { Testing incrStk } { + -body { proc x arg { set i 5 + tcl::unsupported::assemble {{push i} {push 5} {incrStk}} + } + x 1 + } + -result {10} +} + +test assemble-1.19 { Testing incrStkImm } { + -body { proc x arg { set i 5 + tcl::unsupported::assemble {{push i} {incrStkImm 5}} + } + x 1 + } + -result {10} +} + +test assemble-1.20 { Testing incrStkImm } { + -body { proc x arg { set i 5 + tcl::unsupported::assemble {{push i} {incrStkImm 5}} + } + x 1 + } + -result {10} +} + +test assemble-1.21 { Testing incrArray } { + -body { proc x arg { set i(1,2) 5 + tcl::unsupported::assemble {{push 1,2} {push 5} {incrArray i}} + } + x 1 + } + -result {10} +} + +test assemble-1.22 { Testing incrArrayImm } { + -body { proc x arg { set i(1,2) 5 + tcl::unsupported::assemble {{push 1,2} {incrArrayImm i 5}} + } + x 1 + } + -result {10} +} + +test assemble-1.23 { Testing incrArrayStk } { + -body { proc x arg { set i(1,2) 5 + tcl::unsupported::assemble {{push i} {push 1,2} {push 5} {incrArrayStk}} + } + x 1 + } + -result {10} +} + +test assemble-1.24 { Testing incrArrayStkImm } { + -body { proc x arg { set i(1,2) 5 + tcl::unsupported::assemble {{push i} {push 1,2} {incrArrayStkImm 5}} + } + x 1 + } + -result {10} +} + +# Tests for STRs -NOT HERE YET +# Tests for LIST BYTECODES -NOT HERE YET + +# Tests for label and jump {push NotEqual} + +test assemble-1.25 { Testing label and jumpTrue } { + -body { + proc x {arg1 arg2} { tcl::unsupported::assemble {{label a} {load arg2} + {push 2} {mult} {store arg2} pop {load arg1} {push 1} {sub} {store arg1} + {push 0} {neq} {jumpTrue a} {load arg2}}} + x 4 2 + } + -result {32} +} + +test assemble-1.26 { Testing label and jumpFalse } { + -body { + proc x {arg1 arg2} { tcl::unsupported::assemble {{label a} {load arg2} + {push 2} {mult} {store arg2} pop {load arg1} {push 1} {sub} {store arg1} + {push 0} {eq} {jumpFalse a} {load arg2}}} + x 4 2 + } + -result {32} +} + +test assemble-1.27 { Testing trampoline undefined label and jump } { + -body { + proc x {arg1 arg2 arg3} { tcl::unsupported::assemble {{jump a} {push aString} + {store arg1} pop {label a} {jump b} {push aString} {store arg2} {label b} {jump c} + {push aString} {store arg3} {label c} {load arg1} }} + x 1 2 3 + } + -result {1} +} + +test assemble-1.28 { Testing trampoline undefined label and jump } { + -body { + proc x {arg1 arg2 arg3} { tcl::unsupported::assemble {{jump a} {push aString} + {store arg1} pop {label a} {jump b} {push aString} {store arg2} {label b} {jump c} + {push aString} {store arg3} {label c} {load arg2} }} + x 1 2 3 + } + -result {2} +} + +test assemble-1.29 { Testing trampoline undefined label and jump } { + -body { + proc x {arg1 arg2 arg3} { tcl::unsupported::assemble {{jump a} {push aString} + {store arg1} pop {label a} {jump b} {push aString} {store arg2} {label b} {jump c} + {push aString} {store arg3} {label c} {load arg3} }} + x 1 2 3 + } + -result {3} +} + +test assemble-1.30 {Inconsistent stack usage} {*}{ + -body { + proc x {y} { + tcl::unsupported::assemble { + {load y} + {jumpFalse else} + {push 0} + {jump then} + {label else} + {push 1} + {push 2} + {label then} + pop + } + } + catch {x 1} + set errorInfo + } + -match glob + -result {inconsistent stack depths on two execution paths + to source instruction at list index 7 ("label then")*} +} + +test assemble-1.31 {unset, exists, lappend - smoke test} { + -body { + proc x {y} { + tcl::unsupported::assemble { + {exist result} + {store result} + {pop} + + {exist result} + {lappend result} + {pop} + + {push result} + {push y} + {existStk} + {lappendStk} + {pop} + + {push y} + {unsetStk true} + {exist y} + {lappend result} + {pop} + + {push {}} + {store foo} + {pop} + {exist foo} + {lappend result} + {pop} + + {unset true foo} + {exist foo} + {lappend result} + {pop} + + {push a} + {existArray z} + {lappend result} + {pop} + + {push a} + {push b} + {lappendArray z} + {lappend result} + {pop} + + {push z} + {push a} + {existArrayStk} + {lappend result} + {pop} + + {push z} + {push a} + {push c} + {lappendArrayStk} + {lappend result} + + } + } + x 1 + } + -result {0 1 1 0 1 0 0 b 1 {b c}} +} + +test assemble-2.1 {concat} { + -body { + ::tcl::unsupported::assemble { + {push a} + {push b} + {push c} + {concat 3} + } + } + -result abc +} + +test assemble-3.1 {expr} { + -body { + ::tcl::unsupported::assemble { + {push {1+2+3+4+5}} + {exprStk} + } + } + -result 15 +} +test assemble-4.1 {eval} { + -body { + ::tcl::unsupported::assemble { + {push {join [list [expr {1+2+3+4+5}] a] {}}} + {evalStk} + } + } + -result 15a +} +set ::tcl_traceCompile 2 +test assemble-4.2 {eval} { + -body { + proc x {} { + ::tcl::unsupported::assemble { + {push 3} + {store n} + pop + {eval {expr {3*$n + 1}}} + } + } + x + } + -result 10 +} +set ::tcl_traceCompile 0 + +test assemble-30.1 {Ulam's 3n+1 problem, TAL implementation} { + -body { + regsub -all {\#[^\n]*} { + {load n} # max + {dup} # max n + {jump start} # max n + + {label loop} # max n + {over 1} # max n max + {over 1} # max n max n + {ge} # man n max>=n + {jumpTrue skip} # max n + + {reverse 2} # n max + {pop} # n + {dup} # n n + + {label skip} # max n + {dup} # max n n + {push 2} # max n n 2 + {mod} # max n n%2 + {jumpTrue odd} # max n + + {push 2} # max n 2 + {div} # max n/2 -> max n + {jump start} # max n + + {label odd} # max n + {push 3} # max n 3 + {mult} # max 3*n + {push 1} # max 3*n 1 + {add} # max 3*n+1 + + {label start} # max n + {dup} # max n n + {push 1} # max n n 1 + {neq} # max n n>1 + {jumpTrue loop} # max n + + {pop} # max + + } {} code + proc ulam n [list tcl::unsupported::assemble $code] + set result {} + for {set i 1} {$i < 30} {incr i} { + lappend result [ulam $i] + } + set result + } + -result {1 2 16 4 16 16 52 8 52 16 52 16 40 52 160 16 52 52 88 20 64 52 160 24 88 40 9232 52 88} +}
\ No newline at end of file |