Implemented call instruction and function registering
This commit is contained in:
parent
4067027588
commit
ebf58c9427
70
creature.go
70
creature.go
@ -1,11 +1,43 @@
|
|||||||
package creature
|
package creature
|
||||||
|
|
||||||
|
// Machine is a stack machine. It contains an array of integers as its program
|
||||||
|
// data, and provides methods to run this program data, as well as interact with
|
||||||
|
// it.
|
||||||
type Machine struct {
|
type Machine struct {
|
||||||
Program []int
|
// Program is not modified by the machine, and can be freely set before
|
||||||
stack []int
|
// the machine is started.
|
||||||
block []int
|
Program []int
|
||||||
counter int
|
|
||||||
pointer int
|
stack []int
|
||||||
|
block []int
|
||||||
|
counter int
|
||||||
|
pointer int
|
||||||
|
functions map[int] MachineFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
// MachineFunction is a function that can extend the functionality of the stack
|
||||||
|
// machine. It is passed a pointer to the machine that is calling it, and the
|
||||||
|
// machine will halt execution if true is returned.
|
||||||
|
type MachineFunction func (machine *Machine) (stop bool)
|
||||||
|
|
||||||
|
// Error is an error type that can be returned from the machine's methods if
|
||||||
|
// they experience problems.
|
||||||
|
type Error int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ErrorIDTaken is returned by Register when a new function is
|
||||||
|
// registered with the same ID as another one.
|
||||||
|
ErrorIDTaken Error = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
// Error returns a textual description of the error.
|
||||||
|
func (err Error) Error () (description string) {
|
||||||
|
switch err {
|
||||||
|
case ErrorIDTaken:
|
||||||
|
description = "this ID is taken by another function"
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute starts execution at the address specified by offset. The machine will
|
// Execute starts execution at the address specified by offset. The machine will
|
||||||
@ -112,6 +144,16 @@ func (machine *Machine) Execute (offset int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 0xf:
|
case 0xf:
|
||||||
|
// CAL
|
||||||
|
// call an implementation-defined subroutine, with the
|
||||||
|
// id specified by the last word on the stack. this may
|
||||||
|
// push and pop various things from the stack
|
||||||
|
id := machine.Pop()
|
||||||
|
if machine.functions == nil { break }
|
||||||
|
function, exists := machine.functions[id]
|
||||||
|
if exists {
|
||||||
|
function(machine)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
machine.counter ++
|
machine.counter ++
|
||||||
}
|
}
|
||||||
@ -171,5 +213,23 @@ func (machine *Machine) Poke (address int, word int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register registers a function at the specified ID. If there is already a
|
||||||
|
// function registered at that ID, this method will return an error.
|
||||||
|
func (machine *Machine) Register (id int, function MachineFunction) (err error) {
|
||||||
|
if machine.functions == nil {
|
||||||
|
machine.functions = make(map[int] MachineFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, exists := machine.functions[id]
|
||||||
|
if exists {
|
||||||
|
err = ErrorIDTaken
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
machine.functions[id] = function
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Milk milks the stack machine
|
// Milk milks the stack machine
|
||||||
func (machine *Machine) Milk () {}
|
func (machine *Machine) Milk () {}
|
||||||
|
Loading…
Reference in New Issue
Block a user