From 810ecdb3acb87a0b42df035ee6e95da00b74d6a0 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Mon, 29 Aug 2022 01:10:04 -0400 Subject: [PATCH] Added two examples showing the machine in action --- examples/echo.go | 40 +++++++++++ examples/psychiatrist.go | 142 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 examples/echo.go create mode 100644 examples/psychiatrist.go diff --git a/examples/echo.go b/examples/echo.go new file mode 100644 index 0000000..105ca58 --- /dev/null +++ b/examples/echo.go @@ -0,0 +1,40 @@ +// +build ignore + +package main + +import "os" +import cre "git.tebibyte.media/sashakoshka/creature" + +func main () { + // this is a simple echo program. it will take in input indefinetly and + // repeat it. due to line buffering in the terminal however, it will + // only print output once you have pressed enter. + machine := cre.Machine { Program: []int { + cre.PUSH, 0, + cre.CAL, + + cre.PUSH, 1, + cre.CAL, + + cre.PUSH, 1, + cre.PUSH, 0, + cre.JMP, + }} + + machine.Register (0, read) + machine.Register (1, write) + err := machine.Execute(0) + if err != nil { panic(err.Error()) } +} + +func read (machine *cre.Machine) (stop bool) { + ch := []byte { 0 } + os.Stdin.Read(ch) + machine.Push(int(ch[0])) + return +} + +func write (machine *cre.Machine) (stop bool) { + print(string(rune(machine.Pop()))) + return +} diff --git a/examples/psychiatrist.go b/examples/psychiatrist.go new file mode 100644 index 0000000..26e7316 --- /dev/null +++ b/examples/psychiatrist.go @@ -0,0 +1,142 @@ +// +build ignore + +package main + +import "os" +import cre "git.tebibyte.media/sashakoshka/creature" + +func main () { + // this is an "ai psychiatrist" program. when it starts, it asks the + // user "What brings you in today?", and no matter what the user types, + // the program will respond with "And how does that make you feel?". + // this is a crude re-implementation of a program i used on macos at one + // point. + + // constant address values + x := 0 + introStart := 1 + introLoopStart := 5 + readLoopStart := 36 + responseStart := 71 + responseLoopStart := 50 + + machine := cre.Machine { Program: []int { + // reset x + cre.PUSH, introStart, + cre.PUSH, x, + cre.POKE, + + // INTRO LOOP START + // get char + cre.PUSH, x, + cre.PEEK, + cre.PEEK, + + // break if char is equal to zero + cre.PUSH, 0, + cre.EQ, + cre.PUSH, readLoopStart, + cre.JMP, + + // get char + cre.PUSH, x, + cre.PEEK, + cre.PEEK, + + // call write function + cre.PUSH, 1, + cre.CAL, + + // increment x + cre.PUSH, x, + cre.PEEK, + cre.PUSH, 1, + cre.ADD, + cre.PUSH, x, + cre.POKE, + + // loop + cre.PUSH, 1, + cre.PUSH, introLoopStart, + cre.JMP, + + // INTRO LOOP END / READ LOOP START + // wait until the user presses enter + cre.PUSH, 0, + cre.CAL, + cre.PUSH, int('\n'), + cre.NEQ, + cre.PUSH, readLoopStart, + cre.JMP, + + // reset x + cre.PUSH, responseStart, + cre.PUSH, x, + cre.POKE, + + // RESPONSE LOOP START + // get char + cre.PUSH, x, + cre.PEEK, + cre.PEEK, + + // if the char is zero, we have finished printing and can once + // again prompt the user for an answer + cre.PUSH, 0, + cre.EQ, + cre.PUSH, readLoopStart, + cre.JMP, + + // get char + cre.PUSH, x, + cre.PEEK, + cre.PEEK, + + // call write function + cre.PUSH, 1, + cre.CAL, + + // increment x + cre.PUSH, x, + cre.PEEK, + cre.PUSH, 1, + cre.ADD, + cre.PUSH, x, + cre.POKE, + + // loop + cre.PUSH, 1, + cre.PUSH, responseLoopStart, + cre.JMP, + }} + + stringData := []byte ( + "\x00" + + "== Artificial Intelligence Psychiatrist ==\n" + + "What brings you in today?\n\x00" + + "And how does that make you feel?\n\x00") + block := make([]int, len(stringData)) + + for index, char := range stringData { + block[index] = int(char) + } + + machine.LoadMemory(block) + machine.Register (0, read) + machine.Register (1, write) + + err := machine.Execute(0) + if err != nil { panic(err.Error()) } +} + +func read (machine *cre.Machine) (stop bool) { + ch := []byte { 0 } + os.Stdin.Read(ch) + machine.Push(int(ch[0])) + return +} + +func write (machine *cre.Machine) (stop bool) { + print(string(rune(machine.Pop()))) + return +}