ADD Implemented
This commit is contained in:
91
elm.go
91
elm.go
@@ -1,7 +1,94 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"errors"
|
||||
)
|
||||
|
||||
const STACK_SIZE = 1024
|
||||
|
||||
type Operation int
|
||||
|
||||
const (
|
||||
HALT Operation = 0
|
||||
PUSH Operation = 1
|
||||
ADD Operation = 2
|
||||
)
|
||||
|
||||
type Instruction struct {
|
||||
Operation Operation
|
||||
Operand int
|
||||
}
|
||||
|
||||
type Machine struct {
|
||||
program []Instruction
|
||||
stack []int
|
||||
ip int
|
||||
sp int
|
||||
isHalted bool;
|
||||
}
|
||||
|
||||
func Constructor() *Machine {
|
||||
m := Machine{}
|
||||
m.program = make([]Instruction, 0)
|
||||
m.stack = make([]int, STACK_SIZE)
|
||||
m.ip = 0
|
||||
m.sp = 0
|
||||
m.isHalted = false
|
||||
|
||||
return &m
|
||||
}
|
||||
|
||||
func (m* Machine) Push(i Instruction) error {
|
||||
m.program = append(m.program, i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m* Machine) Execute() error {
|
||||
instr := m.program[m.ip]
|
||||
switch op := instr.Operation; op {
|
||||
case HALT:
|
||||
m.isHalted = true;
|
||||
case PUSH:
|
||||
m.stack[m.sp] = instr.Operand
|
||||
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++;
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m* Machine) Print() {
|
||||
fmt.Println("Stack:");
|
||||
for i := 0; i <= m.sp; i++ {
|
||||
fmt.Println(m.stack[i])
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello, World!")
|
||||
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})
|
||||
|
||||
for !m.isHalted {
|
||||
m.Print()
|
||||
err := m.Execute()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[ERR] %s", err);
|
||||
}
|
||||
}
|
||||
m.Print()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user