bitfield/gmachine/gmachine.go
2022-02-23 01:31:53 +01:00

76 lines
1.3 KiB
Go

package gmachine
import (
"fmt"
"log"
)
// DefaultMemSize is the number of 64-bit words of memory which will be
// allocated to a new G-machine by default.
const DefaultMemSize = 1024
const (
OpHALT uint64 = iota
OpNOOP
OpINCA
OpDECA
OpSETA
)
type gMachine struct {
// Memory 64-bit words of memory
Memory []uint64
// P (Program counter)
P uint64
// A (Register A)
A uint64
// Debugging flag, if turned on will print OpCodes
DebugOn bool
}
func New() *gMachine {
return &gMachine{
P: 0,
Memory: make([]uint64, DefaultMemSize),
DebugOn: false,
}
}
func (m *gMachine) NewProgram(program []uint64) {
copy(m.Memory, program)
m.Run()
}
func (m *gMachine) Run() {
for {
pointer := m.P
m.P++
switch m.Memory[pointer] {
case OpHALT:
m.printIfDebug("OpHALT")
return
case OpNOOP:
m.printIfDebug("OpNOOP")
case OpINCA:
m.printIfDebug("OpINCA")
m.A++
case OpDECA:
m.printIfDebug("OpDECA")
m.A--
case OpSETA:
m.A = m.Memory[m.P]
m.P++
m.printIfDebug(fmt.Sprintf("OpSETA %d", m.A))
default:
m.printIfDebug(fmt.Sprintf("COULD NOT DETERMINE OP CODE, code:%d, pointer:%d", m.Memory[pointer], pointer))
panic(pointer)
}
}
}
func (m *gMachine) printIfDebug(message string) {
if m.DebugOn {
log.Println(message)
}
}