diff --git a/creature.go b/creature.go index 8880828..a90ef03 100644 --- a/creature.go +++ b/creature.go @@ -11,10 +11,7 @@ type Word interface { // data, and provides methods to run this program data, as well as interact with // it. type Machine [WORD Word] struct { - // Program is not modified by the machine, and can be freely set before - // the machine is started. - Program []WORD - + program []WORD stack []WORD block []WORD counter WORD @@ -87,7 +84,7 @@ func (machine *Machine[WORD]) Reset() { func (machine *Machine[WORD]) Execute(offset WORD) (err error) { machine.counter = offset - for int(machine.counter) < len(machine.Program) { + for int(machine.counter) < len(machine.program) { switch machine.instruction() { case PUSH: machine.counter++ @@ -202,7 +199,7 @@ func (machine *Machine[WORD]) Execute(offset WORD) (err error) { // Instruction returns the current instruction in program memory. func (machine *Machine[WORD]) instruction() (instruction WORD) { - instruction = machine.Program[machine.counter] + instruction = machine.program[machine.counter] return } @@ -291,6 +288,12 @@ func (machine *Machine[WORD]) Unregister(id WORD) { delete(machine.functions, id) } +// LoadProgram loads the contents of program into the machine's program memory. +func (machine *Machine[WORD]) LoadProgram(program []WORD) { + machine.program = make([]WORD, len(program)) + copy(machine.program, program) +} + // LoadMemory loads the contents of block into the machine's memory. func (machine *Machine[WORD]) LoadMemory(block []WORD) { machine.block = make([]WORD, len(block)) diff --git a/creature_test.go b/creature_test.go index a320dad..9a54bbd 100644 --- a/creature_test.go +++ b/creature_test.go @@ -9,7 +9,8 @@ func runMachineTest ( ) ( machine *Machine[int], ) { - machine = &Machine[int] { Program: program } + machine = &Machine[int] {} + machine.LoadProgram(program) if memory != nil { machine.LoadMemory(memory) } @@ -230,7 +231,8 @@ func TestJump(test *testing.T) { func TestRegister(test *testing.T) { output := "" - machine := &Machine[int] { Program: []int { + machine := &Machine[int] {} + machine.LoadProgram([]int { PUSH, int('h'), PUSH, 4, CAL, @@ -258,7 +260,7 @@ func TestRegister(test *testing.T) { PUSH, int('!'), PUSH, 4, CAL, - }} + }) machine.Register(4, func(machine *Machine[int]) (stop bool) { output += string(rune(machine.Pop())) return diff --git a/examples/echo.go b/examples/echo.go index 8a3d8ba..c5ff5a1 100644 --- a/examples/echo.go +++ b/examples/echo.go @@ -9,7 +9,8 @@ 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[int] { Program: []int { + machine := cre.Machine[int] {} + machine.LoadProgram([]int { cre.PUSH, 0, cre.CAL, @@ -19,7 +20,7 @@ func main () { cre.PUSH, 1, cre.PUSH, 0, cre.JMP, - }} + }) machine.Register (0, read) machine.Register (1, write) diff --git a/examples/psychiatrist.go b/examples/psychiatrist.go index 72338b5..f3e4ec9 100644 --- a/examples/psychiatrist.go +++ b/examples/psychiatrist.go @@ -20,7 +20,8 @@ func main () { responseStart := 71 responseLoopStart := 50 - machine := cre.Machine[int] { Program: []int { + machine := cre.Machine[int] {} + machine.LoadProgram([]int { // reset x cre.PUSH, introStart, cre.PUSH, x, @@ -108,7 +109,7 @@ func main () { cre.PUSH, 1, cre.PUSH, responseLoopStart, cre.JMP, - }} + }) stringData := []byte ( "\x00" +