| Colin Cross | 08693d2 | 2016-05-25 17:25:40 -0700 | [diff] [blame] | 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 | } | 
| Colin Cross | 5126504 | 2016-05-27 12:45:17 -0700 | [diff] [blame] | 25 | return target + x.Name.Dump() + " " + x.Type + " " + x.Value.Dump() | 
| Colin Cross | 08693d2 | 2016-05-25 17:25:40 -0700 | [diff] [blame] | 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 | } |