Added basic implementation that executes text files
This commit is contained in:
parent
a52e5d3426
commit
dcd8c56c0d
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/cmd/creature/creature
|
10
cmd/creature/examples/echo
Normal file
10
cmd/creature/examples/echo
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
0 0
|
||||
F
|
||||
|
||||
0 1
|
||||
F
|
||||
|
||||
0 1
|
||||
0 0
|
||||
E
|
104
cmd/creature/main.go
Normal file
104
cmd/creature/main.go
Normal 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
|
||||
}
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
package main
|
Loading…
Reference in New Issue
Block a user