78 lines
1.9 KiB
Go
78 lines
1.9 KiB
Go
|
|
package pass
|
||
|
|
|
||
|
|
import (
|
||
|
|
"reflect"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/mmcloughlin/avo"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestLabelTarget(t *testing.T) {
|
||
|
|
expect := map[avo.Label]*avo.Instruction{
|
||
|
|
"lblA": &avo.Instruction{Opcode: "A"},
|
||
|
|
"lblB": &avo.Instruction{Opcode: "B"},
|
||
|
|
}
|
||
|
|
|
||
|
|
f := avo.NewFunction("happypath")
|
||
|
|
for lbl, i := range expect {
|
||
|
|
f.AddLabel(lbl)
|
||
|
|
f.AddInstruction(i)
|
||
|
|
f.AddInstruction(&avo.Instruction{Opcode: "IDK"})
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := LabelTarget(f); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if !reflect.DeepEqual(expect, f.LabelTarget) {
|
||
|
|
t.Fatalf("incorrect LabelTarget value\ngot=%#v\nexpext=%#v\n", f.LabelTarget, expect)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLabelTargetDuplicate(t *testing.T) {
|
||
|
|
f := avo.NewFunction("dupelabel")
|
||
|
|
f.AddLabel(avo.Label("lblA"))
|
||
|
|
f.AddInstruction(&avo.Instruction{Opcode: "A"})
|
||
|
|
f.AddLabel(avo.Label("lblA"))
|
||
|
|
f.AddInstruction(&avo.Instruction{Opcode: "A"})
|
||
|
|
|
||
|
|
err := LabelTarget(f)
|
||
|
|
|
||
|
|
if err == nil || err.Error() != "duplicate label \"lblA\"" {
|
||
|
|
t.Fatalf("expected error on duplcate label; got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLabelTargetEndsWithLabel(t *testing.T) {
|
||
|
|
f := avo.NewFunction("endswithlabel")
|
||
|
|
f.AddInstruction(&avo.Instruction{Opcode: "A"})
|
||
|
|
f.AddLabel(avo.Label("theend"))
|
||
|
|
|
||
|
|
err := LabelTarget(f)
|
||
|
|
|
||
|
|
if err == nil || err.Error() != "function ends with label" {
|
||
|
|
t.Fatalf("expected error when function ends with label; got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLabelTargetInstructionFollowLabel(t *testing.T) {
|
||
|
|
f := avo.NewFunction("expectinstafterlabel")
|
||
|
|
f.AddLabel(avo.Label("lblA"))
|
||
|
|
f.AddLabel(avo.Label("lblB"))
|
||
|
|
f.AddInstruction(&avo.Instruction{Opcode: "A"})
|
||
|
|
|
||
|
|
err := LabelTarget(f)
|
||
|
|
|
||
|
|
if err == nil || err.Error() != "instruction should follow a label" {
|
||
|
|
t.Fatalf("expected error when label is not followed by instruction; got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestCFG(t *testing.T) {
|
||
|
|
// TODO(mbm): jump backward
|
||
|
|
// TODO(mbm): jump forward
|
||
|
|
// TODO(mbm): multiple returns
|
||
|
|
// TODO(mbm): infinite loop
|
||
|
|
// TODO(mbm): very short infinite loop
|
||
|
|
}
|