#!/usr/local/bin/tclsh if {[llength $argv] < 1} { puts stderr "usage: $argv0 programfile ?inputs ...?" exit 1 } set programfile [lindex $argv 0] set input [lrange $argv 1 end] set fd [open $programfile r] set list [split [string trimright [read $fd] \n] ,] close $fd while {[llength $list] < 16384} { lappend list 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 } set pc 0 set relbase 0 while 1 { set op [format %05d [lindex $list $pc]] set mode1 [string index $op 2] set mode2 [string index $op 1] set mode3 [string index $op 0] set i [expr {$pc + 1}] set j [expr {$pc + 2}] set k [expr {$pc + 3}] switch -- $mode1 { 0 {set a [lindex $list [lindex $list $i]]} 1 {set a [lindex $list $i]} 2 {set a [lindex $list [expr {$relbase + [lindex $list $i]}]]} } switch -- $mode2 { 0 {set b [lindex $list [lindex $list $j]]} 1 {set b [lindex $list $j]} 2 {set b [lindex $list [expr {$relbase + [lindex $list $j]}]]} } switch -- $mode3 { 0 {set store [lindex $list $k]} 2 {set store [expr {$relbase + [lindex $list $k]}]} } switch -glob -- $op { *01 { lset list $store [expr {$a + $b}] incr pc 4 } *02 { lset list $store [expr {$a * $b}] incr pc 4 } *03 { if {[llength $input] == 0} { gets stdin line foreach c [split $line ""] { scan $c %c ascii lappend input $ascii } lappend input 10 } if {$mode1 == 0} { lset list [lindex $list $i] [lindex $input 0] } else { lset list [expr {$relbase+[lindex $list $i]}] [lindex $input 0] } set input [lrange $input 1 end] incr pc 2 } *04 { puts -nonewline [format %c $a] incr pc 2 } *05 { if {$a != 0} { set pc $b } else { incr pc 3 } } *06 { if {$a == 0} { set pc $b } else { incr pc 3 } } *07 { lset list $store [expr {$a < $b}] incr pc 4 } *08 { lset list $store [expr {$a == $b}] incr pc 4 } *09 { incr relbase $a incr pc 2 } *99 break } }