1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
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
}
|