pass: allow consecutive labels (#123)

Fixes #122
This commit is contained in:
Michael McLoughlin
2020-01-19 22:06:52 -08:00
committed by GitHub
parent cde7e9483b
commit ff7a160610
8 changed files with 123 additions and 19 deletions

View File

@@ -11,26 +11,22 @@ import (
// label name to the following instruction.
func LabelTarget(fn *ir.Function) error {
target := map[ir.Label]*ir.Instruction{}
var empty ir.Label
pending := empty
var pending []ir.Label
for _, node := range fn.Nodes {
switch n := node.(type) {
case ir.Label:
if pending != empty {
return fmt.Errorf("expected instruction following label %q", pending)
}
pending = n
if _, found := target[pending]; found {
return fmt.Errorf("duplicate label \"%s\"", pending)
if _, found := target[n]; found {
return fmt.Errorf("duplicate label \"%s\"", n)
}
pending = append(pending, n)
case *ir.Instruction:
if pending != empty {
target[pending] = n
pending = empty
for _, label := range pending {
target[label] = n
}
pending = nil
}
}
if pending != empty {
if len(pending) != 0 {
return errors.New("function ends with label")
}
fn.LabelTarget = target

View File

@@ -58,16 +58,25 @@ func TestLabelTargetEndsWithLabel(t *testing.T) {
}
}
func TestLabelTargetInstructionFollowLabel(t *testing.T) {
f := ir.NewFunction("expectinstafterlabel")
func TestLabelTargetConsecutiveLabels(t *testing.T) {
i := &ir.Instruction{Opcode: "A"}
f := ir.NewFunction("consecutivelabels")
f.AddLabel(ir.Label("lblA"))
f.AddLabel(ir.Label("lblB"))
f.AddInstruction(&ir.Instruction{Opcode: "A"})
f.AddInstruction(i)
err := LabelTarget(f)
expect := map[ir.Label]*ir.Instruction{
"lblA": i,
"lblB": i,
}
if err == nil || err.Error() != "expected instruction following label \"lblA\"" {
t.Fatalf("expected error when label is not followed by instruction; got %v", err)
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)
}
}