Add soong_build primary builder

Initial build logic for building android with soong.  It can build
a variety of C and C++ files for arm/arm64 and host.

Change-Id: I10eb37c2c2a50be6af1bb5fd568c0962b9476bf0
diff --git a/androidmk/parser/makething.go b/androidmk/parser/makething.go
new file mode 100644
index 0000000..7d60a77
--- /dev/null
+++ b/androidmk/parser/makething.go
@@ -0,0 +1,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
+}