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) } }