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 package hal
import ( import (
"fmt"
"strings" "strings"
) )
@ -9,20 +10,20 @@ type ProgrammedInstruction struct {
Operand float64 Operand float64
} }
func (pi *ProgrammedInstruction) Execute(module *Module) { func (pi *ProgrammedInstruction) Execute(module *Module) error {
if pi.Instruction.ExecuteWithOperand != nil { if pi.Instruction.ExecuteWithOperand != nil {
pi.Instruction.ExecuteWithOperand(module, pi.Operand) return pi.Instruction.ExecuteWithOperand(module, pi.Operand)
} else if pi.Instruction.Execute != nil { } else if pi.Instruction.Execute != nil {
pi.Instruction.Execute(module) return pi.Instruction.Execute(module)
} else { } else {
panic("instruction is not implemented") return fmt.Errorf("instruction is not implemented")
} }
} }
type Instruction struct { type Instruction struct {
Name string Name string
ExecuteWithOperand func(module *Module, operand float64) ExecuteWithOperand func(module *Module, operand float64) error
Execute func(module *Module) Execute func(module *Module) error
} }
func FindInstructionByName(name string) *Instruction { func FindInstructionByName(name string) *Instruction {
@ -43,29 +44,87 @@ var instructions = []*Instruction{
var InstructionStart = &Instruction{ var InstructionStart = &Instruction{
Name: "START", Name: "START",
Execute: func(module *Module) { Execute: func(module *Module) error {
// actually not required // actually not required
module.isStopped = false module.isStopped = false
return nil
}, },
} }
var InstructionStop = &Instruction{ var InstructionStop = &Instruction{
Name: "STOP", Name: "STOP",
Execute: func(module *Module) { Execute: func(module *Module) error {
module.isStopped = true module.isStopped = true
return nil
}, },
} }
var InstructionOut = &Instruction{ var InstructionOut = &Instruction{
Name: "OUT", 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 module.IO[int64(operand)] = module.accumulator
return nil
}, },
} }
var InstructionIn = &Instruction{ var InstructionIn = &Instruction{
Name: "IN", Name: "IN",
Execute: func(module *Module) { ExecuteWithOperand: func(module *Module, operand float64) error {
// TODO implement 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 isStopped bool
} }
func (h *Module) ProgramCounter() int64 { func (h *Module) programCounter() int64 {
return int64(h.register[0]) 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() { func (h *Module) increaseProgramCounter() {
h.register[0]++ h.register[0]++
} }
func (h *Module) Step() { func (h *Module) Step() {
instruction := h.programStorage[h.ProgramCounter()] instruction := h.programStorage[h.programCounter()]
h.increaseProgramCounter() h.increaseProgramCounter()
if instruction == nil { if instruction == nil {
return return
@ -32,10 +39,10 @@ func (h *Module) Step() {
} }
func (h *Module) Run() error { func (h *Module) Run() error {
for !h.isStopped && h.ProgramCounter() <= maxInstructions { for !h.isStopped && h.programCounter() <= maxInstructions {
h.Step() h.Step()
} }
if h.ProgramCounter() > maxInstructions { if h.programCounter() > maxInstructions {
return fmt.Errorf("module exceeded max instructions without being stopped") return fmt.Errorf("module exceeded max instructions without being stopped")
} }
return nil return nil

Loading…
Cancel
Save