Make Operands an array

This commit is contained in:
Ian Gulliver
2021-11-20 09:46:51 -10:00
parent 579ddab2de
commit b4a27cafd3
4 changed files with 67 additions and 72 deletions

View File

@@ -70,30 +70,21 @@ func assembleInstruction(in instruction) (*vm.Instruction, error) {
return nil, fmt.Errorf("Incorrect number of operands: expected %d, found %d\n", len(pattern), len(operands))
}
if len(operands) >= 1 {
op1, err := assembleOperand(operands[0], pattern[0])
for i, t := range pattern {
op, err := assembleOperand(operands[i], t)
if err != nil {
return nil, errors.Wrapf(err, "In first operand")
}
instr.Operand1 = op1
}
if len(operands) >= 2 {
op2, err := assembleOperand(operands[1], pattern[1])
if err != nil {
return nil, errors.Wrapf(err, "In second operand")
}
instr.Operand2 = op2
instr.Operands[i] = op
}
return instr, nil
}
func assembleOperand(op string, t operandType) (vm.Operand, error) {
func assembleOperand(op string, t operandType) (*vm.Operand, error) {
op = strings.ToLower(op)
ret := vm.Operand{}
ret := &vm.Operand{}
numStr := ""
switch {

View File

@@ -1,6 +1,7 @@
package asm
import "fmt"
import "strings"
import "github.com/firestuff/subcoding/vm"
import "github.com/pkg/errors"
@@ -28,7 +29,11 @@ func disassembleFunction(fnc *vm.Function) ([]byte, error) {
}
func disassembleInstruction(in *vm.Instruction) ([]byte, error) {
fmt.Printf("%s\n", nameByOpCode[in.OpCode])
parts := []string{
nameByOpCode[in.OpCode],
}
return nil, nil
encoded := fmt.Sprintf("[%s]", strings.Join(parts, ", "))
return []byte(encoded), nil
}

View File

@@ -3,8 +3,7 @@ package vm
type Instruction struct {
OpCode OpCodeType
Reserved [4]byte
Operand1 Operand
Operand2 Operand
Operands [2]*Operand
opHandler opHandler `struc:"skip"`
}

View File

@@ -48,131 +48,131 @@ func (state *State) handleNoOp(instr *Instruction) {
}
func (state *State) handleMove(instr *Instruction) {
in := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in)
in := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in)
}
func (state *State) handleAdd(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1+in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1+in2)
}
func (state *State) handleSubtract(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1-in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1-in2)
}
func (state *State) handleMultiply(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1*in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1*in2)
}
func (state *State) handleDivideUnsigned(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1/in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1/in2)
}
func (state *State) handleDivideSigned(instr *Instruction) {
in1 := state.readSigned(&instr.Operand1)
in2 := state.readSigned(&instr.Operand2)
state.writeSigned(&instr.Operand1, in1/in2)
in1 := state.readSigned(instr.Operands[0])
in2 := state.readSigned(instr.Operands[1])
state.writeSigned(instr.Operands[0], in1/in2)
}
func (state *State) handleNot(instr *Instruction) {
in := state.readUnsigned(&instr.Operand1)
state.writeUnsigned(&instr.Operand1, ^in)
in := state.readUnsigned(instr.Operands[0])
state.writeUnsigned(instr.Operands[0], ^in)
}
func (state *State) handleAnd(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1&in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1&in2)
}
func (state *State) handleOr(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1|in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1|in2)
}
func (state *State) handleXor(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1^in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1^in2)
}
func (state *State) handleShiftRight(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1>>in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1>>in2)
}
func (state *State) handleShiftLeft(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1<<in2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.writeUnsigned(instr.Operands[0], in1<<in2)
}
func (state *State) handleIsEqual(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.comparisonResult = (in1 == in2)
}
func (state *State) handleIsLessThanUnsigned(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.comparisonResult = (in1 < in2)
}
func (state *State) handleIsLessThanSigned(instr *Instruction) {
in1 := state.readSigned(&instr.Operand1)
in2 := state.readSigned(&instr.Operand2)
in1 := state.readSigned(instr.Operands[0])
in2 := state.readSigned(instr.Operands[1])
state.comparisonResult = (in1 < in2)
}
func (state *State) handleIsGreaterThanUnsigned(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.comparisonResult = (in1 > in2)
}
func (state *State) handleIsGreaterThanSigned(instr *Instruction) {
in1 := state.readSigned(&instr.Operand1)
in2 := state.readSigned(&instr.Operand2)
in1 := state.readSigned(instr.Operands[0])
in2 := state.readSigned(instr.Operands[1])
state.comparisonResult = (in1 > in2)
}
func (state *State) handleIsLessThanOrEqualUnsigned(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.comparisonResult = (in1 <= in2)
}
func (state *State) handleIsLessThanOrEqualSigned(instr *Instruction) {
in1 := state.readSigned(&instr.Operand1)
in2 := state.readSigned(&instr.Operand2)
in1 := state.readSigned(instr.Operands[0])
in2 := state.readSigned(instr.Operands[1])
state.comparisonResult = (in1 <= in2)
}
func (state *State) handleIsGreaterThanOrEqualUnsigned(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
in1 := state.readUnsigned(instr.Operands[0])
in2 := state.readUnsigned(instr.Operands[1])
state.comparisonResult = (in1 >= in2)
}
func (state *State) handleIsGreaterThanOrEqualSigned(instr *Instruction) {
in1 := state.readSigned(&instr.Operand1)
in2 := state.readSigned(&instr.Operand2)
in1 := state.readSigned(instr.Operands[0])
in2 := state.readSigned(instr.Operands[1])
state.comparisonResult = (in1 >= in2)
}
func (state *State) handleJump(instr *Instruction) {
in := state.readSigned(&instr.Operand1)
in := state.readSigned(instr.Operands[0])
state.jump(in)
}
@@ -189,7 +189,7 @@ func (state *State) handleJumpIfFalse(instr *Instruction) {
}
func (state *State) handleCall(instr *Instruction) {
in := state.readSigned(&instr.Operand1)
in := state.readSigned(instr.Operands[0])
state.call(in)
}