Fix rule_in_var.mk

Now we parse rules at eval time, not in parse time.
diff --git a/ast.go b/ast.go
index 33ef5be..2997aea 100644
--- a/ast.go
+++ b/ast.go
@@ -47,38 +47,26 @@
 	Log("%s=%s", ast.lhs, ast.rhs)
 }
 
-type RuleAST struct {
+// Note we cannot be sure what this is, until all variables in |expr|
+// are expanded.
+type MaybeRuleAST struct {
 	ASTBase
-	lhs       string
-	rhs       string
+	expr      string
 	cmds      []string
 	cmdLineno int
 }
 
-func (ast *RuleAST) eval(ev *Evaluator) {
-	ev.evalRule(ast)
+func (ast *MaybeRuleAST) eval(ev *Evaluator) {
+	ev.evalMaybeRule(ast)
 }
 
-func (ast *RuleAST) show() {
-	Log("%s: %s", ast.lhs, ast.rhs)
+func (ast *MaybeRuleAST) show() {
+	Log("%s", ast.expr)
 	for _, cmd := range ast.cmds {
 		Log("\t%s", cmd)
 	}
 }
 
-type RawExprAST struct {
-	ASTBase
-	expr string
-}
-
-func (ast *RawExprAST) eval(ev *Evaluator) {
-	ev.evalRawExpr(ast)
-}
-
-func (ast *RawExprAST) show() {
-	Log("%s", ast.expr)
-}
-
 type IncludeAST struct {
 	ASTBase
 	expr string
diff --git a/eval.go b/eval.go
index e0e1dd4..060763c 100644
--- a/eval.go
+++ b/eval.go
@@ -132,18 +132,32 @@
 	ev.outVars[lhs] = rhs
 }
 
-func (ev *Evaluator) evalRule(ast *RuleAST) {
+func (ev *Evaluator) evalMaybeRule(ast *MaybeRuleAST) {
 	ev.filename = ast.filename
 	ev.lineno = ast.lineno
 
+	line := ev.evalExpr(ast.expr)
+	if strings.TrimSpace(line) == "" {
+		if len(ast.cmds) > 0 {
+			Error(ast.filename, ast.cmdLineno, "*** commands commence before first target.")
+		}
+		return
+	}
+
 	ev.curRule = &Rule{
 		filename:  ast.filename,
 		lineno:    ast.lineno,
 		cmdLineno: ast.cmdLineno,
 	}
-	lhs := ev.evalExpr(ast.lhs)
+
+	colonIndex := strings.IndexByte(line, ':')
+	if colonIndex < 0 {
+		Error(ast.filename, ast.lineno, "*** missing separator.")
+	}
+
+	lhs := line[:colonIndex]
 	ev.curRule.output = lhs
-	rhs := strings.TrimSpace(ev.evalExpr(ast.rhs))
+	rhs := strings.TrimSpace(line[colonIndex+1:])
 	if rhs != "" {
 		re, err := regexp.Compile(`\s+`)
 		if err != nil {
@@ -155,12 +169,13 @@
 	for _, cmd := range ast.cmds {
 		cmds = append(cmds, ev.evalExpr(cmd))
 	}
-	Log("RULE: %s=%s", lhs, rhs)
+	Log("RULE: %s=%s (%d commands)", lhs, rhs, len(cmds))
 	ev.curRule.cmds = cmds
 	ev.outRules = append(ev.outRules, ev.curRule)
 	ev.curRule = nil
 }
 
+/*
 func (ev *Evaluator) evalRawExpr(ast *RawExprAST) {
 	ev.filename = ast.filename
 	ev.lineno = ast.lineno
@@ -171,6 +186,7 @@
 		Error(ast.filename, ast.lineno, "*** missing separator.")
 	}
 }
+*/
 
 func (ev *Evaluator) getVar(name string) (string, bool) {
 	value, present := ev.outVars[name]
diff --git a/parser.go b/parser.go
index 2f7af91..9fd5eef 100644
--- a/parser.go
+++ b/parser.go
@@ -110,12 +110,16 @@
 	return ast
 }
 
-func (p *parser) parseRule(line []byte, sep int) AST {
-	lhs := string(bytes.TrimSpace(line[:sep]))
-	rhs := string(bytes.TrimSpace(line[sep+1:]))
-	ast := &RuleAST{
-		lhs: lhs,
-		rhs: rhs,
+func (p *parser) parseMaybeRule(line string) AST {
+	if len(strings.TrimSpace(line)) == 0 {
+		return nil
+	}
+	if line[0] == '\t' {
+		Error(p.filename, p.lineno, "*** commands commence before first target.")
+	}
+
+	ast := &MaybeRuleAST{
+		expr: line,
 	}
 	ast.filename = p.filename
 	ast.lineno = p.lineno
@@ -312,13 +316,6 @@
 	return false
 }
 
-func (p *parser) parseLine(line string) AST {
-	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 {
@@ -339,7 +336,7 @@
 				if i+1 < len(line) && line[i+1] == '=' {
 					ast = p.parseAssign(line, i, i+2)
 				} else {
-					ast = p.parseRule(line, i)
+					ast = p.parseMaybeRule(string(line))
 				}
 			case '=':
 				ast = p.parseAssign(line, i, i+1)
@@ -353,9 +350,11 @@
 				break
 			}
 		}
-		if ast == nil && len(bytes.TrimSpace(line)) > 0 {
-			ast = p.parseLine(string(line))
-			p.addStatement(ast)
+		if ast == nil {
+			ast = p.parseMaybeRule(string(line))
+			if ast != nil {
+				p.addStatement(ast)
+			}
 		}
 	}
 	return p.mk, nil
diff --git a/test/err_no_target_commands.mk b/test/err_no_target_commands.mk
new file mode 100644
index 0000000..2113a57
--- /dev/null
+++ b/test/err_no_target_commands.mk
@@ -0,0 +1 @@
+	all:
diff --git a/test/err_no_target_commands2.mk b/test/err_no_target_commands2.mk
new file mode 100644
index 0000000..47570b1
--- /dev/null
+++ b/test/err_no_target_commands2.mk
@@ -0,0 +1,2 @@
+$(empty)
+	all:
diff --git a/test/rule_in_var.mk b/test/rule_in_var.mk
index c527cb5..caf4303 100644
--- a/test/rule_in_var.mk
+++ b/test/rule_in_var.mk
@@ -1,5 +1,3 @@
-# TODO: Implement this. We probably need this.
-
 RULE=foo:
 
 test: foo