diff --git a/elm.go b/elm.go index 08ae766..f08101e 100644 --- a/elm.go +++ b/elm.go @@ -14,15 +14,18 @@ const ( HALT Operation = 0 PUSH Operation = 1 ADD Operation = 2 + SUB Operation = 3 + MUL Operation = 4 + DIV Operation = 5 ) -type Instruction struct { +type Inst struct { Operation Operation Operand int } type Machine struct { - program []Instruction + program []Inst stack []int ip int sp int @@ -31,7 +34,7 @@ type Machine struct { func Constructor() *Machine { m := Machine{} - m.program = make([]Instruction, 0) + m.program = make([]Inst, 0) m.stack = make([]int, STACK_SIZE) m.ip = 0 m.sp = 0 @@ -40,7 +43,7 @@ func Constructor() *Machine { return &m } -func (m* Machine) Push(i Instruction) error { +func (m* Machine) Push(i Inst) error { m.program = append(m.program, i) return nil } @@ -49,28 +52,58 @@ func (m* Machine) Execute() error { instr := m.program[m.ip] switch op := instr.Operation; op { case HALT: - m.isHalted = true; + m.isHalted = true case PUSH: + if (m.sp >= STACK_SIZE) { + return errors.New("Stack Overflow"); + } + m.stack[m.sp] = instr.Operand - m.sp++; - m.ip++; + m.sp++ + m.ip++ case ADD: if (len(m.stack) < 2) { return errors.New("Stack size is less than required to execute ADD") } - m.sp--; - first := m.stack[m.sp] - m.stack[m.sp] = 0; - m.stack[m.sp - 1] = first + m.stack[m.sp - 1]; - m.ip++; + m.stack[m.sp - 2] += m.stack[m.sp - 1]; + m.sp-- + m.ip++ + case SUB: + if (len(m.stack) < 2) { + return errors.New("Stack size is less than required to execute SUB") + } + + m.stack[m.sp - 2] -= m.stack[m.sp - 1]; + m.sp-- + m.ip++ + case MUL: + if (len(m.stack) < 2) { + return errors.New("Stack size is less than required to execute MUL") + } + + m.stack[m.sp - 2] *= m.stack[m.sp - 1]; + m.sp-- + m.ip++ + case DIV: + if (len(m.stack) < 2) { + return errors.New("Stack size is less than required to execute DIV") + } + + if (m.stack[m.sp - 2] == 0 || m.stack[m.sp - 1] == 0) { + return errors.New("Divide by zero exception") + } + + m.stack[m.sp - 2] /= m.stack[m.sp - 1]; + m.sp-- + m.ip++ } return nil } func (m* Machine) Print() { fmt.Println("Stack:"); - for i := 0; i <= m.sp; i++ { + for i := 0; i < m.sp; i++ { fmt.Println(m.stack[i]) } } @@ -78,11 +111,17 @@ func (m* Machine) Print() { func main() { m := Constructor() - m.Push(Instruction{Operation: PUSH, Operand: 1}) - m.Push(Instruction{Operation: PUSH, Operand: 2}) - m.Push(Instruction{Operation: ADD}) - m.Push(Instruction{Operation: HALT}) - + m.Push(Inst{Operation: PUSH, Operand: 1}) + m.Push(Inst{Operation: PUSH, Operand: 2}) + m.Push(Inst{Operation: ADD}) + m.Push(Inst{Operation: PUSH, Operand: 2}) + m.Push(Inst{Operation: SUB}) + m.Push(Inst{Operation: PUSH, Operand: 6}) + m.Push(Inst{Operation: MUL}) + m.Push(Inst{Operation: PUSH, Operand: 2}) + m.Push(Inst{Operation: DIV}) + m.Push(Inst{Operation: HALT}) + for !m.isHalted { m.Print() err := m.Execute() @@ -90,5 +129,4 @@ func main() { fmt.Fprintf(os.Stderr, "[ERR] %s", err); } } - m.Print() }