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 }