Added basic implementation that executes text files

This commit is contained in:
Sasha Koshka 2022-09-08 16:02:36 -04:00
parent a52e5d3426
commit dcd8c56c0d
4 changed files with 115 additions and 1 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/cmd/creature/creature

View File

@ -0,0 +1,10 @@
---
0 0
F
0 1
F
0 1
0 0
E

104
cmd/creature/main.go Normal file
View File

@ -0,0 +1,104 @@
package main
import "io"
import "os"
import "fmt"
import "bufio"
import "strconv"
import cre "git.tebibyte.media/sashakoshka/creature"
func main() {
if len(os.Args) != 2 {
logLine("ERR file unspecified")
os.Exit(1)
}
file, err := os.Open(os.Args[1])
if err != nil {
logLine("ERR could not open file: " + err.Error())
os.Exit(1)
}
program, block, err := readFile(file)
if err != nil {
logLine("ERR could not read file: " + err.Error())
os.Exit(1)
}
machine := cre.Machine[int]{}
machine.LoadProgram(program)
machine.LoadMemory(block)
machine.Register(0, read)
machine.Register(1, write)
err = machine.Execute(0)
if err != nil {
logLine("XXX machine failed: " + err.Error())
os.Exit(1)
}
}
func read(machine *cre.Machine[int]) (stop bool) {
ch := []byte{0}
os.Stdin.Read(ch)
machine.Push(int(ch[0]))
return
}
func write(machine *cre.Machine[int]) (stop bool) {
print(string(rune(machine.Pop())))
return
}
func logLine (message ...any) {
fmt.Fprintln(os.Stderr, message...)
}
func readFile (reader io.Reader) (program []int, block []int, err error) {
scanner := bufio.NewScanner(reader)
scanner.Split(bufio.ScanWords)
blockLen := 0
block = make([]int, 8)
for scanner.Scan() {
if scanner.Text() == "---" {
break
}
if blockLen >= len(block) {
newSlice := make([]int, len(block) * 2)
copy(newSlice, block)
block = newSlice
}
var number int64
number, err = strconv.ParseInt(scanner.Text(), 16, 64)
if err != nil {
return
}
block[blockLen] = int(number)
blockLen ++
}
block = block[:blockLen]
programLen := 0
program = make([]int, 8)
for scanner.Scan() {
if programLen >= len(program) {
newSlice := make([]int, len(program) * 2)
copy(newSlice, program)
program = newSlice
}
var number int64
number, err = strconv.ParseInt(scanner.Text(), 16, 64)
if err != nil {
return
}
program[programLen] = int(number)
programLen ++
}
program = program[:programLen]
return
}

View File

@ -1 +0,0 @@
package main