{
// Package asmgoto implements a practical use case for GlobalStore feature.
//
// Very simplistic assembler language, only containing noop and jump instructions.
// Jump instructions use labels as target, which may be defined optionally on ever code line.
//
// GlobalStore is used to keep track of the labels as well as the unresolved targets for jump instructions.
//
// Example:
//     label: noop
//     jump label
//
package asmgoto

func toIfaceSlice(v interface{}) []interface{} {
    if v == nil {
        return nil
    }
    return v.([]interface{})
}
}

Program ← lines:Line* EOF &{ return labelCheck(c) } {
  lines0 := toIfaceSlice(lines)
  asmLines := make([]Instruction, 0, len(lines0))
  for _, line := range lines0 {
    asmLines = append(asmLines, line.(Instruction))
  }
  return asmLines, nil
}

Line ← _ inst:Instruction _ (nl / EOF) {
  return inst, nil
}

Instruction ← Label? _ op:( Noop / Jump ) {
  return op, nil
}

Label ← l:labelIdentifier ":" {
  l0 := l.(string)
  addLabel(c, l0)
  return nil, nil
}

labelIdentifier ← [a-z][a-z0-9]* {
  return string(c.text), nil
}

Noop ← "noop" {
  return Noop{}, nil
}

Jump ← "jump" __ label:labelIdentifier {
  label0 := label.(string)
  j := addJump(c, label0)
  return j, nil
}

nl "newline" ← [\n\r]+

__ "whitespace" ← [ \t]+

_ "optional whitespace" ← [ \t]*

EOF ← !.