Other math implemented

This commit is contained in:
2024-01-20 00:48:02 +07:00
parent 3b82f5c4ba
commit 435f203abe

74
elm.go
View File

@@ -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,10 +111,16 @@ 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()
@@ -90,5 +129,4 @@ func main() {
fmt.Fprintf(os.Stderr, "[ERR] %s", err); fmt.Fprintf(os.Stderr, "[ERR] %s", err);
} }
} }
m.Print()
} }