ronnie
2022-10-23 fcca8e734726472c54304e97e653ae7e87a0c976
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
// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
 
package parser
 
type Pos int
 
const NoPos Pos = 0
 
type Node interface {
   Dump() string
   Pos() Pos
   End() Pos
}
 
type Assignment struct {
   Target *MakeString
   Name   *MakeString
   Value  *MakeString
   Type   string
}
 
func (x *Assignment) Dump() string {
   target := ""
   if x.Target != nil {
       target = x.Target.Dump() + ": "
   }
   return target + x.Name.Dump() + " " + x.Type + " " + x.Value.Dump()
}
 
func (x *Assignment) Pos() Pos {
   if x.Target != nil {
       return x.Target.Pos()
   }
   return x.Name.Pos()
}
 
func (x *Assignment) End() Pos { return x.Value.End() }
 
type Comment struct {
   CommentPos Pos
   Comment    string
}
 
func (x *Comment) Dump() string {
   return "#" + x.Comment
}
 
func (x *Comment) Pos() Pos { return x.CommentPos }
func (x *Comment) End() Pos { return Pos(int(x.CommentPos) + len(x.Comment)) }
 
type Directive struct {
   NamePos Pos
   Name    string
   Args    *MakeString
   EndPos  Pos
}
 
func (x *Directive) Dump() string {
   return x.Name + " " + x.Args.Dump()
}
 
func (x *Directive) Pos() Pos { return x.NamePos }
func (x *Directive) End() Pos {
   if x.EndPos != NoPos {
       return x.EndPos
   }
   return x.Args.End()
}
 
type Rule struct {
   Target        *MakeString
   Prerequisites *MakeString
   RecipePos     Pos
   Recipe        string
}
 
func (x *Rule) Dump() string {
   recipe := ""
   if x.Recipe != "" {
       recipe = "\n" + x.Recipe
   }
   return "rule:       " + x.Target.Dump() + ": " + x.Prerequisites.Dump() + recipe
}
 
func (x *Rule) Pos() Pos { return x.Target.Pos() }
func (x *Rule) End() Pos { return Pos(int(x.RecipePos) + len(x.Recipe)) }
 
type Variable struct {
   Name *MakeString
}
 
func (x *Variable) Pos() Pos { return x.Name.Pos() }
func (x *Variable) End() Pos { return x.Name.End() }
 
func (x *Variable) Dump() string {
   return "$(" + x.Name.Dump() + ")"
}
 
// Sort interface for []Node by position
type byPosition []Node
 
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() < s[j].Pos()
}