Other math implemented
This commit is contained in:
76
elm.go
76
elm.go
@@ -14,15 +14,18 @@ const (
|
|||||||
HALT Operation = 0
|
HALT Operation = 0
|
||||||
PUSH Operation = 1
|
PUSH Operation = 1
|
||||||
ADD Operation = 2
|
ADD Operation = 2
|
||||||
|
SUB Operation = 3
|
||||||
|
MUL Operation = 4
|
||||||
|
DIV Operation = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
type Instruction struct {
|
type Inst struct {
|
||||||
Operation Operation
|
Operation Operation
|
||||||
Operand int
|
Operand int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Machine struct {
|
type Machine struct {
|
||||||
program []Instruction
|
program []Inst
|
||||||
stack []int
|
stack []int
|
||||||
ip int
|
ip int
|
||||||
sp int
|
sp int
|
||||||
@@ -31,7 +34,7 @@ type Machine struct {
|
|||||||
|
|
||||||
func Constructor() *Machine {
|
func Constructor() *Machine {
|
||||||
m := Machine{}
|
m := Machine{}
|
||||||
m.program = make([]Instruction, 0)
|
m.program = make([]Inst, 0)
|
||||||
m.stack = make([]int, STACK_SIZE)
|
m.stack = make([]int, STACK_SIZE)
|
||||||
m.ip = 0
|
m.ip = 0
|
||||||
m.sp = 0
|
m.sp = 0
|
||||||
@@ -40,7 +43,7 @@ func Constructor() *Machine {
|
|||||||
return &m
|
return &m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m* Machine) Push(i Instruction) error {
|
func (m* Machine) Push(i Inst) error {
|
||||||
m.program = append(m.program, i)
|
m.program = append(m.program, i)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -49,28 +52,58 @@ func (m* Machine) Execute() error {
|
|||||||
instr := m.program[m.ip]
|
instr := m.program[m.ip]
|
||||||
switch op := instr.Operation; op {
|
switch op := instr.Operation; op {
|
||||||
case HALT:
|
case HALT:
|
||||||
m.isHalted = true;
|
m.isHalted = true
|
||||||
case PUSH:
|
case PUSH:
|
||||||
|
if (m.sp >= STACK_SIZE) {
|
||||||
|
return errors.New("Stack Overflow");
|
||||||
|
}
|
||||||
|
|
||||||
m.stack[m.sp] = instr.Operand
|
m.stack[m.sp] = instr.Operand
|
||||||
m.sp++;
|
m.sp++
|
||||||
m.ip++;
|
m.ip++
|
||||||
case ADD:
|
case ADD:
|
||||||
if (len(m.stack) < 2) {
|
if (len(m.stack) < 2) {
|
||||||
return errors.New("Stack size is less than required to execute ADD")
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m* Machine) Print() {
|
func (m* Machine) Print() {
|
||||||
fmt.Println("Stack:");
|
fmt.Println("Stack:");
|
||||||
for i := 0; i <= m.sp; i++ {
|
for i := 0; i < m.sp; i++ {
|
||||||
fmt.Println(m.stack[i])
|
fmt.Println(m.stack[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,11 +111,17 @@ func (m* Machine) Print() {
|
|||||||
func main() {
|
func main() {
|
||||||
m := Constructor()
|
m := Constructor()
|
||||||
|
|
||||||
m.Push(Instruction{Operation: PUSH, Operand: 1})
|
m.Push(Inst{Operation: PUSH, Operand: 1})
|
||||||
m.Push(Instruction{Operation: PUSH, Operand: 2})
|
m.Push(Inst{Operation: PUSH, Operand: 2})
|
||||||
m.Push(Instruction{Operation: ADD})
|
m.Push(Inst{Operation: ADD})
|
||||||
m.Push(Instruction{Operation: HALT})
|
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 {
|
for !m.isHalted {
|
||||||
m.Print()
|
m.Print()
|
||||||
err := m.Execute()
|
err := m.Execute()
|
||||||
@@ -90,5 +129,4 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, "[ERR] %s", err);
|
fmt.Fprintf(os.Stderr, "[ERR] %s", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.Print()
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user