Implement some instructions

master
Jonas Franz 5 years ago
parent 743ec2c0b5
commit 99bb8f98a7
Signed by: JonasFranzDEV
GPG Key ID: 7293A220B7C38080
  1. 81
      hal/instructions.go
  2. 15
      hal/module.go

@ -1,6 +1,7 @@
package hal
import (
"fmt"
"strings"
)
@ -9,20 +10,20 @@ type ProgrammedInstruction struct {
Operand float64
}
func (pi *ProgrammedInstruction) Execute(module *Module) {
func (pi *ProgrammedInstruction) Execute(module *Module) error {
if pi.Instruction.ExecuteWithOperand != nil {
pi.Instruction.ExecuteWithOperand(module, pi.Operand)
return pi.Instruction.ExecuteWithOperand(module, pi.Operand)
} else if pi.Instruction.Execute != nil {
pi.Instruction.Execute(module)
return pi.Instruction.Execute(module)
} else {
panic("instruction is not implemented")
return fmt.Errorf("instruction is not implemented")
}
}
type Instruction struct {
Name string
ExecuteWithOperand func(module *Module, operand float64)
Execute func(module *Module)
ExecuteWithOperand func(module *Module, operand float64) error
Execute func(module *Module) error
}
func FindInstructionByName(name string) *Instruction {
@ -43,29 +44,87 @@ var instructions = []*Instruction{
var InstructionStart = &Instruction{
Name: "START",
Execute: func(module *Module) {
Execute: func(module *Module) error {
// actually not required
module.isStopped = false
return nil
},
}
var InstructionStop = &Instruction{
Name: "STOP",
Execute: func(module *Module) {
Execute: func(module *Module) error {
module.isStopped = true
return nil
},
}
var InstructionOut = &Instruction{
Name: "OUT",
ExecuteWithOperand: func(module *Module, operand float64) {
ExecuteWithOperand: func(module *Module, operand float64) error {
index := int(operand)
if len(module.IO) >= index {
return fmt.Errorf("index %d exceeds IO size of %d", index, len(module.IO))
}
module.IO[int64(operand)] = module.accumulator
return nil
},
}
var InstructionIn = &Instruction{
Name: "IN",
Execute: func(module *Module) {
// TODO implement
ExecuteWithOperand: func(module *Module, operand float64) error {
index := int(operand)
if len(module.IO) >= index {
return fmt.Errorf("index %d exceeds IO size of %d", index, len(module.IO))
}
module.accumulator = module.IO[index]
return nil
},
}
var InstructionLoad = &Instruction{
Name: "LOAD",
ExecuteWithOperand: func(module *Module, operand float64) error {
index := int(operand)
if len(module.register) >= index {
return fmt.Errorf("index %d exceeds register size of %d", index, len(module.IO))
}
module.accumulator = module.register[index]
return nil
},
}
var InstructionLoadNum = &Instruction{
Name: "LOADNUM",
ExecuteWithOperand: func(module *Module, operand float64) error {
module.accumulator = operand
return nil
},
}
var InstructionStore = &Instruction{
Name: "STORE",
ExecuteWithOperand: func(module *Module, operand float64) error {
index := int(operand)
if len(module.register) >= index {
return fmt.Errorf("index %d exceeds register size of %d", index, len(module.IO))
}
module.register[index] = module.accumulator
return nil
},
}
var InstructionJumpNeg = &Instruction{
Name: "JUMPNEG",
ExecuteWithOperand: func(module *Module, operand float64) error {
index := int64(operand)
if _, ok := module.programStorage[index]; !ok {
return fmt.Errorf("index %d does not exist in program storage", index)
}
if module.accumulator < 0 {
return module.setProgramCounter(index)
}
return nil
},
}

@ -14,16 +14,23 @@ type Module struct {
isStopped bool
}
func (h *Module) ProgramCounter() int64 {
func (h *Module) programCounter() int64 {
return int64(h.register[0])
}
func (h *Module) setProgramCounter(counter int64) error {
h.register[0] = float64(counter)
if _, ok := h.programStorage[counter]; !ok {
return fmt.Errorf("index %d does not exist in program storage", counter)
}
return nil
}
func (h *Module) increaseProgramCounter() {
h.register[0]++
}
func (h *Module) Step() {
instruction := h.programStorage[h.ProgramCounter()]
instruction := h.programStorage[h.programCounter()]
h.increaseProgramCounter()
if instruction == nil {
return
@ -32,10 +39,10 @@ func (h *Module) Step() {
}
func (h *Module) Run() error {
for !h.isStopped && h.ProgramCounter() <= maxInstructions {
for !h.isStopped && h.programCounter() <= maxInstructions {
h.Step()
}
if h.ProgramCounter() > maxInstructions {
if h.programCounter() > maxInstructions {
return fmt.Errorf("module exceeded max instructions without being stopped")
}
return nil

Loading…
Cancel
Save