Make Operands an array
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
108
vm/ophandler.go
108
vm/ophandler.go
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user