60 lines
1.1 KiB
Go
60 lines
1.1 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
func Run(code []int16) error {
|
|
if len(code) != 100 {
|
|
return errors.New("Code must be exactly 100 mailboxes long")
|
|
}
|
|
|
|
// for i, x := range code {
|
|
// fmt.Printf("%d: %d\n", i, x)
|
|
// }
|
|
// fmt.Println()
|
|
|
|
var accumulator int16 = 0
|
|
|
|
pc := 0
|
|
for pc >= 0 && pc < len(code) {
|
|
i := code[pc]
|
|
pc++
|
|
switch i / 100 {
|
|
case IHALT:
|
|
return nil
|
|
case IADD:
|
|
accumulator += code[i%100]
|
|
case ISUBTRACT:
|
|
accumulator -= code[i%100]
|
|
case ISTORE:
|
|
code[i%100] = accumulator
|
|
case ILOAD:
|
|
accumulator = code[i%100]
|
|
case IBRANCH:
|
|
pc = int(i % 100)
|
|
case IBRANCH_IF_ZERO:
|
|
if accumulator == 0 {
|
|
pc = int(i % 100)
|
|
}
|
|
case IBRANCH_IF_POSITIVE:
|
|
if accumulator > 0 {
|
|
pc = int(i % 100)
|
|
}
|
|
default:
|
|
switch i {
|
|
case 901:
|
|
fmt.Printf("Input: ")
|
|
fmt.Scanf("%d\n", &accumulator)
|
|
case 902:
|
|
fmt.Printf("Output: %d\n", accumulator)
|
|
default:
|
|
e := fmt.Sprintf("Unsupported instruction %d at %d", i, pc)
|
|
return errors.New(e)
|
|
}
|
|
}
|
|
}
|
|
return errors.New("Program counter ran away")
|
|
}
|