Files
avo/pass/cfg_test.go
2018-12-02 13:51:03 -08:00

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
}