cue: add optional fields

Optional fields are crucial in making it manageable
to work with very large struct types, like those of
Kubernetes. Without optional fields, the fields of
a simple K8s configuration  would be lost in the noise
compared to the default value of every expanded field.

It also allows writing:
  foo?: MyStruct
instead of
  foo: *null | MyStruct
which gets old quickly when one has hundreds of
such fields.

Updates #24

Change-Id: I856d9a3e20584750b911784924fa18d4557b9920
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/1700
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cue/ast.go b/cue/ast.go
index b6924b4..5e02b9e 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -112,7 +112,7 @@
 	ctx := v.ctx()
 	label := v.label(n.Name, true)
 	if r := v.resolveRoot; r != nil {
-		if value, _ := r.lookup(v.ctx(), label); value != nil {
+		if a := r.lookup(v.ctx(), label); a.val() != nil {
 			return &selectorExpr{newExpr(n),
 				&nodeRef{baseValue: newExpr(n), node: r}, label}
 		}
@@ -252,6 +252,7 @@
 		v.object.comprehensions = append(v.object.comprehensions, fc)
 
 	case *ast.Field:
+		opt := n.Optional != token.NoPos
 		switch x := n.Label.(type) {
 		case *ast.Interpolation:
 			yielder := &yield{baseValue: newNode(x)}
@@ -261,6 +262,7 @@
 			}
 			yielder.key = v.walk(x)
 			yielder.value = v.walk(n.Value)
+			yielder.opt = opt
 			v.object.comprehensions = append(v.object.comprehensions, fc)
 
 		case *ast.TemplateLabel:
@@ -289,7 +291,7 @@
 				return v.error(n.Label, "invalid field name: %v", n.Label)
 			}
 			if f != 0 {
-				v.object.insertValue(v.ctx(), f, v.walk(n.Value), attrs)
+				v.object.insertValue(v.ctx(), f, opt, v.walk(n.Value), attrs)
 			}
 
 		default: