| // 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() | 
 | } |