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