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))
|
return nil, fmt.Errorf("Incorrect number of operands: expected %d, found %d\n", len(pattern), len(operands))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(operands) >= 1 {
|
for i, t := range pattern {
|
||||||
op1, err := assembleOperand(operands[0], pattern[0])
|
op, err := assembleOperand(operands[i], t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "In first operand")
|
return nil, errors.Wrapf(err, "In first operand")
|
||||||
}
|
}
|
||||||
|
|
||||||
instr.Operand1 = op1
|
instr.Operands[i] = op
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return instr, nil
|
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)
|
op = strings.ToLower(op)
|
||||||
ret := vm.Operand{}
|
ret := &vm.Operand{}
|
||||||
numStr := ""
|
numStr := ""
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package asm
|
package asm
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
import "strings"
|
||||||
|
|
||||||
import "github.com/firestuff/subcoding/vm"
|
import "github.com/firestuff/subcoding/vm"
|
||||||
import "github.com/pkg/errors"
|
import "github.com/pkg/errors"
|
||||||
@@ -28,7 +29,11 @@ func disassembleFunction(fnc *vm.Function) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func disassembleInstruction(in *vm.Instruction) ([]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 {
|
type Instruction struct {
|
||||||
OpCode OpCodeType
|
OpCode OpCodeType
|
||||||
Reserved [4]byte
|
Reserved [4]byte
|
||||||
Operand1 Operand
|
Operands [2]*Operand
|
||||||
Operand2 Operand
|
|
||||||
|
|
||||||
opHandler opHandler `struc:"skip"`
|
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) {
|
func (state *State) handleMove(instr *Instruction) {
|
||||||
in := state.readUnsigned(&instr.Operand2)
|
in := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in)
|
state.writeUnsigned(instr.Operands[0], in)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleAdd(instr *Instruction) {
|
func (state *State) handleAdd(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1+in2)
|
state.writeUnsigned(instr.Operands[0], in1+in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleSubtract(instr *Instruction) {
|
func (state *State) handleSubtract(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1-in2)
|
state.writeUnsigned(instr.Operands[0], in1-in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleMultiply(instr *Instruction) {
|
func (state *State) handleMultiply(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1*in2)
|
state.writeUnsigned(instr.Operands[0], in1*in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleDivideUnsigned(instr *Instruction) {
|
func (state *State) handleDivideUnsigned(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1/in2)
|
state.writeUnsigned(instr.Operands[0], in1/in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleDivideSigned(instr *Instruction) {
|
func (state *State) handleDivideSigned(instr *Instruction) {
|
||||||
in1 := state.readSigned(&instr.Operand1)
|
in1 := state.readSigned(instr.Operands[0])
|
||||||
in2 := state.readSigned(&instr.Operand2)
|
in2 := state.readSigned(instr.Operands[1])
|
||||||
state.writeSigned(&instr.Operand1, in1/in2)
|
state.writeSigned(instr.Operands[0], in1/in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleNot(instr *Instruction) {
|
func (state *State) handleNot(instr *Instruction) {
|
||||||
in := state.readUnsigned(&instr.Operand1)
|
in := state.readUnsigned(instr.Operands[0])
|
||||||
state.writeUnsigned(&instr.Operand1, ^in)
|
state.writeUnsigned(instr.Operands[0], ^in)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleAnd(instr *Instruction) {
|
func (state *State) handleAnd(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1&in2)
|
state.writeUnsigned(instr.Operands[0], in1&in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleOr(instr *Instruction) {
|
func (state *State) handleOr(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1|in2)
|
state.writeUnsigned(instr.Operands[0], in1|in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleXor(instr *Instruction) {
|
func (state *State) handleXor(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1^in2)
|
state.writeUnsigned(instr.Operands[0], in1^in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleShiftRight(instr *Instruction) {
|
func (state *State) handleShiftRight(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1>>in2)
|
state.writeUnsigned(instr.Operands[0], in1>>in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleShiftLeft(instr *Instruction) {
|
func (state *State) handleShiftLeft(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.writeUnsigned(&instr.Operand1, in1<<in2)
|
state.writeUnsigned(instr.Operands[0], in1<<in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsEqual(instr *Instruction) {
|
func (state *State) handleIsEqual(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 == in2)
|
state.comparisonResult = (in1 == in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsLessThanUnsigned(instr *Instruction) {
|
func (state *State) handleIsLessThanUnsigned(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 < in2)
|
state.comparisonResult = (in1 < in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsLessThanSigned(instr *Instruction) {
|
func (state *State) handleIsLessThanSigned(instr *Instruction) {
|
||||||
in1 := state.readSigned(&instr.Operand1)
|
in1 := state.readSigned(instr.Operands[0])
|
||||||
in2 := state.readSigned(&instr.Operand2)
|
in2 := state.readSigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 < in2)
|
state.comparisonResult = (in1 < in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsGreaterThanUnsigned(instr *Instruction) {
|
func (state *State) handleIsGreaterThanUnsigned(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 > in2)
|
state.comparisonResult = (in1 > in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsGreaterThanSigned(instr *Instruction) {
|
func (state *State) handleIsGreaterThanSigned(instr *Instruction) {
|
||||||
in1 := state.readSigned(&instr.Operand1)
|
in1 := state.readSigned(instr.Operands[0])
|
||||||
in2 := state.readSigned(&instr.Operand2)
|
in2 := state.readSigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 > in2)
|
state.comparisonResult = (in1 > in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsLessThanOrEqualUnsigned(instr *Instruction) {
|
func (state *State) handleIsLessThanOrEqualUnsigned(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 <= in2)
|
state.comparisonResult = (in1 <= in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsLessThanOrEqualSigned(instr *Instruction) {
|
func (state *State) handleIsLessThanOrEqualSigned(instr *Instruction) {
|
||||||
in1 := state.readSigned(&instr.Operand1)
|
in1 := state.readSigned(instr.Operands[0])
|
||||||
in2 := state.readSigned(&instr.Operand2)
|
in2 := state.readSigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 <= in2)
|
state.comparisonResult = (in1 <= in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsGreaterThanOrEqualUnsigned(instr *Instruction) {
|
func (state *State) handleIsGreaterThanOrEqualUnsigned(instr *Instruction) {
|
||||||
in1 := state.readUnsigned(&instr.Operand1)
|
in1 := state.readUnsigned(instr.Operands[0])
|
||||||
in2 := state.readUnsigned(&instr.Operand2)
|
in2 := state.readUnsigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 >= in2)
|
state.comparisonResult = (in1 >= in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleIsGreaterThanOrEqualSigned(instr *Instruction) {
|
func (state *State) handleIsGreaterThanOrEqualSigned(instr *Instruction) {
|
||||||
in1 := state.readSigned(&instr.Operand1)
|
in1 := state.readSigned(instr.Operands[0])
|
||||||
in2 := state.readSigned(&instr.Operand2)
|
in2 := state.readSigned(instr.Operands[1])
|
||||||
state.comparisonResult = (in1 >= in2)
|
state.comparisonResult = (in1 >= in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleJump(instr *Instruction) {
|
func (state *State) handleJump(instr *Instruction) {
|
||||||
in := state.readSigned(&instr.Operand1)
|
in := state.readSigned(instr.Operands[0])
|
||||||
state.jump(in)
|
state.jump(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ func (state *State) handleJumpIfFalse(instr *Instruction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) handleCall(instr *Instruction) {
|
func (state *State) handleCall(instr *Instruction) {
|
||||||
in := state.readSigned(&instr.Operand1)
|
in := state.readSigned(instr.Operands[0])
|
||||||
state.call(in)
|
state.call(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user