144 lines
2.5 KiB
Go
144 lines
2.5 KiB
Go
// +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[int] {}
|
|
machine.LoadProgram([]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[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
|
|
}
|