Conditional return instructions
This commit is contained in:
@@ -3,10 +3,8 @@ package asm
|
||||
import "github.com/firestuff/subcoding/vm"
|
||||
|
||||
var opCodeByName = map[string]vm.OpCodeType{
|
||||
"noop": vm.OpNoOp,
|
||||
"nop": vm.OpNop,
|
||||
"return": vm.OpReturn,
|
||||
"ret": vm.OpRet,
|
||||
"noop": vm.OpNoOp,
|
||||
"nop": vm.OpNop,
|
||||
|
||||
"move": vm.OpMove,
|
||||
"mov": vm.OpMov,
|
||||
@@ -53,6 +51,13 @@ var opCodeByName = map[string]vm.OpCodeType{
|
||||
"calt": vm.OpCalT,
|
||||
"calliffalse": vm.OpCallIfFalse,
|
||||
"calf": vm.OpCalF,
|
||||
|
||||
"return": vm.OpReturn,
|
||||
"ret": vm.OpRet,
|
||||
"returniftrue": vm.OpReturnIfTrue,
|
||||
"rett": vm.OpRetT,
|
||||
"returniffalse": vm.OpReturnIfFalse,
|
||||
"retf": vm.OpRetF,
|
||||
}
|
||||
|
||||
type operandType int
|
||||
@@ -66,7 +71,6 @@ const (
|
||||
|
||||
var operandsByOpCode = map[vm.OpCodeType][]operandType{
|
||||
vm.OpNop: []operandType{},
|
||||
vm.OpRet: []operandType{},
|
||||
|
||||
vm.OpMov: []operandType{r, us},
|
||||
vm.OpAdd: []operandType{r, us},
|
||||
@@ -92,4 +96,8 @@ var operandsByOpCode = map[vm.OpCodeType][]operandType{
|
||||
vm.OpCal: []operandType{s},
|
||||
vm.OpCalT: []operandType{s},
|
||||
vm.OpCalF: []operandType{s},
|
||||
|
||||
vm.OpRet: []operandType{},
|
||||
vm.OpRetT: []operandType{},
|
||||
vm.OpRetF: []operandType{},
|
||||
}
|
||||
|
||||
@@ -11,21 +11,6 @@ functions:
|
||||
expectGlobalMemory(t, state, 0, 0)
|
||||
}
|
||||
|
||||
func TestRet(t *testing.T) {
|
||||
state := assembleAndExecute(t, `
|
||||
functions:
|
||||
- - [cal, +1]
|
||||
- [add, g0, 1]
|
||||
- [ret]
|
||||
|
||||
- - [mov, g0, 5]
|
||||
- [ret]
|
||||
- [add, g0, 2]
|
||||
`)
|
||||
|
||||
expectGlobalMemory(t, state, 0, 6)
|
||||
}
|
||||
|
||||
func TestMov(t *testing.T) {
|
||||
state := assembleAndExecute(t, `
|
||||
functions:
|
||||
@@ -360,3 +345,54 @@ functions:
|
||||
|
||||
expectGlobalMemory(t, state, 0, 16)
|
||||
}
|
||||
|
||||
func TestRet(t *testing.T) {
|
||||
state := assembleAndExecute(t, `
|
||||
functions:
|
||||
- - [cal, +1]
|
||||
- [add, g0, 1]
|
||||
- [ret]
|
||||
|
||||
- - [mov, g0, 5]
|
||||
- [ret]
|
||||
- [add, g0, 2]
|
||||
`)
|
||||
|
||||
expectGlobalMemory(t, state, 0, 6)
|
||||
}
|
||||
|
||||
func TestRetT(t *testing.T) {
|
||||
state := assembleAndExecute(t, `
|
||||
functions:
|
||||
- - [cal, +1]
|
||||
- [add, g0, 1]
|
||||
|
||||
- - [add, g0, 2]
|
||||
- [eq, 0, 0]
|
||||
- [rett]
|
||||
- [add, g0, 4]
|
||||
- [eq, 0, 1]
|
||||
- [rett]
|
||||
- [add, g0, 8]
|
||||
`)
|
||||
|
||||
expectGlobalMemory(t, state, 0, 3)
|
||||
}
|
||||
|
||||
func TestRetF(t *testing.T) {
|
||||
state := assembleAndExecute(t, `
|
||||
functions:
|
||||
- - [cal, +1]
|
||||
- [add, g0, 1]
|
||||
|
||||
- - [add, g0, 2]
|
||||
- [eq, 0, 0]
|
||||
- [retf]
|
||||
- [add, g0, 4]
|
||||
- [eq, 0, 1]
|
||||
- [retf]
|
||||
- [add, g0, 8]
|
||||
`)
|
||||
|
||||
expectGlobalMemory(t, state, 0, 7)
|
||||
}
|
||||
|
||||
13
vm/opcode.go
13
vm/opcode.go
@@ -3,10 +3,8 @@ package vm
|
||||
type OpCodeType uint32
|
||||
|
||||
const (
|
||||
OpNoOp OpCodeType = 0x00000000
|
||||
OpNop = OpNoOp
|
||||
OpReturn = 0x00000002
|
||||
OpRet = OpReturn
|
||||
OpNoOp OpCodeType = 0x00000000
|
||||
OpNop = OpNoOp
|
||||
|
||||
OpMove = 0x00000100
|
||||
OpMov = OpMove
|
||||
@@ -53,4 +51,11 @@ const (
|
||||
OpCalT = OpCallIfTrue
|
||||
OpCallIfFalse = 0x00000502
|
||||
OpCalF = OpCallIfFalse
|
||||
|
||||
OpReturn = 0x00000600
|
||||
OpRet = OpReturn
|
||||
OpReturnIfTrue = 0x00000601
|
||||
OpRetT = OpReturnIfTrue
|
||||
OpReturnIfFalse = 0x00000602
|
||||
OpRetF = OpReturnIfFalse
|
||||
)
|
||||
|
||||
@@ -3,8 +3,7 @@ package vm
|
||||
type opHandler func(*State, *Instruction)
|
||||
|
||||
var opHandlers = map[OpCodeType]opHandler{
|
||||
OpNoOp: (*State).handleNoOp,
|
||||
OpReturn: (*State).handleReturn,
|
||||
OpNoOp: (*State).handleNoOp,
|
||||
|
||||
OpMove: (*State).handleMove,
|
||||
|
||||
@@ -31,15 +30,15 @@ var opHandlers = map[OpCodeType]opHandler{
|
||||
OpCall: (*State).handleCall,
|
||||
OpCallIfTrue: (*State).handleCallIfTrue,
|
||||
OpCallIfFalse: (*State).handleCallIfFalse,
|
||||
|
||||
OpReturn: (*State).handleReturn,
|
||||
OpReturnIfTrue: (*State).handleReturnIfTrue,
|
||||
OpReturnIfFalse: (*State).handleReturnIfFalse,
|
||||
}
|
||||
|
||||
func (state *State) handleNoOp(instr *Instruction) {
|
||||
}
|
||||
|
||||
func (state *State) handleReturn(instr *Instruction) {
|
||||
state.ret()
|
||||
}
|
||||
|
||||
func (state *State) handleMove(instr *Instruction) {
|
||||
in := state.readUnsigned(&instr.Operand2)
|
||||
state.writeUnsigned(&instr.Operand1, in)
|
||||
@@ -162,3 +161,19 @@ func (state *State) handleCallIfFalse(instr *Instruction) {
|
||||
state.handleCall(instr)
|
||||
}
|
||||
}
|
||||
|
||||
func (state *State) handleReturn(instr *Instruction) {
|
||||
state.ret()
|
||||
}
|
||||
|
||||
func (state *State) handleReturnIfTrue(instr *Instruction) {
|
||||
if state.comparisonResult == true {
|
||||
state.handleReturn(instr)
|
||||
}
|
||||
}
|
||||
|
||||
func (state *State) handleReturnIfFalse(instr *Instruction) {
|
||||
if state.comparisonResult == false {
|
||||
state.handleReturn(instr)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user