Implement += and ?=
diff --git a/ast.go b/ast.go
index f4dd83f..fe8e21f 100644
--- a/ast.go
+++ b/ast.go
@@ -23,14 +23,23 @@
 	ev.evalAssign(ast)
 }
 
-func (ast *AssignAST) evalRHS(ev *Evaluator) string {
+func (ast *AssignAST) evalRHS(ev *Evaluator, lhs string) string {
 	switch ast.op {
 	case ":=":
 		return ev.evalExpr(ast.rhs)
 	case "=":
 		return ast.rhs
-	default: // "+=", "?="
-		panic(fmt.Sprintf("not implemented assign op: %q", ast.op))
+	case "+=":
+		prev, _ := ev.getVar(lhs)
+		return fmt.Sprintf("%s %s", prev, ev.evalExpr(ast.rhs))
+	case "?=":
+		prev, present := ev.getVar(lhs)
+		if present {
+			return prev
+		}
+		return ev.evalExpr(ast.rhs)
+	default:
+		panic(fmt.Sprintf("unknown assign op: %q", ast.op))
 	}
 }
 
diff --git a/eval.go b/eval.go
index dbff80f..6f092cc 100644
--- a/eval.go
+++ b/eval.go
@@ -120,7 +120,7 @@
 	ev.lineno = ast.lineno
 
 	lhs := ev.evalExpr(ast.lhs)
-	rhs := ast.evalRHS(ev)
+	rhs := ast.evalRHS(ev, lhs)
 	Log("ASSIGN: %s=%s", lhs, rhs)
 	ev.outVars[lhs] = rhs
 }
@@ -165,6 +165,18 @@
 	}
 }
 
+func (ev *Evaluator) getVar(name string) (string, bool) {
+	value, present := ev.outVars[name]
+	if present {
+		return value, true
+	}
+	value, present = ev.vars[name]
+	if present {
+		return value, true
+	}
+	return "", false
+}
+
 func (ev *Evaluator) getVars() map[string]string {
 	vars := make(map[string]string)
 	for k, v := range ev.vars {
diff --git a/parser.go b/parser.go
index 3f9c5a2..4b93928 100644
--- a/parser.go
+++ b/parser.go
@@ -164,8 +164,10 @@
 				}
 			case '=':
 				ast = p.parseAssign(line, i, i+1)
-			case '?':
-				panic("TODO")
+			case '?', '+':
+				if i+1 < len(line) && line[i+1] == '=' {
+					ast = p.parseAssign(line, i, i+2)
+				}
 			}
 			if ast != nil {
 				p.mk.stmts = append(p.mk.stmts, ast)
diff --git a/test/assign_types.mk b/test/assign_types.mk
index adbceee..4ceaecd 100644
--- a/test/assign_types.mk
+++ b/test/assign_types.mk
@@ -2,6 +2,10 @@
 B = $(A)
 C := $(A)
 A = aa
+D = b
+D += b
+E ?= c
+E ?= d
 
 test:
-	echo $(B) $(C)
+	echo $(B) $(C) $(D) $(E)