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 }