cue: implementation of marked defaults

Change-Id: I7b0ed2b1e372a71410cbd05253ca819f08509a2a
diff --git a/cue/ast.go b/cue/ast.go
index 43a3616..013b119 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -457,6 +457,9 @@
 		value = call
 
 	case *ast.UnaryExpr:
+		if n.Op == token.MUL {
+			return v.error(n, "preference mark not allowed at this position")
+		}
 		value = &unaryExpr{
 			newExpr(n),
 			tokenMap[n.Op],
@@ -466,7 +469,10 @@
 	case *ast.BinaryExpr:
 		switch n.Op {
 		case token.DISJUNCTION:
-			value = makeDisjunction(v.ctx(), n, v.walk(n.X), v.walk(n.Y))
+			d := &disjunction{baseValue: newExpr(n)}
+			v.addDisjunctionElem(d, n.X, false)
+			v.addDisjunctionElem(d, n.Y, false)
+			value = d
 		case token.RANGE:
 			value = &rangeLit{
 				newExpr(n),
@@ -493,6 +499,23 @@
 	return value
 }
 
+func (v *astVisitor) addDisjunctionElem(d *disjunction, n ast.Node, mark bool) {
+	switch x := n.(type) {
+	case *ast.BinaryExpr:
+		if x.Op == token.DISJUNCTION {
+			v.addDisjunctionElem(d, x.X, mark)
+			v.addDisjunctionElem(d, x.Y, mark)
+			return
+		}
+	case *ast.UnaryExpr:
+		if x.Op == token.MUL {
+			mark = true
+			n = x.X
+		}
+	}
+	d.values = append(d.values, dValue{v.walk(n), mark})
+}
+
 func wrapClauses(v *astVisitor, y yielder, clauses []ast.Clause) yielder {
 	for _, c := range clauses {
 		if n, ok := c.(*ast.ForClause); ok {