package interpreter import "fmt" type Interpreter struct { program []int instructionPointer int } func Init(program []int) *Interpreter { return &Interpreter { program: program, instructionPointer: 0, } } func (i *Interpreter) Next() bool { opcode := i.getValueAtIndex(i.instructionPointer) ipIncrement := 1 switch opcode { case 1: i.add() ipIncrement = 4 case 2: i.mul() ipIncrement = 4 case 99: return true default: panic(fmt.Sprintf("unhandled opcode %v at IP %v", opcode, i.instructionPointer)) } i.instructionPointer += ipIncrement return false } func (i *Interpreter) getValueAtIndex(index int) int { return i.program[index] } func (i *Interpreter) setValueAtIndex(index, value int) { i.program[index] = value } func (i *Interpreter) add() { resIndex := i.getValueAtIndex(i.instructionPointer + 3) arg1Index := i.getValueAtIndex(i.instructionPointer + 1) arg2Index := i.getValueAtIndex(i.instructionPointer + 2) i.setValueAtIndex(resIndex, i.getValueAtIndex(arg1Index) + i.getValueAtIndex(arg2Index)) } func (i *Interpreter) mul() { resIndex := i.getValueAtIndex(i.instructionPointer + 3) arg1Index := i.getValueAtIndex(i.instructionPointer + 1) arg2Index := i.getValueAtIndex(i.instructionPointer + 2) i.setValueAtIndex(resIndex, i.getValueAtIndex(arg1Index) * i.getValueAtIndex(arg2Index)) }