fixes && parse IL
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
/elm
|
||||
/elm
|
||||
*.bin
|
||||
*.lil
|
||||
140
elm.go
140
elm.go
@@ -1,14 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"strings"
|
||||
"fmt"
|
||||
"os"
|
||||
"errors"
|
||||
"encoding/binary"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const STACK_SIZE = 1024
|
||||
|
||||
type Operation int
|
||||
type Operation int32
|
||||
|
||||
const (
|
||||
HALT Operation = 0
|
||||
@@ -26,21 +30,21 @@ const (
|
||||
|
||||
type Inst struct {
|
||||
Operation Operation
|
||||
Operand int
|
||||
Operand int32
|
||||
}
|
||||
|
||||
type Machine struct {
|
||||
program []Inst
|
||||
stack []int
|
||||
ip int
|
||||
sp int
|
||||
stack []int32
|
||||
ip int32
|
||||
sp int32
|
||||
isHalted bool;
|
||||
}
|
||||
|
||||
func Constructor() *Machine {
|
||||
m := Machine{}
|
||||
m.program = make([]Inst, 0)
|
||||
m.stack = make([]int, STACK_SIZE)
|
||||
m.stack = make([]int32, STACK_SIZE)
|
||||
m.ip = 0
|
||||
m.sp = 0
|
||||
m.isHalted = false
|
||||
@@ -139,7 +143,7 @@ func (m* Machine) Execute() error {
|
||||
m.sp--
|
||||
m.ip++
|
||||
case JMP:
|
||||
if (len(m.program) < instr.Operand || instr.Operand < 0) {
|
||||
if (int32(len(m.program)) < instr.Operand || instr.Operand < 0) {
|
||||
return errors.New("Illegal access")
|
||||
}
|
||||
|
||||
@@ -149,7 +153,7 @@ func (m* Machine) Execute() error {
|
||||
return errors.New("Stack Underflow")
|
||||
}
|
||||
|
||||
if (len(m.program) <= instr.Operand || instr.Operand < 0) {
|
||||
if (int32(len(m.program)) <= instr.Operand || instr.Operand < 0) {
|
||||
return errors.New("Illegal access")
|
||||
}
|
||||
|
||||
@@ -165,11 +169,104 @@ func (m* Machine) Execute() error {
|
||||
|
||||
func (m* Machine) Print() {
|
||||
fmt.Println("Stack:");
|
||||
for i := 0; i < m.sp; i++ {
|
||||
for i := 0; int32(i) < m.sp; i++ {
|
||||
fmt.Println(m.stack[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (m* Machine) DumpProgramBinary(filename string) error {
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return errors.New("Couldn't open file")
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
err = binary.Write(f, binary.LittleEndian, m.program)
|
||||
if err != nil {
|
||||
return err
|
||||
//return errors.New("Couldn't write to file")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m* Machine) LoadProgramFromBinary(filename string) error {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return errors.New("Couldn't open file")
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
program := make([]Inst, STACK_SIZE)
|
||||
err = binary.Read(f, binary.LittleEndian, &program)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.program = program
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m* Machine) InterpretProgramFromFile(filename string) error {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return errors.New("Couldn't open file")
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
if (strings.HasPrefix(line, "HALT")){
|
||||
m.Push(Inst{Operation: HALT})
|
||||
} else if (strings.HasPrefix(line, "PUSH")) {
|
||||
op, err := strconv.Atoi(strings.Fields(line)[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Push(Inst{Operation: PUSH, Operand: int32(op)})
|
||||
} else if (strings.HasPrefix(line, "POP")) {
|
||||
m.Push(Inst{Operation: POP})
|
||||
} else if (strings.HasPrefix(line, "DUP")) {
|
||||
op, err := strconv.Atoi(strings.Fields(line)[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Push(Inst{Operation: DUP, Operand: int32(op)})
|
||||
} else if (strings.HasPrefix(line, "ADD")) {
|
||||
m.Push(Inst{Operation: ADD})
|
||||
} else if (strings.HasPrefix(line, "SUB")) {
|
||||
m.Push(Inst{Operation: SUB})
|
||||
} else if (strings.HasPrefix(line, "DIV")) {
|
||||
m.Push(Inst{Operation: DIV})
|
||||
} else if (strings.HasPrefix(line, "MUL")) {
|
||||
m.Push(Inst{Operation: MUL})
|
||||
} else if (strings.HasPrefix(line, "JMPIF")) {
|
||||
op, err := strconv.Atoi(strings.Fields(line)[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Push(Inst{Operation: JMPIF, Operand: int32(op)})
|
||||
} else if (strings.HasPrefix(line, "JMP")) {
|
||||
op, err := strconv.Atoi(strings.Fields(line)[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Push(Inst{Operation: JMP, Operand: int32(op)})
|
||||
} else if (strings.HasPrefix(line, "EQ")) {
|
||||
m.Push(Inst{Operation: EQ})
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
m := Constructor()
|
||||
|
||||
@@ -184,16 +281,21 @@ func main() {
|
||||
// m.Push(Inst{Operation: DIV})
|
||||
// m.Push(Inst{Operation: HALT})
|
||||
|
||||
m.Push(Inst{Operation: PUSH, Operand: 1})
|
||||
m.Push(Inst{Operation: JMPIF, Operand: 3})
|
||||
m.Push(Inst{Operation: HALT})
|
||||
m.Push(Inst{Operation: PUSH, Operand: 1})
|
||||
m.Push(Inst{Operation: PUSH, Operand: 2})
|
||||
m.Push(Inst{Operation: HALT})
|
||||
|
||||
// m.Push(Inst{Operation: PUSH, Operand: 1})
|
||||
// m.Push(Inst{Operation: JMPIF, Operand: 3})
|
||||
// m.Push(Inst{Operation: HALT})
|
||||
// m.Push(Inst{Operation: PUSH, Operand: 1})
|
||||
// m.Push(Inst{Operation: PUSH, Operand: 2})
|
||||
// m.Push(Inst{Operation: HALT})
|
||||
err := m.InterpretProgramFromFile("program.lil")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[ERR] %s\n", err);
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
stackCounter := 0
|
||||
for !m.isHalted && stackCounter < 69 {
|
||||
err := m.Execute()
|
||||
for !m.isHalted {
|
||||
err = m.Execute()
|
||||
m.Print()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[ERR] %s\n", err);
|
||||
@@ -201,6 +303,6 @@ func main() {
|
||||
}
|
||||
|
||||
stackCounter++
|
||||
|
||||
}
|
||||
m.Print()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user