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
|
||||
|
||||
// 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 {
|
||||
Program []int
|
||||
stack []int
|
||||
block []int
|
||||
counter int
|
||||
pointer int
|
||||
// Program is not modified by the machine, and can be freely set before
|
||||
// the machine is started.
|
||||
Program []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
|
||||
@ -112,6 +144,16 @@ func (machine *Machine) Execute (offset int) {
|
||||
}
|
||||
|
||||
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 ++
|
||||
}
|
||||
@ -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
|
||||
func (machine *Machine) Milk () {}
|
||||
|
Loading…
Reference in New Issue
Block a user