Add gmachine
This commit is contained in:
75
gmachine/gmachine.go
Normal file
75
gmachine/gmachine.go
Normal file
@@ -0,0 +1,75 @@
|
||||
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)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user