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") }