1package parser 2 3type Pos int 4 5const NoPos Pos = 0 6 7type Node interface { 8 Dump() string 9 Pos() Pos 10 End() Pos 11} 12 13type Assignment struct { 14 Target *MakeString 15 Name *MakeString 16 Value *MakeString 17 Type string 18} 19 20func (x *Assignment) Dump() string { 21 target := "" 22 if x.Target != nil { 23 target = x.Target.Dump() + ": " 24 } 25 return target + x.Name.Dump() + " " + x.Type + " " + x.Value.Dump() 26} 27 28func (x *Assignment) Pos() Pos { 29 if x.Target != nil { 30 return x.Target.Pos() 31 } 32 return x.Name.Pos() 33} 34 35func (x *Assignment) End() Pos { return x.Value.End() } 36 37type Comment struct { 38 CommentPos Pos 39 Comment string 40} 41 42func (x *Comment) Dump() string { 43 return "#" + x.Comment 44} 45 46func (x *Comment) Pos() Pos { return x.CommentPos } 47func (x *Comment) End() Pos { return Pos(int(x.CommentPos) + len(x.Comment)) } 48 49type Directive struct { 50 NamePos Pos 51 Name string 52 Args *MakeString 53 EndPos Pos 54} 55 56func (x *Directive) Dump() string { 57 return x.Name + " " + x.Args.Dump() 58} 59 60func (x *Directive) Pos() Pos { return x.NamePos } 61func (x *Directive) End() Pos { 62 if x.EndPos != NoPos { 63 return x.EndPos 64 } 65 return x.Args.End() 66} 67 68type Rule struct { 69 Target *MakeString 70 Prerequisites *MakeString 71 RecipePos Pos 72 Recipe string 73} 74 75func (x *Rule) Dump() string { 76 recipe := "" 77 if x.Recipe != "" { 78 recipe = "\n" + x.Recipe 79 } 80 return "rule: " + x.Target.Dump() + ": " + x.Prerequisites.Dump() + recipe 81} 82 83func (x *Rule) Pos() Pos { return x.Target.Pos() } 84func (x *Rule) End() Pos { return Pos(int(x.RecipePos) + len(x.Recipe)) } 85 86type Variable struct { 87 Name *MakeString 88} 89 90func (x *Variable) Pos() Pos { return x.Name.Pos() } 91func (x *Variable) End() Pos { return x.Name.End() } 92 93func (x *Variable) Dump() string { 94 return "$(" + x.Name.Dump() + ")" 95} 96 97// Sort interface for []Node by position 98type byPosition []Node 99 100func (s byPosition) Len() int { 101 return len(s) 102} 103 104func (s byPosition) Swap(i, j int) { 105 s[i], s[j] = s[j], s[i] 106} 107 108func (s byPosition) Less(i, j int) bool { 109 return s[i].Pos() < s[j].Pos() 110} 111