diff --git a/load/load.go b/load/load.go new file mode 100644 index 0000000..d6e6aac --- /dev/null +++ b/load/load.go @@ -0,0 +1,54 @@ +package load + +import "bytes" + +import "github.com/firestuff/subcoding/vm" +import "github.com/lunixbochs/struc" +import "github.com/pkg/errors" + +const instructionBytes = 32 + +func Load(byteCodes [][]byte) ([][]*vm.Instruction, error) { + fncs := [][]*vm.Instruction{} + + for i, byteCode := range byteCodes { + instrs, err := loadFunction(byteCode) + if err != nil { + return nil, errors.Wrapf(err, "At function index %d", i) + } + + fncs = append(fncs, instrs) + } + + return fncs, nil +} + +func loadFunction(byteCode []byte) ([]*vm.Instruction, error) { + instrs := []*vm.Instruction{} + + for start := 0; start < len(byteCode); start += instructionBytes { + chunk := byteCode[start : start+instructionBytes] + + instr, err := loadInstruction(chunk) + if err != nil { + return nil, errors.Wrapf(err, "At byte offset %d", start) + } + + instrs = append(instrs, instr) + } + + return instrs, nil +} + +func loadInstruction(byteCode []byte) (*vm.Instruction, error) { + instr := &vm.Instruction{} + + reader := bytes.NewReader(byteCode) + + err := struc.Unpack(reader, instr) + if err != nil { + return nil, errors.Wrap(err, "Error decoding instruction") + } + + return instr, nil +} diff --git a/test/load_test.go b/test/load_test.go new file mode 100644 index 0000000..9007a2c --- /dev/null +++ b/test/load_test.go @@ -0,0 +1,12 @@ +package test + +import "testing" + +import "github.com/firestuff/subcoding/load" + +func TestLoad(t *testing.T) { + _, err := load.Load(nil) + if err != nil { + t.Fatal(err) + } +} diff --git a/vm/instruction.go b/vm/instruction.go index 3b21965..ff472b2 100644 --- a/vm/instruction.go +++ b/vm/instruction.go @@ -1,10 +1,5 @@ package vm -import "bytes" - -import "github.com/lunixbochs/struc" -import "github.com/pkg/errors" - type Instruction struct { OpCode OpCodeType Reserved [4]byte @@ -13,33 +8,3 @@ type Instruction struct { opHandler opHandler `struc:"skip"` } - -const instructionBytes = 32 - -func NewInstructionFromByteCode(byteCode []byte) (*Instruction, error) { - instr := &Instruction{} - - reader := bytes.NewReader(byteCode) - - err := struc.Unpack(reader, instr) - if err != nil { - return nil, errors.Wrap(err, "Error decoding instruction") - } - - return instr, nil -} - -func NewInstructionsFromByteCode(byteCode []byte) ([]*Instruction, error) { - instrs := []*Instruction{} - - for start := 0; start < len(byteCode); start += instructionBytes { - chunk := byteCode[start : start+instructionBytes] - instr, err := NewInstructionFromByteCode(chunk) - if err != nil { - return nil, errors.Wrapf(err, "At byte offset %d", start) - } - instrs = append(instrs, instr) - } - - return instrs, nil -} diff --git a/vm/state.go b/vm/state.go index eea02cf..a075b5d 100644 --- a/vm/state.go +++ b/vm/state.go @@ -2,8 +2,6 @@ package vm import "fmt" -import "github.com/pkg/errors" - type State struct { running bool err error @@ -24,21 +22,6 @@ func NewState(functions [][]*Instruction) (*State, error) { }, nil } -func NewStateFromByteCode(byteCodes [][]byte) (*State, error) { - functions := [][]*Instruction{} - - for i, byteCode := range byteCodes { - instrs, err := NewInstructionsFromByteCode(byteCode) - if err != nil { - return nil, errors.Wrapf(err, "At function index %d", i) - } - - functions = append(functions, instrs) - } - - return NewState(functions) -} - func (state *State) Execute() error { state.setHandlers() state.call(0)