Very naive implementation of include
diff --git a/ast.go b/ast.go
index 4525136..f623c39 100644
--- a/ast.go
+++ b/ast.go
@@ -68,3 +68,17 @@
func (ast *RawExprAST) show() {
Log("%s", ast.expr)
}
+
+type IncludeAST struct {
+ ASTBase
+ expr string
+ op string
+}
+
+func (ast *IncludeAST) eval(ev *Evaluator) {
+ ev.evalInclude(ast)
+}
+
+func (ast *IncludeAST) show() {
+ Log("include %s", ast.expr)
+}
diff --git a/eval.go b/eval.go
index 040995a..acaf588 100644
--- a/eval.go
+++ b/eval.go
@@ -31,11 +31,11 @@
lineno int
}
-func newEvaluator() *Evaluator {
+func newEvaluator(vars map[string]string) *Evaluator {
return &Evaluator{
outVars: make(map[string]string),
refs: make(map[string]bool),
- vars: make(map[string]string),
+ vars: vars,
funcs: map[string]Func{
"wildcard": funcWildcard,
"shell": funcShell,
@@ -153,12 +153,56 @@
}
}
+func (ev *Evaluator) getVars() map[string]string {
+ vars := make(map[string]string)
+ for k, v := range ev.vars {
+ vars[k] = v
+ }
+ for k, v := range ev.outVars {
+ vars[k] = v
+ }
+ return vars
+}
+
+func (ev *Evaluator) evalInclude(ast *IncludeAST) {
+ ev.filename = ast.filename
+ ev.lineno = ast.lineno
+
+ // TODO: Handle glob
+ files := strings.Split(ev.evalExpr(ast.expr), " ")
+ for _, file := range files {
+ mk, err := ParseMakefile(file)
+ if err != nil {
+ if ast.op == "include" {
+ panic(err)
+ } else {
+ continue
+ }
+ }
+
+ er, err2 := Eval(mk, ev.getVars())
+ if err2 != nil {
+ panic(err2)
+ }
+
+ for k, v := range er.vars {
+ ev.outVars[k] = v
+ }
+ for _, r := range er.rules {
+ ev.outRules = append(ev.outRules, r)
+ }
+ for r, _ := range er.refs {
+ ev.refs[r] = true
+ }
+ }
+}
+
func (ev *Evaluator) eval(ast AST) {
ast.eval(ev)
}
-func Eval(mk Makefile) (er *EvalResult, err error) {
- ev := newEvaluator()
+func Eval(mk Makefile, vars map[string]string) (er *EvalResult, err error) {
+ ev := newEvaluator(vars)
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
diff --git a/main.go b/main.go
index ab2b48e..8620f7e 100644
--- a/main.go
+++ b/main.go
@@ -12,7 +12,8 @@
stmt.show()
}
- er, err := Eval(mk)
+ vars := make(map[string]string)
+ er, err := Eval(mk, vars)
if err != nil {
panic(err)
}
diff --git a/parser.go b/parser.go
index 4a45b6f..5fff8aa 100644
--- a/parser.go
+++ b/parser.go
@@ -7,6 +7,7 @@
"fmt"
"io"
"os"
+ "strings"
)
type Makefile struct {
@@ -119,6 +120,29 @@
return ast
}
+func (p *parser) parseInclude(line string, oplen int) AST {
+ ast := &IncludeAST{
+ expr: line[oplen+1:],
+ op: line[:oplen],
+ }
+ ast.filename = p.filename
+ ast.lineno = p.lineno
+ return ast
+}
+
+func (p *parser) parseLine(line string) AST {
+ if strings.HasPrefix(line, "include ") {
+ return p.parseInclude(line, len("include"))
+ }
+ if strings.HasPrefix(line, "-include ") {
+ return p.parseInclude(line, len("-include"))
+ }
+ ast := &RawExprAST{expr: line}
+ ast.filename = p.filename
+ ast.lineno = p.lineno
+ return ast
+}
+
func (p *parser) parse() (mk Makefile, err error) {
defer func() {
if r := recover(); r != nil {
@@ -148,10 +172,8 @@
}
}
if ast == nil && len(bytes.TrimSpace(line)) > 0 {
- a := &RawExprAST{expr: string(line)}
- a.filename = p.filename
- a.lineno = p.lineno
- p.mk.stmts = append(p.mk.stmts, a)
+ ast = p.parseLine(string(line))
+ p.mk.stmts = append(p.mk.stmts, ast)
}
}
return p.mk, nil
diff --git a/test/include.mk b/test/include.mk
index d8df92d..9ac8f5b 100644
--- a/test/include.mk
+++ b/test/include.mk
@@ -1,5 +1,3 @@
-# TODO: Fix
-
test1:
echo "foo: bar" > foo.d