Ran gofmt

This commit is contained in:
Sasha Koshka 2022-08-28 17:52:39 -04:00
parent eb3f581b00
commit 07a783b6ba

View File

@ -6,19 +6,19 @@ package creature
type Machine struct { type Machine struct {
// Program is not modified by the machine, and can be freely set before // Program is not modified by the machine, and can be freely set before
// the machine is started. // the machine is started.
Program []int Program []int
stack []int stack []int
block []int block []int
counter int counter int
pointer int pointer int
functions map[int] MachineFunction functions map[int]MachineFunction
} }
// MachineFunction is a function that can extend the functionality of the stack // 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. It is passed a pointer to the machine that is calling it, and the
// machine will halt execution if true is returned. // machine will halt execution if true is returned.
type MachineFunction func (machine *Machine) (stop bool) type MachineFunction func(machine *Machine) (stop bool)
// Error is an error type that can be returned from the machine's methods if // Error is an error type that can be returned from the machine's methods if
// they experience problems. // they experience problems.
@ -31,7 +31,7 @@ const (
) )
// Error returns a textual description of the error. // Error returns a textual description of the error.
func (err Error) Error () (description string) { func (err Error) Error() (description string) {
switch err { switch err {
case ErrorIDTaken: case ErrorIDTaken:
description = "this ID is taken by another function" description = "this ID is taken by another function"
@ -42,15 +42,15 @@ func (err Error) Error () (description string) {
// Reset resets the stack of the machine. This should be called before Execute, // Reset resets the stack of the machine. This should be called before Execute,
// since Execute does not reset the stack. // since Execute does not reset the stack.
func (machine *Machine) Reset () { func (machine *Machine) Reset() {
machine.stack = nil machine.stack = nil
machine.pointer = 0 machine.pointer = 0
} }
// Execute starts execution at the address specified by offset. The machine will // Execute starts execution at the address specified by offset. The machine will
// run until a HALT instruction is encountered, or the end of program memory is // run until a HALT instruction is encountered, or the end of program memory is
// reached. // reached.
func (machine *Machine) Execute (offset int) { func (machine *Machine) Execute(offset int) {
machine.counter = offset machine.counter = offset
for machine.counter < len(machine.Program) { for machine.counter < len(machine.Program) {
@ -58,88 +58,96 @@ func (machine *Machine) Execute (offset int) {
case 0x0: case 0x0:
// PUSH // PUSH
// push the next word in program memory onto the stack // push the next word in program memory onto the stack
machine.counter ++ machine.counter++
machine.Push(machine.instruction()) machine.Push(machine.instruction())
case 0x1: case 0x1:
// POP // POP
// pop the top word off of the stack, and discard it // pop the top word off of the stack, and discard it
machine.Pop() machine.Pop()
case 0x2: case 0x2:
// LOAD // LOAD
// push the word at an address onto the stack // push the word at an address onto the stack
machine.Push(machine.Peek(machine.Pop())) machine.Push(machine.Peek(machine.Pop()))
case 0x3: case 0x3:
// STOR // STOR
// store a word at an address // store a word at an address
machine.Poke(machine.Pop(), machine.Pop()) machine.Poke(machine.Pop(), machine.Pop())
case 0x4: case 0x4:
// ADD // ADD
// adds the last two words on the stack // adds the last two words on the stack
machine.Push(machine.Pop() + machine.Pop()) machine.Push(machine.Pop() + machine.Pop())
case 0x5: case 0x5:
// SUB // SUB
// subtracts the second to last word on the stack from // subtracts the second to last word on the stack from
// the last word on the stack // the last word on the stack
machine.Push(machine.Pop() - machine.Pop()) machine.Push(machine.Pop() - machine.Pop())
case 0x6: case 0x6:
// MUL // MUL
// multiplies the last two words on the stack // multiplies the last two words on the stack
machine.Push(machine.Pop() * machine.Pop()) machine.Push(machine.Pop() * machine.Pop())
case 0x7: case 0x7:
// DIV // DIV
// divides the last word on the stack by the second to // divides the last word on the stack by the second to
// last word on the stack // last word on the stack
machine.Push(machine.Pop() / machine.Pop()) machine.Push(machine.Pop() / machine.Pop())
case 0x8: case 0x8:
// EQ // EQ
// checks if the last two words on the stack are equal // checks if the last two words on the stack are equal
equal := 0 equal := 0
if machine.Pop() == machine.Pop() { equal = 1 } if machine.Pop() == machine.Pop() {
equal = 1
}
machine.Push(equal) machine.Push(equal)
case 0x9: case 0x9:
// GT // GT
// checks if the last word on the stack is greater than // checks if the last word on the stack is greater than
// the second to last word on the stack // the second to last word on the stack
greater := 0 greater := 0
if machine.Pop() > machine.Pop() { greater = 1 } if machine.Pop() > machine.Pop() {
greater = 1
}
machine.Push(greater) machine.Push(greater)
case 0xa: case 0xa:
// LT // LT
// checks if the last word on the stack is less than the // checks if the last word on the stack is less than the
// second to last word on the stack // second to last word on the stack
less := 0 less := 0
if machine.Pop() > machine.Pop() { less = 1 } if machine.Pop() > machine.Pop() {
less = 1
}
machine.Push(less) machine.Push(less)
case 0xb: case 0xb:
// NEQ // NEQ
// checks if the last two words on the stack are not // checks if the last two words on the stack are not
// equal // equal
notEqual := 0 notEqual := 0
if machine.Pop() != machine.Pop() { notEqual = 1 } if machine.Pop() != machine.Pop() {
notEqual = 1
}
machine.Push(notEqual) machine.Push(notEqual)
case 0xc: case 0xc:
// MOD // MOD
// performs a modulo operation of the second to last // performs a modulo operation of the second to last
// word on the stack to the last word on the stack // word on the stack to the last word on the stack
machine.Push(machine.Pop() % machine.Pop()) machine.Push(machine.Pop() % machine.Pop())
case 0xd: case 0xd:
// HALT // HALT
// stops execution // stops execution
return return
case 0xe: case 0xe:
// JMP // JMP
// jump to the address specified by the last word on the // jump to the address specified by the last word on the
@ -149,25 +157,27 @@ func (machine *Machine) Execute (offset int) {
if machine.Pop() != 0 { if machine.Pop() != 0 {
machine.counter = jumpTo - 1 machine.counter = jumpTo - 1
} }
case 0xf: case 0xf:
// CAL // CAL
// call an implementation-defined subroutine, with the // call an implementation-defined subroutine, with the
// id specified by the last word on the stack. this may // id specified by the last word on the stack. this may
// push and pop various things from the stack // push and pop various things from the stack
id := machine.Pop() id := machine.Pop()
if machine.functions == nil { break } if machine.functions == nil {
break
}
function, exists := machine.functions[id] function, exists := machine.functions[id]
if exists { if exists {
function(machine) function(machine)
} }
} }
machine.counter ++ machine.counter++
} }
} }
// Instruction returns the current instruction in program memory. // Instruction returns the current instruction in program memory.
func (machine *Machine) instruction () (instruction int) { func (machine *Machine) instruction() (instruction int) {
instruction = machine.Program[machine.counter] instruction = machine.Program[machine.counter]
return return
} }
@ -175,16 +185,16 @@ func (machine *Machine) instruction () (instruction int) {
// reallocateStack changes the size of the stack to something reasonable. This // reallocateStack changes the size of the stack to something reasonable. This
// should be called then the stack pointer is really small compared to the // should be called then the stack pointer is really small compared to the
// actual stack size, or the stack pointer is bigger than the stack. // actual stack size, or the stack pointer is bigger than the stack.
func (machine *Machine) reallocateStack () { func (machine *Machine) reallocateStack() {
reallocatedStack := make([]int, machine.pointer * 3 / 2) reallocatedStack := make([]int, machine.pointer*3/2)
copy(reallocatedStack, machine.stack) copy(reallocatedStack, machine.stack)
machine.stack = reallocatedStack machine.stack = reallocatedStack
} }
// Push pushes a word onto the stack, increasing the stack pointer and // Push pushes a word onto the stack, increasing the stack pointer and
// reallocating the stack if necessary. // reallocating the stack if necessary.
func (machine *Machine) Push (word int) { func (machine *Machine) Push(word int) {
machine.pointer ++ machine.pointer++
if len(machine.stack) <= machine.pointer { if len(machine.stack) <= machine.pointer {
machine.reallocateStack() machine.reallocateStack()
} }
@ -192,29 +202,29 @@ func (machine *Machine) Push (word int) {
// Pop pops the last word off of the stack, and returns it, decreasing the stack // Pop pops the last word off of the stack, and returns it, decreasing the stack
// pointer and reallocating the stack if necessary. // pointer and reallocating the stack if necessary.
func (machine *Machine) Pop () (word int) { func (machine *Machine) Pop() (word int) {
word = machine.stack[machine.pointer] word = machine.stack[machine.pointer]
machine.pointer -- machine.pointer--
if machine.pointer < len(machine.stack) / 3 { if machine.pointer < len(machine.stack)/3 {
machine.reallocateStack() machine.reallocateStack()
} }
return return
} }
// Peek returns the word at address in the block // Peek returns the word at address in the block.
func (machine *Machine) Peek (address int) (word int) { func (machine *Machine) Peek(address int) (word int) {
if address < len(machine.block) { if address < len(machine.block) {
word = machine.block[address] word = machine.block[address]
} }
return return
} }
// Poke sets the value at address in the block to word // Poke sets the value at address in the block to word.
func (machine *Machine) Poke (address int, word int) { func (machine *Machine) Poke(address int, word int) {
if address >= len(machine.block) { if address >= len(machine.block) {
reallocatedBlock := make([]int, address * 3 / 2) reallocatedBlock := make([]int, address*3/2)
copy(reallocatedBlock, machine.block) copy(reallocatedBlock, machine.block)
machine.block = reallocatedBlock machine.block = reallocatedBlock
} }
@ -222,9 +232,9 @@ func (machine *Machine) Poke (address int, word int) {
// Register registers a function at the specified ID. If there is already a // Register registers a function at the specified ID. If there is already a
// function registered at that ID, this method will return an error. // function registered at that ID, this method will return an error.
func (machine *Machine) Register (id int, function MachineFunction) (err error) { func (machine *Machine) Register(id int, function MachineFunction) (err error) {
if machine.functions == nil { if machine.functions == nil {
machine.functions = make(map[int] MachineFunction) machine.functions = make(map[int]MachineFunction)
} }
_, exists := machine.functions[id] _, exists := machine.functions[id]
@ -239,16 +249,18 @@ func (machine *Machine) Register (id int, function MachineFunction) (err error)
} }
// Unregister removes a function that is registered at the specified ID. // Unregister removes a function that is registered at the specified ID.
func (machine *Machine) Unregister (id int) { func (machine *Machine) Unregister(id int) {
if machine.functions == nil { return } if machine.functions == nil {
return
}
delete(machine.functions, id) delete(machine.functions, id)
} }
// LoadMemory loads the contents of block into the machine's memory. // LoadMemory loads the contents of block into the machine's memory.
func (machine *Machine) LoadMemory (block []int) { func (machine *Machine) LoadMemory(block []int) {
machine.block = make([]int, len(block)) machine.block = make([]int, len(block))
copy(machine.block, block) copy(machine.block, block)
} }
// Milk milks the stack machine // Milk milks the stack machine.
func (machine *Machine) Milk () {} func (machine *Machine) Milk() {}