lmc/machine.go

62 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]
arg := i % 100
pc++
switch i - arg {
case IHALT:
return nil
case IADD:
accumulator += code[arg]
case ISUBTRACT:
accumulator -= code[arg]
case ISTORE:
code[arg] = accumulator
case ILOAD:
accumulator = code[arg]
case IBRANCH:
pc = int(i % 100)
case IBRANCH_IF_ZERO:
if accumulator == 0 {
pc = int(arg)
}
case IBRANCH_IF_POSITIVE:
if accumulator > 0 {
pc = int(arg)
}
case IIO:
switch arg {
case IO_INPUT:
fmt.Printf("Input: ")
fmt.Scanf("%d\n", &accumulator)
case IO_OUTPUT:
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")
}