| package parser |
| |
| import ( |
| "text/scanner" |
| ) |
| |
| type MakeThing interface { |
| AsAssignment() (Assignment, bool) |
| AsComment() (Comment, bool) |
| AsDirective() (Directive, bool) |
| AsRule() (Rule, bool) |
| AsVariable() (Variable, bool) |
| Dump() string |
| Pos() scanner.Position |
| EndPos() scanner.Position |
| } |
| |
| type Assignment struct { |
| makeThing |
| Name *MakeString |
| Value *MakeString |
| Target *MakeString |
| Type string |
| } |
| |
| type Comment struct { |
| makeThing |
| Comment string |
| } |
| |
| type Directive struct { |
| makeThing |
| Name string |
| Args *MakeString |
| } |
| |
| type Rule struct { |
| makeThing |
| Target *MakeString |
| Prerequisites *MakeString |
| Recipe string |
| } |
| |
| type Variable struct { |
| makeThing |
| Name *MakeString |
| } |
| |
| type makeThing struct { |
| pos scanner.Position |
| endPos scanner.Position |
| } |
| |
| func (m makeThing) Pos() scanner.Position { |
| return m.pos |
| } |
| |
| func (m makeThing) EndPos() scanner.Position { |
| return m.endPos |
| } |
| |
| func (makeThing) AsAssignment() (a Assignment, ok bool) { |
| return |
| } |
| |
| func (a Assignment) AsAssignment() (Assignment, bool) { |
| return a, true |
| } |
| |
| func (a Assignment) Dump() string { |
| target := "" |
| if a.Target != nil { |
| target = a.Target.Dump() + ": " |
| } |
| return target + a.Name.Dump() + a.Type + a.Value.Dump() |
| } |
| |
| func (makeThing) AsComment() (c Comment, ok bool) { |
| return |
| } |
| |
| func (c Comment) AsComment() (Comment, bool) { |
| return c, true |
| } |
| |
| func (c Comment) Dump() string { |
| return "#" + c.Comment |
| } |
| |
| func (makeThing) AsDirective() (d Directive, ok bool) { |
| return |
| } |
| |
| func (d Directive) AsDirective() (Directive, bool) { |
| return d, true |
| } |
| |
| func (d Directive) Dump() string { |
| return d.Name + " " + d.Args.Dump() |
| } |
| |
| func (makeThing) AsRule() (r Rule, ok bool) { |
| return |
| } |
| |
| func (r Rule) AsRule() (Rule, bool) { |
| return r, true |
| } |
| |
| func (r Rule) Dump() string { |
| recipe := "" |
| if r.Recipe != "" { |
| recipe = "\n" + r.Recipe |
| } |
| return "rule: " + r.Target.Dump() + ": " + r.Prerequisites.Dump() + recipe |
| } |
| |
| func (makeThing) AsVariable() (v Variable, ok bool) { |
| return |
| } |
| |
| func (v Variable) AsVariable() (Variable, bool) { |
| return v, true |
| } |
| |
| func (v Variable) Dump() string { |
| return "$(" + v.Name.Dump() + ")" |
| } |
| |
| type byPosition []MakeThing |
| |
| func (s byPosition) Len() int { |
| return len(s) |
| } |
| |
| func (s byPosition) Swap(i, j int) { |
| s[i], s[j] = s[j], s[i] |
| } |
| |
| func (s byPosition) Less(i, j int) bool { |
| return s[i].Pos().Offset < s[j].Pos().Offset |
| } |