1package parser 2 3import ( 4 "text/scanner" 5) 6 7type MakeThing interface { 8 AsAssignment() (Assignment, bool) 9 AsComment() (Comment, bool) 10 AsDirective() (Directive, bool) 11 AsRule() (Rule, bool) 12 AsVariable() (Variable, bool) 13 Dump() string 14 Pos() scanner.Position 15 EndPos() scanner.Position 16} 17 18type Assignment struct { 19 makeThing 20 Name *MakeString 21 Value *MakeString 22 Target *MakeString 23 Type string 24} 25 26type Comment struct { 27 makeThing 28 Comment string 29} 30 31type Directive struct { 32 makeThing 33 Name string 34 Args *MakeString 35} 36 37type Rule struct { 38 makeThing 39 Target *MakeString 40 Prerequisites *MakeString 41 Recipe string 42} 43 44type Variable struct { 45 makeThing 46 Name *MakeString 47} 48 49type makeThing struct { 50 pos scanner.Position 51 endPos scanner.Position 52} 53 54func (m makeThing) Pos() scanner.Position { 55 return m.pos 56} 57 58func (m makeThing) EndPos() scanner.Position { 59 return m.endPos 60} 61 62func (makeThing) AsAssignment() (a Assignment, ok bool) { 63 return 64} 65 66func (a Assignment) AsAssignment() (Assignment, bool) { 67 return a, true 68} 69 70func (a Assignment) Dump() string { 71 target := "" 72 if a.Target != nil { 73 target = a.Target.Dump() + ": " 74 } 75 return target + a.Name.Dump() + a.Type + a.Value.Dump() 76} 77 78func (makeThing) AsComment() (c Comment, ok bool) { 79 return 80} 81 82func (c Comment) AsComment() (Comment, bool) { 83 return c, true 84} 85 86func (c Comment) Dump() string { 87 return "#" + c.Comment 88} 89 90func (makeThing) AsDirective() (d Directive, ok bool) { 91 return 92} 93 94func (d Directive) AsDirective() (Directive, bool) { 95 return d, true 96} 97 98func (d Directive) Dump() string { 99 return d.Name + " " + d.Args.Dump() 100} 101 102func (makeThing) AsRule() (r Rule, ok bool) { 103 return 104} 105 106func (r Rule) AsRule() (Rule, bool) { 107 return r, true 108} 109 110func (r Rule) Dump() string { 111 recipe := "" 112 if r.Recipe != "" { 113 recipe = "\n" + r.Recipe 114 } 115 return "rule: " + r.Target.Dump() + ": " + r.Prerequisites.Dump() + recipe 116} 117 118func (makeThing) AsVariable() (v Variable, ok bool) { 119 return 120} 121 122func (v Variable) AsVariable() (Variable, bool) { 123 return v, true 124} 125 126func (v Variable) Dump() string { 127 return "$(" + v.Name.Dump() + ")" 128} 129 130type byPosition []MakeThing 131 132func (s byPosition) Len() int { 133 return len(s) 134} 135 136func (s byPosition) Swap(i, j int) { 137 s[i], s[j] = s[j], s[i] 138} 139 140func (s byPosition) Less(i, j int) bool { 141 return s[i].Pos().Offset < s[j].Pos().Offset 142} 143