internal/core/compile: add new compiler

compile: compiler, but still needs support for builtins and imports

debug: debug representation of internal structures

runtime: just string uniquing functionality for now

cuetxtar: added txtar support, including auto --update and --todo
support.

Change-Id: Idadf6045867b55381f0b3e0da3bc772fa40f7a04
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5840
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast/ast.go b/cue/ast/ast.go
index e7aec5e..ab8ce36 100644
--- a/cue/ast/ast.go
+++ b/cue/ast/ast.go
@@ -740,7 +740,7 @@
 // Useful for ASTs generated by code other than the CUE parser.
 func NewBinExpr(op token.Token, operands ...Expr) Expr {
 	if len(operands) == 0 {
-		panic("must specify at least one expression")
+		return nil
 	}
 	expr := operands[0]
 	for _, e := range operands[1:] {
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index 2c30c64..5a394be 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -2457,7 +2457,7 @@
 			`c1: (<2>{a: 1, b: 2} | <3>{a: 2, b: 1}), ` +
 			`c2: (<4>{a: 2, b: 1} | <5>{a: 1, b: 2})}`,
 	}, {
-		desc: "don't convert incomplete errors to non-incomplete",
+		desc: "dont convert incomplete errors to non-incomplete",
 		in: `
 		import "strings"
 
@@ -2865,7 +2865,7 @@
 			`c1: <1>{bar: <2>{baz: 2}, baz: 2}, ` +
 			`c2: _|_(conflicting values {bar: 1} and 1 (mismatched types struct and int))}`,
 	}, {
-		desc: "don't bind to string labels",
+		desc: "dont bind to string labels",
 		in: `
 			x: 1
 			y: {
@@ -2875,7 +2875,7 @@
 			`,
 		out: `<0>{x: 1, y: <1>{x: 2, z: 1}}`,
 	}, {
-		desc: "don't pass incomplete values to builtins",
+		desc: "dont pass incomplete values to builtins",
 		in: `
 		import "encoding/json"
 
diff --git a/cue/testdata/basicrewrite/000_errors.txtar b/cue/testdata/basicrewrite/000_errors.txtar
index ca4b21e..353eb21 100644
--- a/cue/testdata/basicrewrite/000_errors.txtar
+++ b/cue/testdata/basicrewrite/000_errors.txtar
@@ -16,3 +16,12 @@
 e: true
 -- out/legacy-debug --
 <0>{a: _|_(from source), b: _|_(from source), c: true, d: false, e: true}
+-- out/compile --
+--- in.cue
+{
+  a: (_|_ & _|_)
+  b: (null & _|_)
+  c: (〈0;b〉.a == _|_)
+  d: (_|_ != 〈0;b〉.a)
+  e: (_|_ == _|_)
+}
diff --git a/cue/testdata/basicrewrite/001_regexp.txtar b/cue/testdata/basicrewrite/001_regexp.txtar
index d8fad38..3ae91fd 100644
--- a/cue/testdata/basicrewrite/001_regexp.txtar
+++ b/cue/testdata/basicrewrite/001_regexp.txtar
@@ -39,3 +39,24 @@
 e3: _|_ // conflicting values !="a" and <5 (mismatched types string and number)
 -- out/legacy-debug --
 <0>{c1: true, c2: true, c3: false, c4: true, b1: "a", b2: "foo", b3: _|_((=~"[a-z]{4}" & "foo"):invalid value "foo" (does not match =~"[a-z]{4}")), b4: "foo", s1: =~"c", s2: (!="b" & =~"[a-z]"), e1: _|_(("foo" =~ 1):invalid operation "foo" =~ 1 (mismatched types string and int)), e2: _|_(("foo" !~ true):invalid operation "foo" !~ true (mismatched types string and bool)), e3: _|_((!="a" & <5):conflicting values !="a" and <5 (mismatched types string and number))}
+-- out/compile --
+--- in.cue
+{
+  c1: ("a" =~ "a")
+  c2: ("foo" =~ "[a-z]{3}")
+  c3: ("foo" =~ "[a-z]{4}")
+  c4: ("foo" !~ "[a-z]{4}")
+  b1: =~"a"
+  b1: "a"
+  b2: =~"[a-z]{3}"
+  b2: "foo"
+  b3: =~"[a-z]{4}"
+  b3: "foo"
+  b4: !~"[a-z]{4}"
+  b4: "foo"
+  s1: (!="b" & =~"c")
+  s2: (!="b" & =~"[a-z]")
+  e1: ("foo" =~ 1)
+  e2: ("foo" !~ true)
+  e3: (!="a" & <5)
+}
diff --git a/cue/testdata/basicrewrite/002_arithmetic.txtar b/cue/testdata/basicrewrite/002_arithmetic.txtar
index e76baf1..c6ad611 100644
--- a/cue/testdata/basicrewrite/002_arithmetic.txtar
+++ b/cue/testdata/basicrewrite/002_arithmetic.txtar
@@ -66,3 +66,30 @@
 e8: _|_ // invalid operation 1.0 mod 1 (mismatched types float and int)
 -- out/legacy-debug --
 <0>{i1: 1, i2: 2, sum: 1, div1: 4.00000000000000000000000, div2: 4.00000000000000000000000, div3: 1., divZero: _|_((1.0 / 0):division by zero), div00: _|_((0 / 0):division undefined), b: true, add: 5.00000000000000000000000, idiv00: _|_((0 div 0):division by zero), imod00: _|_((0 mod 0):division by zero), iquo00: _|_((0 quo 0):division by zero), irem00: _|_((0 rem 0):division by zero), v1: 5.0000000000e+11, v2: true, v3: 0.666666666666666666666667, v5: 0, e0: _|_((2 + "a"):invalid operation 2 + "a" (mismatched types int and string)), e5: _|_((1.0 div 2):invalid operation 1.0 div 2 (mismatched types float and int)), e6: _|_((2 rem 2.0):invalid operation 2 rem 2.0 (mismatched types int and float)), e7: _|_((2 quo 2.0):invalid operation 2 quo 2.0 (mismatched types int and float)), e8: _|_((1.0 mod 1):invalid operation 1.0 mod 1 (mismatched types float and int))}
+-- out/compile --
+--- in.cue
+{
+  i1: (1 & int)
+  i2: (2 & int)
+  sum: (-1 + +2)
+  div1: ((2.0 / 3) * 6)
+  div2: ((2 / 3) * 6)
+  div3: (1.00 / 1.00)
+  divZero: (1.0 / 0)
+  div00: (0 / 0)
+  b: (1 != 4)
+  add: (〈0;div1〉 + 1.0)
+  idiv00: (0 div 0)
+  imod00: (0 mod 0)
+  iquo00: (0 quo 0)
+  irem00: (0 rem 0)
+  v1: (1000000000000 / 2.0)
+  v2: (2.0 == 2)
+  v3: (2.0 / 3.0)
+  v5: (〈0;i1〉 div 〈0;i2〉)
+  e0: (2 + "a")
+  e5: (1.0 div 2)
+  e6: (2 rem 2.0)
+  e7: (2 quo 2.0)
+  e8: (1.0 mod 1)
+}
diff --git a/cue/testdata/basicrewrite/003_integer-specific_arithmetic.txtar b/cue/testdata/basicrewrite/003_integer-specific_arithmetic.txtar
index ef3acec..02c94b1 100644
--- a/cue/testdata/basicrewrite/003_integer-specific_arithmetic.txtar
+++ b/cue/testdata/basicrewrite/003_integer-specific_arithmetic.txtar
@@ -57,3 +57,31 @@
 me2: _|_ // invalid operation 2 mod 1.0 (mismatched types int and float)
 -- out/legacy-debug --
 <0>{q1: 2, q2: -2, q3: -2, q4: 2, qe1: _|_((2.0 quo 1):invalid operation 2.0 quo 1 (mismatched types float and int)), qe2: _|_((2 quo 1.0):invalid operation 2 quo 1.0 (mismatched types int and float)), r1: 1, r2: 1, r3: -1, r4: -1, re1: _|_((2.0 rem 1):invalid operation 2.0 rem 1 (mismatched types float and int)), re2: _|_((2 rem 1.0):invalid operation 2 rem 1.0 (mismatched types int and float)), d1: 2, d2: -2, d3: -3, d4: 3, de1: _|_((2.0 div 1):invalid operation 2.0 div 1 (mismatched types float and int)), de2: _|_((2 div 1.0):invalid operation 2 div 1.0 (mismatched types int and float)), m1: 1, m2: 1, m3: 1, m4: 1, me1: _|_((2.0 mod 1):invalid operation 2.0 mod 1 (mismatched types float and int)), me2: _|_((2 mod 1.0):invalid operation 2 mod 1.0 (mismatched types int and float))}
+-- out/compile --
+--- in.cue
+{
+  q1: (5 quo 2)
+  q2: (5 quo -2)
+  q3: (-5 quo 2)
+  q4: (-5 quo -2)
+  qe1: (2.0 quo 1)
+  qe2: (2 quo 1.0)
+  r1: (5 rem 2)
+  r2: (5 rem -2)
+  r3: (-5 rem 2)
+  r4: (-5 rem -2)
+  re1: (2.0 rem 1)
+  re2: (2 rem 1.0)
+  d1: (5 div 2)
+  d2: (5 div -2)
+  d3: (-5 div 2)
+  d4: (-5 div -2)
+  de1: (2.0 div 1)
+  de2: (2 div 1.0)
+  m1: (5 mod 2)
+  m2: (5 mod -2)
+  m3: (-5 mod 2)
+  m4: (-5 mod -2)
+  me1: (2.0 mod 1)
+  me2: (2 mod 1.0)
+}
diff --git a/cue/testdata/basicrewrite/004_booleans.txtar b/cue/testdata/basicrewrite/004_booleans.txtar
index eaa5542..7764733 100644
--- a/cue/testdata/basicrewrite/004_booleans.txtar
+++ b/cue/testdata/basicrewrite/004_booleans.txtar
@@ -15,3 +15,13 @@
 e: _|_ // conflicting values true and false
 -- out/legacy-debug --
 <0>{t: true, f: false, e: _|_(true:conflicting values true and false)}
+-- out/compile --
+--- in.cue
+{
+  t: true
+  t: !false
+  f: false
+  f: !〈0;t〉
+  e: true
+  e: !true
+}
diff --git a/cue/testdata/basicrewrite/005_boolean_arithmetic.txtar b/cue/testdata/basicrewrite/005_boolean_arithmetic.txtar
index 1f96a59..a56a1a9 100644
--- a/cue/testdata/basicrewrite/005_boolean_arithmetic.txtar
+++ b/cue/testdata/basicrewrite/005_boolean_arithmetic.txtar
@@ -18,3 +18,13 @@
 f: _|_ // conflicting values true and false
 -- out/legacy-debug --
 <0>{a: true, b: true, c: false, d: true, e: true, f: _|_(true:conflicting values true and false)}
+-- out/compile --
+--- in.cue
+{
+  a: (true && true)
+  b: (true || false)
+  c: (false == true)
+  d: (false != true)
+  e: (true & true)
+  f: (true & false)
+}
diff --git a/cue/testdata/basicrewrite/006_basic_type.txtar b/cue/testdata/basicrewrite/006_basic_type.txtar
index 651f134..3e465d5 100644
--- a/cue/testdata/basicrewrite/006_basic_type.txtar
+++ b/cue/testdata/basicrewrite/006_basic_type.txtar
@@ -20,3 +20,15 @@
 f: true
 -- out/legacy-debug --
 <0>{a: 1, b: 1, c: 1.0, d: _|_((int & float):conflicting values int and float (mismatched types int and float)), e: "4", f: true}
+-- out/compile --
+--- in.cue
+{
+  a: (1 & int)
+  b: (number & 1)
+  c: 1.0
+  c: float
+  d: (int & float)
+  e: ("4" & string)
+  f: true
+  f: bool
+}
diff --git a/cue/testdata/basicrewrite/007_strings_and_bytes.txtar b/cue/testdata/basicrewrite/007_strings_and_bytes.txtar
index 1d3b842..3a43fbc 100644
--- a/cue/testdata/basicrewrite/007_strings_and_bytes.txtar
+++ b/cue/testdata/basicrewrite/007_strings_and_bytes.txtar
@@ -27,3 +27,15 @@
 e1: _|_ // invalid operation 'b' + "c" (mismatched types bytes and string)
 -- out/legacy-debug --
 <0>{s0: "foobar", s1: "abcabcabc", s2: "abcabc", b0: 'foobar', b1: 'abcabcabc', b2: 'abcabc', e0: _|_(("a" + ''):invalid operation "a" + '' (mismatched types string and bytes)), e1: _|_(('b' + "c"):invalid operation 'b' + "c" (mismatched types bytes and string))}
+-- out/compile --
+--- in.cue
+{
+  s0: ("foo" + "bar")
+  s1: (3 * "abc")
+  s2: ("abc" * 2)
+  b0: ('foo' + 'bar')
+  b1: (3 * 'abc')
+  b2: ('abc' * 2)
+  e0: ("a" + '')
+  e1: ('b' + "c")
+}
diff --git a/cue/testdata/basicrewrite/008_escaping.txtar b/cue/testdata/basicrewrite/008_escaping.txtar
index 5a02e06..ab9dc40 100644
--- a/cue/testdata/basicrewrite/008_escaping.txtar
+++ b/cue/testdata/basicrewrite/008_escaping.txtar
@@ -36,3 +36,9 @@
 {"a":"foo\nbar","b":"foo\nbar"}
 -- out/legacy-debug --
 <0>{a: "foo\nbar", b: "foo\nbar"}
+-- out/compile --
+--- in.cue
+{
+  a: "foo\nbar"
+  b: 〈0;a〉
+}
diff --git a/cue/testdata/basicrewrite/009_reference.txtar b/cue/testdata/basicrewrite/009_reference.txtar
index b113beb..b5ad55b 100644
--- a/cue/testdata/basicrewrite/009_reference.txtar
+++ b/cue/testdata/basicrewrite/009_reference.txtar
@@ -62,3 +62,21 @@
 {"a":2,"b":2,"d":{"d":3,"e":3},"e":{"e":{"v":1},"f":{"v":1}}}
 -- out/legacy-debug --
 <0>{a: 2, b: 2, d: <1>{d: 3, e: 3}, e: <2>{e: <3>{v: 1}, f: <4>{v: 1}}}
+-- out/compile --
+--- in.cue
+{
+  a: 〈0;b〉
+  b: 2
+  d: {
+    d: 3
+    e: 〈0;d〉
+  }
+  e: {
+    e: {
+      v: 1
+    }
+    f: {
+      v: 〈1;e〉.v
+    }
+  }
+}
diff --git a/cue/testdata/basicrewrite/010_lists.txtar b/cue/testdata/basicrewrite/010_lists.txtar
index d8f6c7b..577e592 100644
--- a/cue/testdata/basicrewrite/010_lists.txtar
+++ b/cue/testdata/basicrewrite/010_lists.txtar
@@ -24,3 +24,53 @@
 ]
 -- out/legacy-debug --
 <0>{list: [1,2,3], index: 2, unify: [1,2,3], e: _|_(([] & 4):conflicting values [] and 4 (mismatched types list and int)), e2: _|_("d":invalid list index "d" (type string)), e3: _|_(-1:invalid list index -1 (index must be non-negative)), e4: [1,2,4,_|_((<=5 & 8):invalid value 8 (out of bound <=5))], e5: [1,2,4,_|_((<=5 & 8):invalid value 8 (out of bound <=5))]}
+-- out/compile --
+--- in.cue
+{
+  list: [
+    1,
+    2,
+    3,
+  ]
+  index: [
+    1,
+    2,
+    3,
+  ][1]
+  unify: ([
+    1,
+    2,
+    3,
+  ] & [
+    _,
+    2,
+    3,
+  ])
+  e: ([] & 4)
+  e2: [
+    3,
+  ]["d"]
+  e3: [
+    3,
+  ][-1]
+  e4: ([
+    1,
+    2,
+    ...(>=4 & <=5),
+  ] & [
+    1,
+    2,
+    4,
+    8,
+  ])
+  e5: ([
+    1,
+    2,
+    4,
+    8,
+  ] & [
+    1,
+    2,
+    ...(>=4 & <=5),
+  ])
+}
diff --git a/cue/testdata/basicrewrite/011_list_arithmetic.txtar b/cue/testdata/basicrewrite/011_list_arithmetic.txtar
index 2b95dd3..826caaa 100644
--- a/cue/testdata/basicrewrite/011_list_arithmetic.txtar
+++ b/cue/testdata/basicrewrite/011_list_arithmetic.txtar
@@ -24,3 +24,22 @@
 e: _|_ // negative number -1 multiplies list
 -- out/legacy-debug --
 <0>{list: [1,2,3], mul0: [], mul1: [1,2,3], mul2: [1,2,3,1,2,3], list1: [1], mul1_0: [], mul1_1: [1], mul1_2: [1,1], e: _|_((<1>.list * -1):negative number -1 multiplies list)}
+-- out/compile --
+--- in.cue
+{
+  list: [
+    1,
+    2,
+    3,
+  ]
+  mul0: (〈0;list〉 * 0)
+  mul1: (〈0;list〉 * 1)
+  mul2: (2 * 〈0;list〉)
+  list1: [
+    1,
+  ]
+  mul1_0: (〈0;list1〉 * 0)
+  mul1_1: (1 * 〈0;list1〉)
+  mul1_2: (〈0;list1〉 * 2)
+  e: (〈0;list〉 * -1)
+}
diff --git a/cue/testdata/basicrewrite/012_selecting.txtar b/cue/testdata/basicrewrite/012_selecting.txtar
index 216d810..71a0e98 100644
--- a/cue/testdata/basicrewrite/012_selecting.txtar
+++ b/cue/testdata/basicrewrite/012_selecting.txtar
@@ -27,3 +27,34 @@
 h: _|_ // invalid operation: [3].b (type list does not support selection)
 -- out/legacy-debug --
 <0>{obj: <1>{a: 1, b: 2}, index: 2, mulidx: 3, e: _|_(4:invalid struct index 4 (type int)), f: <2>{a: 1}.b, g: <3>{a: 1}["b"], h: _|_([3]:invalid operation: [3].b (type list does not support selection))}
+-- out/compile --
+--- in.cue
+{
+  obj: {
+    a: 1
+    b: 2
+  }
+  index: {
+    a: 1
+    b: 2
+  }["b"]
+  mulidx: {
+    a: 1
+    b: {
+      a: 1
+      b: 3
+    }
+  }["b"]["b"]
+  e: {
+    a: 1
+  }[4]
+  f: {
+    a: 1
+  }.b
+  g: {
+    a: 1
+  }["b"]
+  h: [
+    3,
+  ].b
+}
diff --git a/cue/testdata/basicrewrite/013_obj_unify.txtar b/cue/testdata/basicrewrite/013_obj_unify.txtar
index dceb8c2..a34e7f0 100644
--- a/cue/testdata/basicrewrite/013_obj_unify.txtar
+++ b/cue/testdata/basicrewrite/013_obj_unify.txtar
@@ -31,3 +31,45 @@
 e: _|_ // conflicting values 1 and {a: 3} (mismatched types int and struct)
 -- out/legacy-debug --
 <0>{o1: <1>{a: 1, b: 2}, o2: <2>{a: 1, b: 2}, o3: <3>{a: 1, b: 2}, o4: <4>{a: 1, b: 2}, e: _|_((1 & <5>{a: 3}):conflicting values 1 and {a: 3} (mismatched types int and struct))}
+-- out/compile --
+--- in.cue
+{
+  o1: ({
+    a: 1
+  } & {
+    b: 2
+  })
+  o2: ({
+    a: 1
+    b: 2
+  } & {
+    b: 2
+  })
+  o3: ({
+    a: 1
+  } & {
+    a: 1
+    b: 2
+  })
+  o4: ({
+    a: 1
+  } & {
+    b: 2
+  })
+  o4: ({
+    a: 1
+    b: 2
+  } & {
+    b: 2
+  })
+  o4: ({
+    a: 1
+  } & {
+    a: 1
+    b: 2
+  })
+  e: 1
+  e: {
+    a: 3
+  }
+}
diff --git a/cue/testdata/basicrewrite/014_disjunctions.txtar b/cue/testdata/basicrewrite/014_disjunctions.txtar
index 7d5a40c..887eae2 100644
--- a/cue/testdata/basicrewrite/014_disjunctions.txtar
+++ b/cue/testdata/basicrewrite/014_disjunctions.txtar
@@ -56,3 +56,26 @@
 i1: "c"
 -- out/legacy-debug --
 <0>{o1: (1 | 2 | 3), o2: 1, o3: 2, o4: (1 | 2 | 3 | *_|_), o5: (1 | *2 | 3), o6: (1 | 2 | 3), o7: (2 | 3), o8: (2 | 3), o9: (2 | 3), o10: (3 | *2), m1: (*2 | 3), m2: (*2 | 3), m3: (*2 | 3), m4: (*2 | 3), m5: (*2 | 3), i1: "c"}
+-- out/compile --
+--- in.cue
+{
+  o1: (1|2|3)
+  o2: ((1|2|3) & 1)
+  o3: (2 & (1|*2|3))
+  o4: ((1|*2|3) & (1|2|*3))
+  o5: ((1|*2|3) & (3|*2|1))
+  o6: ((1|2|3) & (3|1|2))
+  o7: ((1|2|3) & (2|3))
+  o8: ((1|2|3) & (3|2))
+  o9: ((2|3) & (1|2|3))
+  o10: ((3|2) & (1|*2|3))
+  m1: ((*1|(*2|3)) & (>=2 & <=3))
+  m2: ((*1|(*2|3)) & (2|3))
+  m3: ((*1|*(*2|3)) & (2|3))
+  m4: ((2|3) & (*2|3))
+  m5: ((*2|3) & (2|3))
+  i1: ([
+    1,
+    2,
+  ][3]|"c")
+}
diff --git a/cue/testdata/basicrewrite/015_types.txtar b/cue/testdata/basicrewrite/015_types.txtar
index 684bcc6..a1c6fb1 100644
--- a/cue/testdata/basicrewrite/015_types.txtar
+++ b/cue/testdata/basicrewrite/015_types.txtar
@@ -24,3 +24,16 @@
 m:  _|_ // invalid operation -false (- bool)
 -- out/legacy-debug --
 <0>{i: int, j: 3, s: string, t: "s", e: _|_((int & string):conflicting values int and string (mismatched types int and string)), e2: _|_((1 & string):conflicting values 1 and string (mismatched types int and string)), b: _|_(!int:invalid operation !int (! int)), p: _|_(+true:invalid operation +true (+ bool)), m: _|_(-false:invalid operation -false (- bool))}
+-- out/compile --
+--- in.cue
+{
+  i: int
+  j: (int & 3)
+  s: string
+  t: ("s" & string)
+  e: (int & string)
+  e2: (1 & string)
+  b: !int
+  p: +true
+  m: -false
+}
diff --git a/cue/testdata/basicrewrite/016_comparison.txtar b/cue/testdata/basicrewrite/016_comparison.txtar
index 9c85001..e927f6b 100644
--- a/cue/testdata/basicrewrite/016_comparison.txtar
+++ b/cue/testdata/basicrewrite/016_comparison.txtar
@@ -23,3 +23,16 @@
 err: _|_ // invalid operation 2 == "s" (mismatched types int and string)
 -- out/legacy-debug --
 <0>{lss: true, leq: true, eql: true, neq: true, gtr: true, geq: true, seq: true, err: _|_((2 == "s"):invalid operation 2 == "s" (mismatched types int and string))}
+-- out/compile --
+--- in.cue
+{
+  lss: (1 < 2)
+  leq: (1 <= 1.0)
+  leq: (2.0 <= 3)
+  eql: (1 == 1.0)
+  neq: (1.0 == 1)
+  gtr: !(2 > 3)
+  geq: (2.0 >= 2)
+  seq: (("a" + "b") == "ab")
+  err: (2 == "s")
+}
diff --git a/cue/testdata/basicrewrite/017_null.txtar b/cue/testdata/basicrewrite/017_null.txtar
index 38ddb51..966c49e 100644
--- a/cue/testdata/basicrewrite/017_null.txtar
+++ b/cue/testdata/basicrewrite/017_null.txtar
@@ -24,3 +24,14 @@
 call: _|_ // cannot call non-function null (type null)
 -- out/legacy-debug --
 <0>{eql: true, neq: false, unf: null, eq1: false, eq2: false, ne1: true, call: _|_(null:cannot call non-function null (type null))}
+-- out/compile --
+--- in.cue
+{
+  eql: (null == null)
+  neq: (null != null)
+  unf: (null & null)
+  eq1: (null == 1)
+  eq2: (1 == null)
+  ne1: ("s" != null)
+  call: null()
+}
diff --git a/cue/testdata/basicrewrite/018_self-reference_cycles.txtar b/cue/testdata/basicrewrite/018_self-reference_cycles.txtar
index fc428bf..30912f8 100644
--- a/cue/testdata/basicrewrite/018_self-reference_cycles.txtar
+++ b/cue/testdata/basicrewrite/018_self-reference_cycles.txtar
@@ -13,3 +13,13 @@
 c: [c[1], c[0]]
 -- out/legacy-debug --
 <0>{a: (<1>.b - 100), b: (<1>.a + 100), c: [<1>.c[1],<1>.c[0]]}
+-- out/compile --
+--- in.cue
+{
+  a: (〈0;b〉 - 100)
+  b: (〈0;a〉 + 100)
+  c: [
+    〈0;c〉[1],
+    〈0;c〉[0],
+  ]
+}
diff --git a/cue/testdata/basicrewrite/019_resolved_self-reference_cycles.txtar b/cue/testdata/basicrewrite/019_resolved_self-reference_cycles.txtar
index 337da3d..951c97d 100644
--- a/cue/testdata/basicrewrite/019_resolved_self-reference_cycles.txtar
+++ b/cue/testdata/basicrewrite/019_resolved_self-reference_cycles.txtar
@@ -66,3 +66,23 @@
 {"a":100,"b":200,"c":[100,100],"s1":{"a":1,"b":2,"c":3},"s2":{"a":1,"b":2,"c":3},"s3":{"a":1,"b":2,"c":3}}
 -- out/legacy-debug --
 <0>{a: 100, b: 200, c: [100,100], s1: <1>{a: 1, b: 2, c: 3}, s2: <2>{a: 1, b: 2, c: 3}, s3: <3>{a: 1, b: 2, c: 3}}
+-- out/compile --
+--- in.cue
+{
+  a: (〈0;b〉 - 100)
+  b: (〈0;a〉 + 100)
+  b: 200
+  c: [
+    〈0;c〉[1],
+    〈0;a〉,
+  ]
+  s1: (〈0;s2〉 & {
+    a: 1
+  })
+  s2: (〈0;s3〉 & {
+    b: 2
+  })
+  s3: (〈0;s1〉 & {
+    c: 3
+  })
+}
diff --git a/cue/testdata/basicrewrite/020_resolved_self-reference_cycles__Issue_19.txtar b/cue/testdata/basicrewrite/020_resolved_self-reference_cycles__Issue_19.txtar
index 701db61..b25bad3 100644
--- a/cue/testdata/basicrewrite/020_resolved_self-reference_cycles__Issue_19.txtar
+++ b/cue/testdata/basicrewrite/020_resolved_self-reference_cycles__Issue_19.txtar
@@ -38,3 +38,14 @@
 {"x":200,"y":100,"z1":11,"z2":10,"z3":8}
 -- out/legacy-debug --
 <0>{x: 200, y: 100, z1: 11, z2: 10, z3: 8}
+-- out/compile --
+--- in.cue
+{
+  x: (〈0;y〉 + 100)
+  y: (〈0;x〉 - 100)
+  x: 200
+  z1: (〈0;z2〉 + 1)
+  z2: (〈0;z3〉 + 2)
+  z3: (〈0;z1〉 - 3)
+  z3: 8
+}
diff --git a/cue/testdata/basicrewrite/021_delayed_constraint_failure.txtar b/cue/testdata/basicrewrite/021_delayed_constraint_failure.txtar
index 7bc334e..e35cec9 100644
--- a/cue/testdata/basicrewrite/021_delayed_constraint_failure.txtar
+++ b/cue/testdata/basicrewrite/021_delayed_constraint_failure.txtar
@@ -15,3 +15,12 @@
 b: _|_ // conflicting values 210 and 200
 -- out/legacy-debug --
 <0>{x: _|_((100 & 101):conflicting values 100 and 101), a: _|_((210 & 200):conflicting values 210 and 200), b: _|_((210 & 200):conflicting values 210 and 200)}
+-- out/compile --
+--- in.cue
+{
+  a: (〈0;b〉 - 100)
+  b: (〈0;a〉 + 110)
+  b: 200
+  x: 100
+  x: (〈0;x〉 + 1)
+}
diff --git a/cue/testdata/choosedefault/000_pick_first.txtar b/cue/testdata/choosedefault/000_pick_first.txtar
index 61c0009..47105f2 100644
--- a/cue/testdata/choosedefault/000_pick_first.txtar
+++ b/cue/testdata/choosedefault/000_pick_first.txtar
@@ -33,3 +33,15 @@
 {"a":5,"b":{"c":{"a":2}}}
 -- out/legacy-debug --
 <0>{a: 5, b: <1>{c: <2>{a: 2}}}
+-- out/compile --
+--- in.cue
+{
+  a: (*5|"a"|true)
+  b: {
+    c: (*{
+      a: 2
+    }|{
+      a: 3
+    })
+  }
+}
diff --git a/cue/testdata/choosedefault/001_simple_disambiguation_conflict.txtar b/cue/testdata/choosedefault/001_simple_disambiguation_conflict.txtar
index 5cc03ac..66e83d3 100644
--- a/cue/testdata/choosedefault/001_simple_disambiguation_conflict.txtar
+++ b/cue/testdata/choosedefault/001_simple_disambiguation_conflict.txtar
@@ -12,3 +12,10 @@
 c: a & b
 -- out/legacy-debug --
 <0>{a: "a", b: "b", c: ("a" | "b")}
+-- out/compile --
+--- in.cue
+{
+  a: (*"a"|"b")
+  b: (*"b"|"a")
+  c: (〈0;a〉 & 〈0;b〉)
+}
diff --git a/cue/testdata/choosedefault/002_associativity_of_defaults.txtar b/cue/testdata/choosedefault/002_associativity_of_defaults.txtar
index e06d112..96647f7 100644
--- a/cue/testdata/choosedefault/002_associativity_of_defaults.txtar
+++ b/cue/testdata/choosedefault/002_associativity_of_defaults.txtar
@@ -16,3 +16,12 @@
 c: *"a" | *"b" | "c"
 -- out/legacy-debug --
 <0>{x: "a", y: (*"a" | *"b"), a: "a", b: "a", c: (*"a" | *"b")}
+-- out/compile --
+--- in.cue
+{
+  a: (*"a"|("b"|"c"))
+  b: ((*"a"|"b")|"c")
+  c: (*"a"|(*"b"|"c"))
+  x: (〈0;a〉 & 〈0;b〉)
+  y: (〈0;b〉 & 〈0;c〉)
+}
diff --git a/cue/testdata/compile/erralias.txtar b/cue/testdata/compile/erralias.txtar
new file mode 100644
index 0000000..deccc61
--- /dev/null
+++ b/cue/testdata/compile/erralias.txtar
@@ -0,0 +1,32 @@
+-- in.cue --
+let X = {}
+
+[Y="foo"]: 3
+a: Y
+
+"\(b)" :: 3
+b: "foo"
+
+c: {}
+for x in c { a: E }
+
+-- out/compile --
+unreferenced alias or let clause X:
+    ./in.cue:1:1
+a: illegal reference Y:
+    ./in.cue:4:4
+definitions not supported for interpolations:
+    ./in.cue:6:1
+for[].a: reference "E" not found:
+    ./in.cue:10:17
+--- in.cue
+{
+  ["foo"]: 3
+  a: _|_
+  "\(〈0;b〉)": 3
+  b: "foo"
+  c: {}
+  for _, x in 〈0;c〉 {
+    a: _|_
+  }
+}
diff --git a/cue/testdata/compile/scope.txtar b/cue/testdata/compile/scope.txtar
new file mode 100644
index 0000000..0f75b8d
--- /dev/null
+++ b/cue/testdata/compile/scope.txtar
@@ -0,0 +1,67 @@
+-- in.cue --
+a: {
+    {{
+      b
+      c
+      d: b
+      e: c
+    }}
+    c: {}
+}
+b: {
+
+}
+s: "foo"
+c: s
+
+// s is technically in a new struct here so it will have a one higher count than
+// the one before.
+d: [s]: 3
+
+e: { }
+e & { // Is this allowed? Probably not as per comprehension rule (ref fixes.)
+    e: {}
+}
+
+{X=["foo"]: b: X | null}
+{[Y="bar"]: b: Y}
+
+B = {open: int}
+f: B
+
+-- out/compile --
+--- in.cue
+{
+  a: {
+    {
+      {
+        〈3;b〉
+        〈2;c〉
+        d: 〈3;b〉
+        e: 〈2;c〉
+      }
+    }
+    c: {}
+  }
+  b: {}
+  s: "foo"
+  c: 〈0;s〉
+  d: {
+    [〈1;s〉]: 3
+  }
+  e: {}
+  (〈0;e〉 & {
+    e: {}
+  })
+  {
+    ["foo"]: {
+      b: (〈1;(〈1;-〉)〉|null)
+    }
+  }
+  {
+    ["bar"]: {
+      b: 〈1;-〉
+    }
+  }
+  f: 〈0;let B〉
+}
diff --git a/cue/testdata/export/000.txtar b/cue/testdata/export/000.txtar
index 5292869..477870c 100644
--- a/cue/testdata/export/000.txtar
+++ b/cue/testdata/export/000.txtar
@@ -12,3 +12,8 @@
 "hello"
 -- out/legacy-debug --
 "hello"
+-- out/compile --
+--- in.cue
+{
+  "hello"
+}
diff --git a/cue/testdata/export/001.txtar b/cue/testdata/export/001.txtar
index ade9f7e..4153b68 100644
--- a/cue/testdata/export/001.txtar
+++ b/cue/testdata/export/001.txtar
@@ -12,3 +12,8 @@
 "aGVsbG8="
 -- out/legacy-debug --
 'hello'
+-- out/compile --
+--- in.cue
+{
+  'hello'
+}
diff --git a/cue/testdata/export/002.txtar b/cue/testdata/export/002.txtar
index 2a5247b..b878ce5 100644
--- a/cue/testdata/export/002.txtar
+++ b/cue/testdata/export/002.txtar
@@ -23,3 +23,8 @@
         hello
         world
         '''
+-- out/compile --
+--- in.cue
+{
+  'hello\nworld'
+}
diff --git a/cue/testdata/export/003.txtar b/cue/testdata/export/003.txtar
index a4f9850..876a8bf 100644
--- a/cue/testdata/export/003.txtar
+++ b/cue/testdata/export/003.txtar
@@ -23,3 +23,8 @@
         hello
         world
         """
+-- out/compile --
+--- in.cue
+{
+  "hello\nworld"
+}
diff --git a/cue/testdata/export/004.txtar b/cue/testdata/export/004.txtar
index 4cd59a3..359e551 100644
--- a/cue/testdata/export/004.txtar
+++ b/cue/testdata/export/004.txtar
@@ -12,3 +12,13 @@
 "_":    int
 "_foo": int
 _bar:   int
+-- out/compile --
+--- in.cue
+{
+  {
+    $type: 3
+    "_": int
+    "_foo": int
+    _bar: int
+  }
+}
diff --git a/cue/testdata/export/005.txtar b/cue/testdata/export/005.txtar
index 3055a61..89885a8 100644
--- a/cue/testdata/export/005.txtar
+++ b/cue/testdata/export/005.txtar
@@ -9,3 +9,15 @@
 d: true
 e: _
 f: string
+-- out/compile --
+--- in.cue
+{
+  {
+    a: 1
+    b: (〈0;a〉 + 2)
+    c: null
+    d: true
+    e: _
+    f: string
+  }
+}
diff --git a/cue/testdata/export/006.txtar b/cue/testdata/export/006.txtar
index 44f70a7..fb9eaf1 100644
--- a/cue/testdata/export/006.txtar
+++ b/cue/testdata/export/006.txtar
@@ -11,3 +11,17 @@
 c: a.c
 d: a["d"]
 e: a.t[2:3]
+-- out/compile --
+--- in.cue
+{
+  {
+    a: {
+      b: 2.0
+      s: "abc"
+    }
+    b: 〈0;a〉.b
+    c: 〈0;a〉.c
+    d: 〈0;a〉["d"]
+    e: 〈0;a〉.t[2:3]
+  }
+}
diff --git a/cue/testdata/export/007.txtar b/cue/testdata/export/007.txtar
index 5f2eb07..e3dc540 100644
--- a/cue/testdata/export/007.txtar
+++ b/cue/testdata/export/007.txtar
@@ -1,9 +1,9 @@
 # DO NOT EDIT; generated by go run testdata/gen.go
 #
 -- in.cue --
-{a :: {b: 2.0, s: "abc"}, b: a.b, c: a.c, d: a["d"], e: a.t[2:3]}
+{#a: {b: 2.0, s: "abc"}, b: #a.b, c: #a.c, d: #a["d"], e: #a.t[2:3]}
 -- out/def --
-a :: {
+#a: {
 	b: 2.0
 	s: "abc"
 }
@@ -11,3 +11,17 @@
 c: _|_ // undefined field "c"
 d: _|_ // undefined field "d"
 e: _|_ // undefined field "t"
+-- out/compile --
+--- in.cue
+{
+  {
+    #a: {
+      b: 2.0
+      s: "abc"
+    }
+    b: 〈0;#a〉.b
+    c: 〈0;#a〉.c
+    d: 〈0;#a〉["d"]
+    e: 〈0;#a〉.t[2:3]
+  }
+}
diff --git a/cue/testdata/export/008.txtar b/cue/testdata/export/008.txtar
index 2d006f4..e490970 100644
--- a/cue/testdata/export/008.txtar
+++ b/cue/testdata/export/008.txtar
@@ -5,3 +5,12 @@
 -- out/def --
 a: [_|_, // conflicting values 3 and 4
 ]
+-- out/compile --
+--- in.cue
+{
+  {
+    a: [
+      (3 & 4),
+    ]
+  }
+}
diff --git a/cue/testdata/export/009.txtar b/cue/testdata/export/009.txtar
index 8c66bed..f3971d9 100644
--- a/cue/testdata/export/009.txtar
+++ b/cue/testdata/export/009.txtar
@@ -21,3 +21,54 @@
 d: >=2*[int] & [1, 2, ...]
 e: [1, 2, ...int]
 f: [1, 2, ...]
+-- out/compile --
+--- in.cue
+{
+  {
+    a: (5 * [
+      int,
+    ])
+    a: [
+      1,
+      2,
+      ...,
+    ]
+    b: (<=5 * [
+      int,
+    ])
+    b: [
+      1,
+      2,
+      ...,
+    ]
+    c: ((>=3 & <=5) * [
+      int,
+    ])
+    c: [
+      1,
+      2,
+      ...,
+    ]
+    d: (>=2 * [
+      int,
+    ])
+    d: [
+      1,
+      2,
+      ...,
+    ]
+    e: [
+      ...int,
+    ]
+    e: [
+      1,
+      2,
+      ...,
+    ]
+    f: [
+      1,
+      2,
+      ...,
+    ]
+  }
+}
diff --git a/cue/testdata/export/010.txtar b/cue/testdata/export/010.txtar
index 0361a8d..6b4f65d 100644
--- a/cue/testdata/export/010.txtar
+++ b/cue/testdata/export/010.txtar
@@ -22,3 +22,54 @@
 d: >=2*[int] & [1, 2, ...]
 e: [1, 2, ...int]
 f: [1, 2, ...]
+-- out/compile --
+--- in.cue
+{
+  {
+    a: (5 * [
+      int,
+    ])
+    a: [
+      1,
+      2,
+      ...,
+    ]
+    b: (<=5 * [
+      int,
+    ])
+    b: [
+      1,
+      2,
+      ...,
+    ]
+    c: ((>=3 & <=5) * [
+      int,
+    ])
+    c: [
+      1,
+      2,
+      ...,
+    ]
+    d: (>=2 * [
+      int,
+    ])
+    d: [
+      1,
+      2,
+      ...,
+    ]
+    e: [
+      ...int,
+    ]
+    e: [
+      1,
+      2,
+      ...,
+    ]
+    f: [
+      1,
+      2,
+      ...,
+    ]
+  }
+}
diff --git a/cue/testdata/export/011.txtar b/cue/testdata/export/011.txtar
index 009a096..3b62924 100644
--- a/cue/testdata/export/011.txtar
+++ b/cue/testdata/export/011.txtar
@@ -22,3 +22,14 @@
 d: []
 -- out/json --
 {"a":{"b":[]},"c":[],"d":[]}
+-- out/compile --
+--- in.cue
+{
+  {
+    a: {
+      b: []
+    }
+    c: 〈0;a〉.b
+    d: 〈0;a〉["b"]
+  }
+}
diff --git a/cue/testdata/export/012.txtar b/cue/testdata/export/012.txtar
index 97414bc..f34909f 100644
--- a/cue/testdata/export/012.txtar
+++ b/cue/testdata/export/012.txtar
@@ -6,3 +6,11 @@
 -- out/def --
 a: *string | int
 b: _|_ // cannot slice a (type string)
+-- out/compile --
+--- in.cue
+{
+  {
+    a: (*"foo"|*"bar"|*string|int)
+    b: 〈0;a〉[2:3]
+  }
+}
diff --git a/cue/testdata/export/013.txtar b/cue/testdata/export/013.txtar
index 8de4f89..4d63d82 100644
--- a/cue/testdata/export/013.txtar
+++ b/cue/testdata/export/013.txtar
@@ -6,3 +6,10 @@
 }
 -- out/def --
 a: >=0 & <=10 & !=1
+-- out/compile --
+--- in.cue
+{
+  {
+    a: ((>=0 & <=10) & !=1)
+  }
+}
diff --git a/cue/testdata/export/014.txtar b/cue/testdata/export/014.txtar
index b4d2f57..330ae1f 100644
--- a/cue/testdata/export/014.txtar
+++ b/cue/testdata/export/014.txtar
@@ -7,3 +7,10 @@
 }
 -- out/def --
 a: >=0 & <=10 & !=1
+-- out/compile --
+--- in.cue
+{
+  {
+    a: ((>=0 & <=10) & !=1)
+  }
+}
diff --git a/cue/testdata/export/015.txtar b/cue/testdata/export/015.txtar
index c817ac3..18e54f1 100644
--- a/cue/testdata/export/015.txtar
+++ b/cue/testdata/export/015.txtar
@@ -10,3 +10,13 @@
 -- out/def --
 a: 1 | 2 | *_|_
 b: [1 | 2 | *_|_]
+-- out/compile --
+--- in.cue
+{
+  {
+    a: ((*1|2) & (1|*2))
+    b: [
+      ((*1|2) & (1|*2)),
+    ]
+  }
+}
diff --git a/cue/testdata/export/016.txtar b/cue/testdata/export/016.txtar
index 41898ce..2d5c8a4 100644
--- a/cue/testdata/export/016.txtar
+++ b/cue/testdata/export/016.txtar
@@ -32,3 +32,22 @@
 i128: int128
 f64:  float64
 fi:   int & float64
+-- out/compile --
+--- in.cue
+{
+  {
+    u16: ((int & >=0) & <=65535)
+    u32: (>=0 & <=4294967295)
+    u64: (>=0 & <=18446744073709551615)
+    u128: (>=0 & <=340282366920938463463374607431768211455)
+    u8: (>=0 & <=255)
+    ua: ((>=0 & <=65535) & >0)
+    us: ((>=0 & <10000) & int)
+    i16: ((>=-32768 & int) & <=32767)
+    i32: ((>=-2147483648 & <=2147483647) & >0)
+    i64: (>=-9223372036854775808 & <=9223372036854775807)
+    i128: (>=-170141183460469231731687303715884105728 & <=170141183460469231731687303715884105727)
+    f64: (>=-1.797693134862315708145274237317043567981E+308 & <=1.797693134862315708145274237317043567981E+308)
+    fi: ((>=-1.797693134862315708145274237317043567981E+308 & <=1.797693134862315708145274237317043567981E+308) & int)
+  }
+}
diff --git a/cue/testdata/export/017.txtar b/cue/testdata/export/017.txtar
index 4c2906b..8ef3f0e 100644
--- a/cue/testdata/export/017.txtar
+++ b/cue/testdata/export/017.txtar
@@ -21,3 +21,18 @@
   "1": 2
 -- out/json --
 {"a":[1,2],"b":{"1":2}}
+-- out/compile --
+--- in.cue
+{
+  {
+    a: [
+      1,
+      2,
+    ]
+    b: {
+      for k, v in 〈1;a〉 if (〈0;v〉 > 1) {
+        "\(〈1;k〉)": 〈1;v〉
+      }
+    }
+  }
+}
diff --git a/cue/testdata/export/018.txtar b/cue/testdata/export/018.txtar
index fe69537..fb48a4d 100644
--- a/cue/testdata/export/018.txtar
+++ b/cue/testdata/export/018.txtar
@@ -18,3 +18,18 @@
 - 2
 -- out/json --
 {"a":[1,2],"b":[1,2]}
+-- out/compile --
+--- in.cue
+{
+  {
+    a: [
+      1,
+      2,
+    ]
+    b: [
+      for k, v in 〈0;a〉 {
+        〈1;v〉
+      },
+    ]
+  }
+}
diff --git a/cue/testdata/export/019.txtar b/cue/testdata/export/019.txtar
index 1f4e6db..68c5e65 100644
--- a/cue/testdata/export/019.txtar
+++ b/cue/testdata/export/019.txtar
@@ -6,3 +6,11 @@
 -- out/def --
 a: >=0 & <=10
 b: "Count: \(a) times"
+-- out/compile --
+--- in.cue
+{
+  {
+    a: (>=0 & <=10)
+    b: "Count: \(〈0;a〉) times"
+  }
+}
diff --git a/cue/testdata/export/021.txtar b/cue/testdata/export/021.txtar
index cb30238..2aefbcf 100644
--- a/cue/testdata/export/021.txtar
+++ b/cue/testdata/export/021.txtar
@@ -24,3 +24,21 @@
 a: {
 	b: 3
 }
+-- out/compile --
+--- in.cue
+{
+  {
+    b: {
+      idx: 〈1;a〉[〈0;str〉]
+      str: string
+    }
+    b: {
+      a: {
+        b: 4
+      }
+    }
+    a: {
+      b: 3
+    }
+  }
+}
diff --git a/cue/testdata/export/022.txtar b/cue/testdata/export/022.txtar
index 4c45811..8281305 100644
--- a/cue/testdata/export/022.txtar
+++ b/cue/testdata/export/022.txtar
@@ -59,3 +59,27 @@
     command: nginx
 -- out/json --
 {"job":{"list":{"name":"list","replicas":1,"command":"ls"},"nginx":{"name":"nginx","replicas":2,"command":"nginx"}}}
+-- out/compile --
+--- in.cue
+{
+  {
+    job: {
+      [_]: {
+        name: 〈1;-〉
+        replicas: (&(int, >=0)|*1)
+        command: string
+      }
+    }
+    job: {
+      list: {
+        command: "ls"
+      }
+    }
+    job: {
+      nginx: {
+        command: "nginx"
+        replicas: 2
+      }
+    }
+  }
+}
diff --git a/cue/testdata/export/023.txtar b/cue/testdata/export/023.txtar
index 665e738..3d05af8 100644
--- a/cue/testdata/export/023.txtar
+++ b/cue/testdata/export/023.txtar
@@ -3,45 +3,45 @@
 raw: true
 -- in.cue --
 {
-	emb :: {
+	#emb: {
 		a: 1
 
 		sub: {
 			f: 3
 		}
 	}
-	def :: {
-		emb
+	#def: {
+		#emb
 
 		b: 2
 	}
-	f :: {a: 10}
-	e :: {
-		f
+	#f: a: 10
+	#e: {
+		#f
 
-		b:   int
-		[_]: <100
+		b: int
+		{[_]: <100}
 		{[_]: <300}
 	}
 }
 -- out/def --
-emb :: {
+#emb: {
 	a: 1
 	sub: {
 		f: 3
 	}
 }
-f :: {
+#def: {
+	b: 2
+	#emb
+}
+#f: {
 	a: 10
 }
-def :: {
-	b: 2
-	emb
-}
-e :: {
+#e: {
+	b: int
+	#f
 	{[string]: <100}
-	b: <100
-	f
 	{[string]: <300}
 }
 -- out/export --
@@ -50,3 +50,32 @@
 {}
 -- out/json --
 {}
+-- out/compile --
+--- in.cue
+{
+  {
+    #emb: {
+      a: 1
+      sub: {
+        f: 3
+      }
+    }
+    #def: {
+      〈1;#emb〉
+      b: 2
+    }
+    #f: {
+      a: 10
+    }
+    #e: {
+      〈1;#f〉
+      b: int
+      {
+        [_]: <100
+      }
+      {
+        [_]: <300
+      }
+    }
+  }
+}
diff --git a/cue/testdata/export/024.txtar b/cue/testdata/export/024.txtar
index 3342808..90f2748 100644
--- a/cue/testdata/export/024.txtar
+++ b/cue/testdata/export/024.txtar
@@ -6,16 +6,16 @@
 -- in.cue --
 {
 	reg: {foo: 1, bar: {baz: 3}}
-	def :: {
+	#def: {
 		a: 1
 
 		sub: reg
 	}
-	val: def
-	def2 :: {
+	val: #def
+	#def2: {
 		a: {b: int}
 	}
-	val2: def2
+	val2: #def2
 }
 -- out/def --
 reg: {
@@ -24,14 +24,37 @@
 		baz: 3
 	}
 }
-def :: {
+#def: {
 	a:   1
 	sub: reg
 }
-val: def
-def2 :: {
+val: #def
+#def2: {
 	a: {
 		b: int
 	}
 }
-val2: def2
+val2: #def2
+-- out/compile --
+--- in.cue
+{
+  {
+    reg: {
+      foo: 1
+      bar: {
+        baz: 3
+      }
+    }
+    #def: {
+      a: 1
+      sub: 〈1;reg〉
+    }
+    val: 〈0;#def〉
+    #def2: {
+      a: {
+        b: int
+      }
+    }
+    val2: 〈0;#def2〉
+  }
+}
diff --git a/cue/testdata/export/025.txtar b/cue/testdata/export/025.txtar
index d0c153d..5b4d7da 100644
--- a/cue/testdata/export/025.txtar
+++ b/cue/testdata/export/025.txtar
@@ -5,7 +5,7 @@
 -- in.cue --
 {
 	b: [{
-		[X=_]: int
+		{[X=_]: int}
 		if a > 4 {
 			f: 4
 		}
@@ -15,10 +15,28 @@
 }
 -- out/def --
 b: [{
-	[X=string]: int
 	if a > 4 {
 		f: 4
 	}
+	{[X=string]: int}
 }][a]
 a: int
 c: *1 | 2
+-- out/compile --
+--- in.cue
+{
+  {
+    b: [
+      {
+        {
+          [_]: int
+        }
+        if (〈1;a〉 > 4) {
+          f: 4
+        }
+      },
+    ][〈0;a〉]
+    a: int
+    c: (*1|2)
+  }
+}
diff --git a/cue/testdata/export/026.txtar b/cue/testdata/export/026.txtar
index 0a32efc..709bc1d 100644
--- a/cue/testdata/export/026.txtar
+++ b/cue/testdata/export/026.txtar
@@ -15,3 +15,16 @@
 {}
 -- out/json --
 {}
+-- out/compile --
+--- in.cue
+{
+  {
+    if false {
+      ({
+        a: 1
+      }|{
+        b: 1
+      })
+    }
+  }
+}
diff --git a/cue/testdata/export/027.txtar b/cue/testdata/export/027.txtar
index e57d1a7..fe2954c 100644
--- a/cue/testdata/export/027.txtar
+++ b/cue/testdata/export/027.txtar
@@ -4,13 +4,13 @@
 eval: true
 -- in.cue --
 {
-	Foo :: {
-		Bar :: Foo | string
+	#Foo: {
+		#Bar: #Foo | string
 	}
 }
 -- out/def --
-Foo :: {
-	Bar :: Foo | string
+#Foo: {
+	#Bar: #Foo | string
 }
 -- out/export --
 
@@ -18,3 +18,12 @@
 {}
 -- out/json --
 {}
+-- out/compile --
+--- in.cue
+{
+  {
+    #Foo: {
+      #Bar: (〈1;#Foo〉|string)
+    }
+  }
+}
diff --git a/cue/testdata/export/028.txtar b/cue/testdata/export/028.txtar
index 5c1dc14..5a7a661 100644
--- a/cue/testdata/export/028.txtar
+++ b/cue/testdata/export/028.txtar
@@ -4,14 +4,16 @@
 eval: true
 -- in.cue --
 {
-	FindInMap :: {
-		"Fn::FindInMap" :: [string | FindInMap]
+	#FindInMap: {
+		#: "Fn::FindInMap": [string | #FindInMap]
 	}
 	a: [...string]
 }
 -- out/def --
-FindInMap :: {
-	"Fn::FindInMap" :: [string | FindInMap]
+#FindInMap: {
+	#: {
+		"Fn::FindInMap": [string | #FindInMap]
+	}
 }
 a: [...string]
 -- out/export --
@@ -20,3 +22,19 @@
 a: []
 -- out/json --
 {"a":[]}
+-- out/compile --
+--- in.cue
+{
+  {
+    #FindInMap: {
+      #: {
+        "Fn::FindInMap": [
+          (string|〈2;#FindInMap〉),
+        ]
+      }
+    }
+    a: [
+      ...string,
+    ]
+  }
+}
diff --git a/cue/testdata/export/029.txtar b/cue/testdata/export/029.txtar
index cbcb241..10d6edd 100644
--- a/cue/testdata/export/029.txtar
+++ b/cue/testdata/export/029.txtar
@@ -5,17 +5,47 @@
 noOpt: true
 -- in.cue --
 {
-	And :: {
-		"Fn::And": [...(3 | And)]
+	#And: {
+		#: "Fn::And": [...(3 | #And)]
 	}
-	Ands: And & {
-		"Fn::And": [_]
+	#Ands: #And & {
+		#: "Fn::And": [_]
 	}
 }
 -- out/def --
-And :: {
-	"Fn::And": [...3 | And]
+#And: {
+	#: {
+		"Fn::And": [...3 | #And]
+	}
 }
-Ands: And & {
-	"Fn::And": [_]
+#Ands: #And & {
+	#: {
+		"Fn::And": [_]
+	}
+}
+-- out/export --
+
+-- out/yaml --
+{}
+-- out/json --
+{}
+-- out/compile --
+--- in.cue
+{
+  {
+    #And: {
+      #: {
+        "Fn::And": [
+          ...(3|〈2;#And〉),
+        ]
+      }
+    }
+    #Ands: (〈0;#And〉 & {
+      #: {
+        "Fn::And": [
+          _,
+        ]
+      }
+    })
+  }
 }
diff --git a/cue/testdata/export/030.txtar b/cue/testdata/export/030.txtar
index 36242ca..834a1b7 100644
--- a/cue/testdata/export/030.txtar
+++ b/cue/testdata/export/030.txtar
@@ -4,35 +4,52 @@
 eval: true
 -- in.cue --
 {
-	Foo :: {
-		sgl:  Bar
-		ref:  null | Foo
-		ext:  Bar | null
-		ref:  null | Foo
-		ref2: null | Foo.sgl
+	#Foo: {
+		sgl:  #Bar
+		ref:  null | #Foo
+		ext:  #Bar | null
+		ref:  null | #Foo
+		ref2: null | #Foo.sgl
 		...
 	}
-	Foo :: {
-		Foo: 2
+	#Foo: {
+		"#Foo": 2
 		...
 	}
-	Bar :: string
+	#Bar: string
 }
 -- out/def --
-
-FOO = Foo
-Foo :: {
-	Foo:  2
-	sgl:  Bar
-	ref:  (null | FOO) & (null | FOO)
-	ext:  Bar | null
-	ref2: null | FOO.sgl
+#Foo: {
+	"#Foo": 2
+	sgl:    #Bar
+	ref:    (null | #Foo) & (null | #Foo)
+	ext:    #Bar | null
+	ref2:   null | #Foo.sgl
 	...
 }
-Bar :: string
+#Bar: string
 -- out/export --
 
 -- out/yaml --
 {}
 -- out/json --
 {}
+-- out/compile --
+--- in.cue
+{
+  {
+    #Foo: {
+      sgl: 〈1;#Bar〉
+      ref: (null|〈1;#Foo〉)
+      ext: (〈1;#Bar〉|null)
+      ref: (null|〈1;#Foo〉)
+      ref2: (null|〈1;#Foo〉.sgl)
+      ...
+    }
+    #Foo: {
+      "#Foo": 2
+      ...
+    }
+    #Bar: string
+  }
+}
diff --git a/cue/testdata/export/031.txtar b/cue/testdata/export/031.txtar
index 247e1a5..eb3fb49 100644
--- a/cue/testdata/export/031.txtar
+++ b/cue/testdata/export/031.txtar
@@ -10,3 +10,17 @@
 -- out/def --
 A: [>=0]
 B: A & ([10] | [192])
+-- out/compile --
+--- in.cue
+{
+  {
+    A: [
+      &(int, >=0),
+    ]
+    B: (〈0;A〉 & ([
+      10,
+    ]|[
+      192,
+    ]))
+  }
+}
diff --git a/cue/testdata/export/032.txtar b/cue/testdata/export/032.txtar
index 6eb06f8..4205cc5 100644
--- a/cue/testdata/export/032.txtar
+++ b/cue/testdata/export/032.txtar
@@ -2,8 +2,8 @@
 #
 -- in.cue --
 {
-	[string]: _
-	foo:      3
+	{[string]: _}
+	foo: 3
 }
 -- out/def --
 foo: 3
@@ -14,3 +14,13 @@
 foo: 3
 -- out/json --
 {"foo":3}
+-- out/compile --
+--- in.cue
+{
+  {
+    {
+      [string]: _
+    }
+    foo: 3
+  }
+}
diff --git a/cue/testdata/fulleval/000_detect_conflicting_value.txtar b/cue/testdata/fulleval/000_detect_conflicting_value.txtar
index 765c22e..703940b 100644
--- a/cue/testdata/fulleval/000_detect_conflicting_value.txtar
+++ b/cue/testdata/fulleval/000_detect_conflicting_value.txtar
@@ -9,3 +9,9 @@
 a: _|_ // conflicting values 8000.9 and int (mismatched types float and int)
 -- out/legacy-debug --
 <0>{a: _|_((8000.9 & (int | int)):conflicting values 8000.9 and int (mismatched types float and int))}
+-- out/compile --
+--- in.cue
+{
+  a: 8000.9
+  a: (7080|int)
+}
diff --git a/cue/testdata/fulleval/001_conflicts_in_optional_fields_are_okay_.txtar b/cue/testdata/fulleval/001_conflicts_in_optional_fields_are_okay_.txtar
index 88aba96..a2eb226 100644
--- a/cue/testdata/fulleval/001_conflicts_in_optional_fields_are_okay_.txtar
+++ b/cue/testdata/fulleval/001_conflicts_in_optional_fields_are_okay_.txtar
@@ -21,3 +21,16 @@
 }
 -- out/legacy-debug --
 <0>{d: (<1>{a: 1, b?: 3} | <2>{a: 2}), c: (<3>{a: 1, b?: (3 & 4)} | <4>{a: 2, b?: 4})}
+-- out/compile --
+--- in.cue
+{
+  d: ({
+    a: 1
+    b?: 3
+  }|{
+    a: 2
+  })
+  c: (〈0;d〉 & {
+    b?: 4
+  })
+}
diff --git a/cue/testdata/fulleval/002_resolve_all_disjunctions.txtar b/cue/testdata/fulleval/002_resolve_all_disjunctions.txtar
index 2d49d76..73896a5 100644
--- a/cue/testdata/fulleval/002_resolve_all_disjunctions.txtar
+++ b/cue/testdata/fulleval/002_resolve_all_disjunctions.txtar
@@ -58,3 +58,26 @@
 {"service":{"foo":{"name":"foo","port":7080},"bar":{"name":"bar","port":8000},"baz":{"name":"foobar","port":7080}}}
 -- out/legacy-debug --
 <0>{service: <1>{[]: <2>(Name: string)-><3>{name: (string | *<2>.Name), port: (int | *7080)}, foo: <4>{name: "foo", port: 7080}, bar: <5>{name: "bar", port: 8000}, baz: <6>{name: "foobar", port: 7080}}}
+-- out/compile --
+--- in.cue
+{
+  service: {
+    [string]: {
+      name: (string|*〈1;-〉)
+      port: (int|*7080)
+    }
+  }
+  service: {
+    foo: _
+  }
+  service: {
+    bar: {
+      port: 8000
+    }
+  }
+  service: {
+    baz: {
+      name: "foobar"
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/003_field_templates.txtar b/cue/testdata/fulleval/003_field_templates.txtar
index c1b9e2a..e7da736 100644
--- a/cue/testdata/fulleval/003_field_templates.txtar
+++ b/cue/testdata/fulleval/003_field_templates.txtar
@@ -4,17 +4,17 @@
 #evalFull
 -- in.cue --
 a: {
-	[name=_]: int
-	k:        1
+	{[name=_]: int}
+	k: 1
 }
 b: {
-	[X=_]: {x: 0, y: *1 | int}
+	{[X=_]: {x: 0, y: *1 | int}}
 	v: {}
 	w: {y: 0}
 }
 b: {[y=_]: {}} // TODO: allow different name
 c: {
-	[Name=_]: {name: Name, y: 1}
+	{[Name=_]: {name: Name, y: 1}}
 	foo: {}
 	bar: _
 }
@@ -94,3 +94,38 @@
 {"a":{"k":1},"b":{"v":{"x":0,"y":1},"w":{"x":0,"y":0}},"c":{"foo":{"y":1,"name":"foo"},"bar":{"y":1,"name":"bar"}}}
 -- out/legacy-debug --
 <0>{a: <1>{[]: <2>(name: string)->int, k: 1}, b: <3>{[]: <4>(X: string)->(<5>{x: 0, y: (*1 | int)} & <6>{}), v: <7>{x: 0, y: 1}, w: <8>{x: 0, y: 0}}, c: <9>{[]: <10>(Name: string)-><11>{y: 1, name: <10>.Name}, foo: <12>{y: 1, name: "foo"}, bar: <13>{y: 1, name: "bar"}}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    {
+      [_]: int
+    }
+    k: 1
+  }
+  b: {
+    {
+      [_]: {
+        x: 0
+        y: (*1|int)
+      }
+    }
+    v: {}
+    w: {
+      y: 0
+    }
+  }
+  b: {
+    [_]: {}
+  }
+  c: {
+    {
+      [_]: {
+        name: 〈1;-〉
+        y: 1
+      }
+    }
+    foo: {}
+    bar: _
+  }
+}
diff --git a/cue/testdata/fulleval/004_field_comprehension.txtar b/cue/testdata/fulleval/004_field_comprehension.txtar
index c1a675d..b73710c 100644
--- a/cue/testdata/fulleval/004_field_comprehension.txtar
+++ b/cue/testdata/fulleval/004_field_comprehension.txtar
@@ -69,3 +69,23 @@
 {"a":{"b":2,"c":3},"b":{"a":1,"b":2,"c":3,"d":4},"c":{"b":2,"c":3}}
 -- out/legacy-debug --
 <0>{a: <1>{b: 2, c: 3}, b: <2>{a: 1, b: 2, c: 3, d: 4}, c: <3>{b: 2, c: 3}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    for k, v in 〈1;b〉 if (〈0;k〉 < "d") if (〈0;v〉 > 〈2;b〉.a) {
+      "\(〈1;k〉)": 〈1;v〉
+    }
+  }
+  b: {
+    a: 1
+    b: 2
+    c: 3
+    d: 4
+  }
+  c: {
+    for k, v in 〈1;b〉 if (〈0;k〉 < "d") if (〈0;v〉 > 〈2;b〉.a) {
+      "\(〈1;k〉)": 〈1;v〉
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/005_conditional_field.txtar b/cue/testdata/fulleval/005_conditional_field.txtar
index e74c1f2..f00f3e8 100644
--- a/cue/testdata/fulleval/005_conditional_field.txtar
+++ b/cue/testdata/fulleval/005_conditional_field.txtar
@@ -34,3 +34,23 @@
 }
 -- out/legacy-debug --
 <0>{b: true, a: "foo", c: <1>{a: 3}, d: <2>{a: int if (<3>.a > 1) yield <4>{a: 3}}}
+-- out/compile --
+--- in.cue
+{
+  if 〈0;b〉 {
+    a: "foo"
+  }
+  b: true
+  c: {
+    a: 3
+    if (〈0;a〉 > 1) {
+      a: 3
+    }
+  }
+  d: {
+    a: int
+    if (〈0;a〉 > 1) {
+      a: 3
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/006_referencing_field_in_field_comprehension.txtar b/cue/testdata/fulleval/006_referencing_field_in_field_comprehension.txtar
index 66a5a43..8e873dd 100644
--- a/cue/testdata/fulleval/006_referencing_field_in_field_comprehension.txtar
+++ b/cue/testdata/fulleval/006_referencing_field_in_field_comprehension.txtar
@@ -39,3 +39,20 @@
 {"a":{"b":{"c":4,"d":5},"c":4,"d":5}}
 -- out/legacy-debug --
 <0>{a: <1>{b: <2>{c: 4, d: 5}, c: 4, d: 5}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    b: {
+      c: 4
+    }
+  }
+  a: {
+    b: {
+      d: 5
+    }
+    for k, v in 〈0;b〉 {
+      "\(〈1;k〉)": 〈1;v〉
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/007_different_labels_for_templates.txtar b/cue/testdata/fulleval/007_different_labels_for_templates.txtar
index d1596bc..47f95ed 100644
--- a/cue/testdata/fulleval/007_different_labels_for_templates.txtar
+++ b/cue/testdata/fulleval/007_different_labels_for_templates.txtar
@@ -29,3 +29,20 @@
 {"a":{"foo":{"name":"foo"}}}
 -- out/legacy-debug --
 <0>{a: <1>{[]: <2>(X: string)->(<3>{name: <2>.X} & <4>{name: <2>.X}), foo: <5>{name: "foo"}}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    [string]: {
+      name: 〈1;-〉
+    }
+  }
+  a: {
+    [string]: {
+      name: 〈1;-〉
+    }
+  }
+  a: {
+    foo: {}
+  }
+}
diff --git a/cue/testdata/fulleval/008_nested_templates_in_one_field.txtar b/cue/testdata/fulleval/008_nested_templates_in_one_field.txtar
index 9aea5f9..b27f3ac 100644
--- a/cue/testdata/fulleval/008_nested_templates_in_one_field.txtar
+++ b/cue/testdata/fulleval/008_nested_templates_in_one_field.txtar
@@ -104,3 +104,40 @@
 {"a":{"A":{"b":{"B":{"name":"A","kind":"B"}}},"C":{"b":{"D":{"name":"C","kind":"D"}}},"EE":{"b":{"FF":{"name":"EE","kind":"FF","c":"bar"}}}}}
 -- out/legacy-debug --
 <0>{a: <1>{[]: <2>(A: string)-><3>{b: <4>{[]: <5>(B: string)-><6>{name: <2>.A, kind: <5>.B}, }}, A: <7>{b: <8>{[]: <9>(B: string)-><10>{name: <11>.A, kind: <9>.B}, B: <12>{name: "A", kind: "B"}}}, C: <13>{b: <14>{[]: <15>(B: string)-><16>{name: <17>.A, kind: <15>.B}, D: <18>{name: "C", kind: "D"}}}, EE: <19>{b: <20>{[]: <21>(B: string)-><22>{name: <23>.A, kind: <21>.B}, FF: <24>{name: "EE", kind: "FF", c: "bar"}}}}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    [string]: {
+      b: {
+        [string]: {
+          name: 〈3;-〉
+          kind: 〈1;-〉
+        }
+      }
+    }
+  }
+  a: {
+    A: {
+      b: {
+        B: _
+      }
+    }
+  }
+  a: {
+    C: {
+      b: {
+        D: _
+      }
+    }
+  }
+  a: {
+    EE: {
+      b: {
+        FF: {
+          c: "bar"
+        }
+      }
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/009_template_unification_within_one_struct.txtar b/cue/testdata/fulleval/009_template_unification_within_one_struct.txtar
index 2cf0f3f..fe90f38 100644
--- a/cue/testdata/fulleval/009_template_unification_within_one_struct.txtar
+++ b/cue/testdata/fulleval/009_template_unification_within_one_struct.txtar
@@ -4,9 +4,10 @@
 #evalFull
 -- in.cue --
 a: {
-	[A=string]: {name: A}
+	{[A=string]: {name: A}}
+
 	// TODO: allow duplicate alias here
-	[X=string]: {kind: X}
+	{[X=string]: {kind: X}}
 }
 a: "A": _
 a: "C": _
@@ -62,3 +63,30 @@
 {"a":{"E":{"name":"E","kind":"E","c":"bar"},"A":{"name":"A","kind":"A"},"C":{"name":"C","kind":"C"}}}
 -- out/legacy-debug --
 <0>{a: <1>{[]: <2>(A: string)->(<3>{name: <2>.A} & <4>{kind: <2>.A}), E: <5>{name: "E", kind: "E", c: "bar"}, A: <6>{name: "A", kind: "A"}, C: <7>{name: "C", kind: "C"}}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    {
+      [string]: {
+        name: 〈1;-〉
+      }
+    }
+    {
+      [string]: {
+        kind: 〈1;-〉
+      }
+    }
+  }
+  a: {
+    A: _
+  }
+  a: {
+    C: _
+  }
+  a: {
+    E: {
+      c: "bar"
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/010_field_comprehensions_with_multiple_keys.txtar b/cue/testdata/fulleval/010_field_comprehensions_with_multiple_keys.txtar
index 32cc966..b07c106 100644
--- a/cue/testdata/fulleval/010_field_comprehensions_with_multiple_keys.txtar
+++ b/cue/testdata/fulleval/010_field_comprehensions_with_multiple_keys.txtar
@@ -124,3 +124,47 @@
 {"E":{"F":{"a":"E","b":"F"}},"a":{"E":{"b":{"F":{"a":"E","b":"F"}}},"A":{"b":{"B":{"a":"A","b":"B"}}},"C":{"b":{"D":{"a":"C","b":"D"}}}},"A":{"B":{"a":"A","b":"B"}},"C":{"D":{"a":"C","b":"D"}}}
 -- out/legacy-debug --
 <0>{E: <1>{F: <2>{a: "E", b: "F"}}, a: <3>{E: <4>{b: <5>{F: <6>{a: "E", b: "F"}}}, A: <7>{b: <8>{B: <9>{a: "A", b: "B"}}}, C: <10>{b: <11>{D: <12>{a: "C", b: "D"}}}}, A: <13>{B: <14>{a: "A", b: "B"}}, C: <15>{D: <16>{a: "C", b: "D"}}}
+-- out/compile --
+--- in.cue
+{
+  for _, x in [
+    {
+      a: "A"
+      b: "B"
+    },
+    {
+      a: "C"
+      b: "D"
+    },
+    {
+      a: "E"
+      b: "F"
+    },
+  ] {
+    a: {
+      "\(〈2;x〉.a)": {
+        b: {
+          "\(〈4;x〉.b)": 〈4;x〉
+        }
+      }
+    }
+  }
+  for _, x in [
+    {
+      a: "A"
+      b: "B"
+    },
+    {
+      a: "C"
+      b: "D"
+    },
+    {
+      a: "E"
+      b: "F"
+    },
+  ] {
+    "\(〈1;x〉.a)": {
+      "\(〈2;x〉.b)": 〈2;x〉
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/011_field_comprehensions_with_templates.txtar b/cue/testdata/fulleval/011_field_comprehensions_with_templates.txtar
index 290109d..425c80d 100644
--- a/cue/testdata/fulleval/011_field_comprehensions_with_templates.txtar
+++ b/cue/testdata/fulleval/011_field_comprehensions_with_templates.txtar
@@ -55,3 +55,25 @@
 {"num":1,"a":{"b":{"c":{"name":"b","kind":"c","d":"bar"}}}}
 -- out/legacy-debug --
 <0>{num: 1, a: <1>{[]: <2>(A: string)-><3>{[]: <4>(B: string)-><5>{name: <2>.A, kind: <4>.B}, }, b: <6>{[]: <7>(B: string)-><8>{name: <9>.A, kind: <7>.B}, c: <10>{name: "b", kind: "c", d: "bar"}}}}
+-- out/compile --
+--- in.cue
+{
+  num: 1
+  a: {
+    if (〈1;num〉 < 5) {
+      [string]: {
+        [string]: {
+          name: 〈2;-〉
+          kind: 〈1;-〉
+        }
+      }
+    }
+  }
+  a: {
+    b: {
+      c: {
+        d: "bar"
+      }
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/012_disjunctions_of_lists.txtar b/cue/testdata/fulleval/012_disjunctions_of_lists.txtar
index 8260c5d..19719f7 100644
--- a/cue/testdata/fulleval/012_disjunctions_of_lists.txtar
+++ b/cue/testdata/fulleval/012_disjunctions_of_lists.txtar
@@ -13,3 +13,22 @@
 l2: ["c", "d"]
 -- out/legacy-debug --
 <0>{l: [int,int], l1: ["a","b"], l2: ["c","d"]}
+-- out/compile --
+--- in.cue
+{
+  l: (*[
+    int,
+    int,
+  ]|[
+    string,
+    string,
+  ])
+  l1: [
+    "a",
+    "b",
+  ]
+  l2: (〈0;l〉 & [
+    "c",
+    "d",
+  ])
+}
diff --git a/cue/testdata/fulleval/013_normalization.txtar b/cue/testdata/fulleval/013_normalization.txtar
index 8949992..d9da622 100644
--- a/cue/testdata/fulleval/013_normalization.txtar
+++ b/cue/testdata/fulleval/013_normalization.txtar
@@ -12,3 +12,10 @@
 c: float
 -- out/legacy-debug --
 <0>{a: string, b: int, c: float}
+-- out/compile --
+--- in.cue
+{
+  a: (string|string)
+  b: (*1|*int)
+  c: (*1.0|*float)
+}
diff --git a/cue/testdata/fulleval/014_default_disambiguation_and_elimination.txtar b/cue/testdata/fulleval/014_default_disambiguation_and_elimination.txtar
index a078caf..7e65db7 100644
--- a/cue/testdata/fulleval/014_default_disambiguation_and_elimination.txtar
+++ b/cue/testdata/fulleval/014_default_disambiguation_and_elimination.txtar
@@ -17,3 +17,12 @@
 e: 1
 -- out/legacy-debug --
 <0>{a: 1, b: 3, c: int, d: int, e: 1}
+-- out/compile --
+--- in.cue
+{
+  a: (*1|int)
+  b: (*3|int)
+  c: (〈0;a〉 & 〈0;b〉)
+  d: (〈0;b〉 & 〈0;a〉)
+  e: (*1|*1)
+}
diff --git a/cue/testdata/fulleval/015_list_comprehension.txtar b/cue/testdata/fulleval/015_list_comprehension.txtar
index e1a497c..5fcc1d8 100644
--- a/cue/testdata/fulleval/015_list_comprehension.txtar
+++ b/cue/testdata/fulleval/015_list_comprehension.txtar
@@ -55,3 +55,28 @@
 {"a":["b","c"],"b":{"a":1,"b":2,"c":3,"d":4},"c":[1,1,1,2,2,3],"d":[0,1]}
 -- out/legacy-debug --
 <0>{a: ["b","c"], b: <1>{a: 1, b: 2, c: 3, d: 4}, c: [1,1,1,2,2,3], d: [0,1]}
+-- out/compile --
+--- in.cue
+{
+  a: [
+    for k, v in 〈0;b〉 if (〈0;k〉 < "d") if (〈0;v〉 > 〈1;b〉.a) {
+      〈1;k〉
+    },
+  ]
+  b: {
+    a: 1
+    b: 2
+    c: 3
+    d: 4
+  }
+  c: [
+    for _, x in 〈0;b〉 for _, y in 〈1;b〉 if (〈1;x〉 < 〈0;y〉) {
+      〈2;x〉
+    },
+  ]
+  d: [
+    for x, _ in 〈0;a〉 {
+      〈1;x〉
+    },
+  ]
+}
diff --git a/cue/testdata/fulleval/016_struct_comprehension_with_template.txtar b/cue/testdata/fulleval/016_struct_comprehension_with_template.txtar
index 3676a1d..2073981 100644
--- a/cue/testdata/fulleval/016_struct_comprehension_with_template.txtar
+++ b/cue/testdata/fulleval/016_struct_comprehension_with_template.txtar
@@ -106,3 +106,32 @@
 {"result":[{"name":"foo","type":"service","port":7080},{"name":"bar","type":"service","port":8000},{"name":"foobar","type":"service","port":7080}],"service":{"foo":{"name":"foo","type":"service","port":7080},"bar":{"name":"bar","type":"service","port":8000},"baz":{"name":"foobar","type":"service","port":7080}}}
 -- out/legacy-debug --
 <0>{result: [<1>{name: "foo", type: "service", port: 7080},<2>{name: "bar", type: "service", port: 8000},<3>{name: "foobar", type: "service", port: 7080}], service: <4>{[]: <5>(Name: string)-><6>{name: (*<5>.Name | string), type: "service", port: (*7080 | int)}, foo: <7>{name: "foo", type: "service", port: 7080}, bar: <8>{name: "bar", type: "service", port: 8000}, baz: <9>{name: "foobar", type: "service", port: 7080}}}
+-- out/compile --
+--- in.cue
+{
+  result: [
+    for _, v in 〈0;service〉 {
+      〈1;v〉
+    },
+  ]
+  service: {
+    [string]: {
+      name: (*〈1;-〉|string)
+      type: "service"
+      port: (*7080|int)
+    }
+  }
+  service: {
+    foo: {}
+  }
+  service: {
+    bar: {
+      port: 8000
+    }
+  }
+  service: {
+    baz: {
+      name: "foobar"
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/017_resolutions_in_struct_comprehension_keys.txtar b/cue/testdata/fulleval/017_resolutions_in_struct_comprehension_keys.txtar
index bdc2cff..c44514e 100644
--- a/cue/testdata/fulleval/017_resolutions_in_struct_comprehension_keys.txtar
+++ b/cue/testdata/fulleval/017_resolutions_in_struct_comprehension_keys.txtar
@@ -19,3 +19,14 @@
 {"a":{"c.":"a"}}
 -- out/legacy-debug --
 <0>{a: <1>{"c.": "a"}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    for _, b in [
+      "c",
+    ] {
+      "\((〈1;b〉 + "."))": "a"
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/018_recursive_evaluation_within_list.txtar b/cue/testdata/fulleval/018_recursive_evaluation_within_list.txtar
index 425efde..9e6b75c 100644
--- a/cue/testdata/fulleval/018_recursive_evaluation_within_list.txtar
+++ b/cue/testdata/fulleval/018_recursive_evaluation_within_list.txtar
@@ -34,3 +34,27 @@
 }
 -- out/legacy-debug --
 <0>{l: [<1>{c: "t", d: "t"}], a: <2>{c: "t", d: "t"}, b: <3>{c: string, d: string}, l1: [<4>{c: "t", d: "st"}], a1: <5>{c: "t", d: "st"}, b1: <6>{c: string, d: ("s" + <7>.c)}}
+-- out/compile --
+--- in.cue
+{
+  l: [
+    〈0;a〉,
+  ]
+  a: (〈0;b〉 & {
+    c: "t"
+  })
+  b: {
+    d: 〈0;c〉
+    c: string
+  }
+  l1: [
+    〈0;a1〉,
+  ]
+  a1: (〈0;b1〉 & {
+    c: "t"
+  })
+  b1: {
+    d: ("s" + 〈0;c〉)
+    c: string
+  }
+}
diff --git a/cue/testdata/fulleval/019_ips.txtar b/cue/testdata/fulleval/019_ips.txtar
index 6081e4f..a44d073 100644
--- a/cue/testdata/fulleval/019_ips.txtar
+++ b/cue/testdata/fulleval/019_ips.txtar
@@ -20,3 +20,37 @@
 MyIP: [10, 10, 10, 10]
 -- out/legacy-debug --
 <0>{IP: [(int & >=0 & int & <=255),(int & >=0 & int & <=255),(int & >=0 & int & <=255),(int & >=0 & int & <=255)], Private: [192,168,(int & >=0 & int & <=255),(int & >=0 & int & <=255)], Inst: [10,10,(int & >=0 & int & <=255),(int & >=0 & int & <=255)], MyIP: [10,10,10,10]}
+-- out/compile --
+--- in.cue
+{
+  IP: (4 * [
+    (>=0 & <=255),
+  ])
+  Private: (*[
+    192,
+    168,
+    (>=0 & <=255),
+    (>=0 & <=255),
+  ]|[
+    10,
+    (>=0 & <=255),
+    (>=0 & <=255),
+    (>=0 & <=255),
+  ]|[
+    172,
+    (>=16 & <=32),
+    (>=0 & <=255),
+    (>=0 & <=255),
+  ])
+  Inst: (〈0;Private〉 & [
+    _,
+    10,
+    ...,
+  ])
+  MyIP: (〈0;Inst〉 & [
+    _,
+    _,
+    10,
+    10,
+  ])
+}
diff --git a/cue/testdata/fulleval/020_complex_interaction_of_groundness.txtar b/cue/testdata/fulleval/020_complex_interaction_of_groundness.txtar
index da525a4..29d64ab 100644
--- a/cue/testdata/fulleval/020_complex_interaction_of_groundness.txtar
+++ b/cue/testdata/fulleval/020_complex_interaction_of_groundness.txtar
@@ -28,3 +28,34 @@
 }
 -- out/legacy-debug --
 <0>{res: [<1>{d: "b", s: "ab"}], a: <2>{b: <3>{[]: <4>(C: string)-><5>{d: string, s: ("a" + <5>.d)}, c: <6>{d: string, s: ("a" + <7>.d)}}}}
+-- out/compile --
+--- in.cue
+{
+  res: [
+    for _, x in 〈0;a〉 for _, y in 〈0;x〉 {
+      (〈1;y〉 & {
+        d: "b"
+      })
+    },
+  ]
+  res: [
+    (〈0;a〉.b.c & {
+      d: "b"
+    }),
+  ]
+  a: {
+    b: {
+      [string]: {
+        d: string
+        s: ("a" + 〈0;d〉)
+      }
+    }
+  }
+  a: {
+    b: {
+      c: {
+        d: string
+      }
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/021_complex_groundness_2.txtar b/cue/testdata/fulleval/021_complex_groundness_2.txtar
index 67bf004..a44907a 100644
--- a/cue/testdata/fulleval/021_complex_groundness_2.txtar
+++ b/cue/testdata/fulleval/021_complex_groundness_2.txtar
@@ -33,3 +33,39 @@
 }
 -- out/legacy-debug --
 <0>{r1: <1>{y: "c", res: <2>{d: "c", s: "ac"}}, f1: <3>{y: string, res: <4>{d: string, s: (("a" + <5>.d) & ("a" + <5>.d))}}, a: <6>{b: <7>{[]: <8>(C: string)-><9>{d: string, s: ("a" + <9>.d)}, c: <10>{d: string, s: (("a" + <11>.d) & ("a" + <11>.d))}}}}
+-- out/compile --
+--- in.cue
+{
+  r1: (〈0;f1〉 & {
+    y: "c"
+  })
+  f1: {
+    y: string
+    res: (〈1;a〉.b.c & {
+      d: 〈1;y〉
+    })
+  }
+  a: {
+    b: {
+      c: {
+        d: string
+        s: ("a" + 〈0;d〉)
+      }
+    }
+  }
+  a: {
+    b: {
+      [string]: {
+        d: string
+        s: ("a" + 〈0;d〉)
+      }
+    }
+  }
+  a: {
+    b: {
+      c: {
+        d: string
+      }
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/022_references_from_template_to_concrete.txtar b/cue/testdata/fulleval/022_references_from_template_to_concrete.txtar
index aa6c93c..552769c 100644
--- a/cue/testdata/fulleval/022_references_from_template_to_concrete.txtar
+++ b/cue/testdata/fulleval/022_references_from_template_to_concrete.txtar
@@ -62,3 +62,26 @@
 {"res":[{"x":{"a":"XDDDD","c":"X","b":{"str":"DDDD"}}}],"t":{"x":{"a":"XDDDD","c":"X","b":{"str":"DDDD"}}}}
 -- out/legacy-debug --
 <0>{res: [<1>{[]: <2>(X: string)-><3>{a: (<3>.c + <3>.b.str), c: "X", b: <4>{str: string}}, x: <5>{a: "XDDDD", c: "X", b: <6>{str: "DDDD"}}}], t: <7>{[]: <2>(X: string)-><3>{a: (<3>.c + <3>.b.str), c: "X", b: <4>{str: string}}, x: <8>{a: "XDDDD", c: "X", b: <9>{str: "DDDD"}}}}
+-- out/compile --
+--- in.cue
+{
+  res: [
+    〈0;t〉,
+  ]
+  t: {
+    [string]: {
+      a: (〈0;c〉 + 〈0;b〉.str)
+      b: {
+        str: string
+      }
+      c: "X"
+    }
+  }
+  t: {
+    x: {
+      b: {
+        str: "DDDD"
+      }
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/023_reentrance.txtar b/cue/testdata/fulleval/023_reentrance.txtar
index 1b9ab5a..e074f6c 100644
--- a/cue/testdata/fulleval/023_reentrance.txtar
+++ b/cue/testdata/fulleval/023_reentrance.txtar
@@ -46,3 +46,35 @@
 fib12: 144
 -- out/legacy-debug --
 <0>{fibRec: <1>{nn: int, out: (<2>.fib & <3>{n: <4>.nn}).out}, fib: <5>{n: int if (<6>.n >= 2) yield <7>{out: ((<2>.fibRec & <8>{nn: (<6>.n - 2)}).out + (<2>.fibRec & <9>{nn: (<6>.n - 1)}).out)},  if (<6>.n < 2) yield <10>{out: <6>.n}}, fib2: 1, fib7: 13, fib12: 144}
+-- out/compile --
+--- in.cue
+{
+  fibRec: {
+    nn: int
+    out: (〈1;fib〉 & {
+      n: 〈1;nn〉
+    }).out
+  }
+  fib: {
+    n: int
+    if (〈0;n〉 >= 2) {
+      out: ((〈2;fibRec〉 & {
+        nn: (〈2;n〉 - 2)
+      }).out + (〈2;fibRec〉 & {
+        nn: (〈2;n〉 - 1)
+      }).out)
+    }
+    if (〈0;n〉 < 2) {
+      out: 〈1;n〉
+    }
+  }
+  fib2: (〈0;fib〉 & {
+    n: 2
+  }).out
+  fib7: (〈0;fib〉 & {
+    n: 7
+  }).out
+  fib12: (〈0;fib〉 & {
+    n: 12
+  }).out
+}
diff --git "a/cue/testdata/fulleval/024_Issue_\04323.txtar" "b/cue/testdata/fulleval/024_Issue_\04323.txtar"
index 5f12158..cbabfdf 100644
--- "a/cue/testdata/fulleval/024_Issue_\04323.txtar"
+++ "b/cue/testdata/fulleval/024_Issue_\04323.txtar"
@@ -14,3 +14,15 @@
 y: _|_ // ; empty disjunction: conflicting values 2 and 3
 -- out/legacy-debug --
 <0>{x: (<1>{a: 1} | <2>{a: 2}), y: _|_((1 & 3):empty disjunction: conflicting values 1 and 3;(2 & 3):empty disjunction: conflicting values 2 and 3)}
+-- out/compile --
+--- in.cue
+{
+  x: ({
+    a: 1
+  }|{
+    a: 2
+  })
+  y: (〈0;x〉 & {
+    a: 3
+  })
+}
diff --git a/cue/testdata/fulleval/025_cannot_resolve_references_that_would_be_ambiguous.txtar b/cue/testdata/fulleval/025_cannot_resolve_references_that_would_be_ambiguous.txtar
index 68b5eba..981e750 100644
--- a/cue/testdata/fulleval/025_cannot_resolve_references_that_would_be_ambiguous.txtar
+++ b/cue/testdata/fulleval/025_cannot_resolve_references_that_would_be_ambiguous.txtar
@@ -32,3 +32,24 @@
 }) & c1
 -- out/legacy-debug --
 <0>{a1: ((*0 | 1) & (<1>.a3 - <1>.a2)), a3: 1, a2: ((*0 | 1) & (<1>.a3 - <1>.a1)), b1: (0 | 1), b2: (0 | 1), c1: (<2>{a: 1, b: 2} | <3>{a: 2, b: 1}), c2: (<4>{a: 2, b: 1} | <5>{a: 1, b: 2})}
+-- out/compile --
+--- in.cue
+{
+  a1: (*0|1)
+  a1: (〈0;a3〉 - 〈0;a2〉)
+  a2: (*0|1)
+  a2: (〈0;a3〉 - 〈0;a1〉)
+  a3: 1
+  b1: ((*0|1) & 〈0;b2〉)
+  b2: ((0|*1) & 〈0;b1〉)
+  c1: ((*{
+    a: 1
+  }|{
+    b: 1
+  }) & 〈0;c2〉)
+  c2: ((*{
+    a: 2
+  }|{
+    b: 2
+  }) & 〈0;c1〉)
+}
diff --git a/cue/testdata/fulleval/026_dont_convert_incomplete_errors_to_non-incomplete.txtar b/cue/testdata/fulleval/026_dont_convert_incomplete_errors_to_non-incomplete.txtar
index 9ffbc9c..72b82ef 100644
--- a/cue/testdata/fulleval/026_dont_convert_incomplete_errors_to_non-incomplete.txtar
+++ b/cue/testdata/fulleval/026_dont_convert_incomplete_errors_to_non-incomplete.txtar
@@ -1,6 +1,6 @@
 # DO NOT EDIT; generated by go run testdata/gen.go
 #
-#name: don't convert incomplete errors to non-incomplete
+#name: dont convert incomplete errors to non-incomplete
 #evalFull
 -- in.cue --
 import "strings"
diff --git a/cue/testdata/fulleval/028_slice_rewrite_bug.txtar b/cue/testdata/fulleval/028_slice_rewrite_bug.txtar
index 93c73f9..d97ef30 100644
--- a/cue/testdata/fulleval/028_slice_rewrite_bug.txtar
+++ b/cue/testdata/fulleval/028_slice_rewrite_bug.txtar
@@ -38,3 +38,20 @@
 {"fn":{"arg":[1],"out":[]},"fn1":{"arg":[1],"out":[]}}
 -- out/legacy-debug --
 <0>{fn: <1>{arg: [1], out: []}, fn1: <2>{arg: [1], out: []}}
+-- out/compile --
+--- in.cue
+{
+  fn: {
+    arg: ([
+      ...int,
+    ] & [
+      1,
+    ])
+    out: 〈0;arg〉[1:]
+  }
+  fn1: (〈0;fn〉 & {
+    arg: [
+      1,
+    ]
+  })
+}
diff --git "a/cue/testdata/fulleval/029_Issue_\04394.txtar" "b/cue/testdata/fulleval/029_Issue_\04394.txtar"
index f05a453..268d3d1 100644
--- "a/cue/testdata/fulleval/029_Issue_\04394.txtar"
+++ "b/cue/testdata/fulleval/029_Issue_\04394.txtar"
@@ -6,7 +6,7 @@
 foo: {
 	opt?:    1
 	"txt":   2
-	def ::   3
+	#def:    3
 	regular: 4
 	_hidden: 5
 }
@@ -14,14 +14,14 @@
 select: {
 	opt:     foo.opt
 	"txt":   foo.txt
-	def ::   foo.def
+	#def:    foo.#def
 	regular: foo.regular
 	_hidden: foo._hidden
 }
 index: {
 	opt:     foo["opt"]
 	"txt":   foo["txt"]
-	def ::   foo["def"]
+	#def:    foo["#def"]
 	regular: foo["regular"]
 	_hidden: foo["_hidden"]
 }
@@ -29,7 +29,7 @@
 foo: {
 	opt?:    1
 	txt:     2
-	def ::   3
+	#def:    3
 	regular: 4
 	_hidden: 5
 }
@@ -40,16 +40,46 @@
 select: {
 	opt:     foo.opt
 	txt:     2
-	def ::   3
+	#def:    3
 	regular: 4
 	_hidden: 5
 }
 index: {
 	opt:     foo["opt"]
 	txt:     2
-	def ::   _|_ // field "def" is a definition
+	#def:    foo["#def"]
 	regular: 4
 	_hidden: foo["_hidden"]
 }
 -- out/legacy-debug --
-<0>{foo: <1>{opt?: 1, txt: 2, def :: 3, regular: 4, _hidden: 5}, comp: <2>{txt: 2, regular: 4}, select: <3>{opt: <4>.foo.opt, txt: 2, def :: 3, regular: 4, _hidden: 5}, index: <5>{opt: <4>.foo["opt"], txt: 2, def :: _|_(<4>.foo["def"]:field "def" is a definition), regular: 4, _hidden: <4>.foo["_hidden"]}}
+<0>{foo: <1>{opt?: 1, txt: 2, #def: 3, regular: 4, _hidden: 5}, comp: <2>{txt: 2, regular: 4}, select: <3>{opt: <4>.foo.opt, txt: 2, #def: 3, regular: 4, _hidden: 5}, index: <5>{opt: <4>.foo["opt"], txt: 2, #def: <4>.foo["#def"], regular: 4, _hidden: <4>.foo["_hidden"]}}
+-- out/compile --
+--- in.cue
+{
+  foo: {
+    opt?: 1
+    txt: 2
+    #def: 3
+    regular: 4
+    _hidden: 5
+  }
+  comp: {
+    for k, v in 〈1;foo〉 {
+      "\(〈1;k〉)": 〈1;v〉
+    }
+  }
+  select: {
+    opt: 〈1;foo〉.opt
+    txt: 〈1;foo〉.txt
+    #def: 〈1;foo〉.#def
+    regular: 〈1;foo〉.regular
+    _hidden: 〈1;foo〉._hidden
+  }
+  index: {
+    opt: 〈1;foo〉["opt"]
+    txt: 〈1;foo〉["txt"]
+    #def: 〈1;foo〉["#def"]
+    regular: 〈1;foo〉["regular"]
+    _hidden: 〈1;foo〉["_hidden"]
+  }
+}
diff --git a/cue/testdata/fulleval/030_retain_references_with_interleaved_embedding.txtar b/cue/testdata/fulleval/030_retain_references_with_interleaved_embedding.txtar
index a5cc8b4..c6aa3d4 100644
--- a/cue/testdata/fulleval/030_retain_references_with_interleaved_embedding.txtar
+++ b/cue/testdata/fulleval/030_retain_references_with_interleaved_embedding.txtar
@@ -4,35 +4,35 @@
 #evalFull
 -- in.cue --
 a: d: {
-	base
-	info :: {...}
-	Y: info.X
+	#base
+	#info: {...}
+	Y: #info.X
 }
 
-base :: {
-	info :: {...}
+#base: {
+	#info: {...}
 }
 
-a: [Name=string]: {info :: {
+a: [Name=string]: {#info: {
 	X: "foo"
 }}
 -- out/def --
 a: {
 	{[Name=string]: {
-		info :: {
+		#info: {
 			X: "foo"
 		}
 	}}
 	d: {
-		info :: {
+		#info: {
 			...
 		}
-		Y: info.X
-		base
+		Y: #info.X
+		#base
 	}
 }
-base :: {
-	info :: {
+#base: {
+	#info: {
 		...
 	}
 }
@@ -49,4 +49,29 @@
 -- out/json --
 {"a":{"d":{"Y":"foo"}}}
 -- out/legacy-debug --
-<0>{a: <1>{[]: <2>(Name: string)-><3>{info :: <4>C{X: "foo"}}, d: <5>C{info :: <6>C{X: "foo"}, Y: "foo"}}, base :: <7>C{info :: <8>{...}}}
+<0>{a: <1>{[]: <2>(Name: string)-><3>{#info: <4>C{X: "foo"}}, d: <5>C{#info: <6>C{X: "foo"}, Y: "foo"}}, #base: <7>C{#info: <8>{...}}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    d: {
+      〈2;#base〉
+      #info: {
+        ...
+      }
+      Y: 〈0;#info〉.X
+    }
+  }
+  #base: {
+    #info: {
+      ...
+    }
+  }
+  a: {
+    [string]: {
+      #info: {
+        X: "foo"
+      }
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/031_comparison_against_bottom.txtar b/cue/testdata/fulleval/031_comparison_against_bottom.txtar
index 820f8f5..2dc0bc4 100644
--- a/cue/testdata/fulleval/031_comparison_against_bottom.txtar
+++ b/cue/testdata/fulleval/031_comparison_against_bottom.txtar
@@ -29,3 +29,33 @@
 i: false
 -- out/legacy-debug --
 <0>{a: true, b: _|_((1 & 2):conflicting values 1 and 2), err: _|_((1 & 2):conflicting values 1 and 2), c: true, d: false, e: _|_((1 & 2):conflicting values 1 and 2), f: true, g: false, h: true, i: false}
+-- out/compile --
+--- in.cue
+{
+  a: (_|_ == _|_)
+  b: ((〈0;err〉 == 1) & 2)
+  c: (〈0;err〉 == _|_)
+  d: (〈0;err〉 != _|_)
+  e: ((〈0;err〉 != 1) & 3)
+  f: (({
+    a: 1
+  } & {
+    a: 2
+  }) == _|_)
+  g: (({
+    a: 1
+  } & {
+    b: 2
+  }) == _|_)
+  h: (_|_ == ({
+    a: 1
+  } & {
+    a: 2
+  }))
+  i: (_|_ == ({
+    a: 1
+  } & {
+    b: 2
+  }))
+  err: (1 & 2)
+}
diff --git a/cue/testdata/fulleval/032_or_builtin_should_not_fail_on_non-concrete_empty_list.txtar b/cue/testdata/fulleval/032_or_builtin_should_not_fail_on_non-concrete_empty_list.txtar
index 2ab4f21..b3e4875 100644
--- a/cue/testdata/fulleval/032_or_builtin_should_not_fail_on_non-concrete_empty_list.txtar
+++ b/cue/testdata/fulleval/032_or_builtin_should_not_fail_on_non-concrete_empty_list.txtar
@@ -3,26 +3,26 @@
 #name: or builtin should not fail on non-concrete empty list
 #evalFull
 -- in.cue --
-Workflow :: {
+#Workflow: {
 	jobs: {
 		[jobID=string]: {
 		}
 	}
-	JobID :: or([ for k, _ in jobs {k}])
+	#JobID: or([ for k, _ in jobs {k}])
 }
 
-foo: Workflow & {
+foo: #Workflow & {
 	jobs: foo: {
 	}
 }
 -- out/def --
-Workflow :: {
+#Workflow: {
 	jobs: {
 		[jobID=string]: {}
 	}
-	JobID :: or([ for k, _ in jobs { k } ])
+	#JobID: or([ for k, _ in jobs { k } ])
 }
-foo: Workflow & {
+foo: #Workflow & {
 	jobs: {
 		foo: {}
 	}
@@ -40,4 +40,4 @@
 -- out/json --
 {"foo":{"jobs":{"foo":{}}}}
 -- out/legacy-debug --
-<0>{Workflow :: <1>C{jobs: <2>{[]: <3>(jobID: string)-><4>C{}, }, JobID :: or ([ <5>for k, _ in <6>.jobs yield <5>.k ])}, foo: <7>C{jobs: <8>{[]: <9>(jobID: string)-><10>C{}, foo: <11>C{}}, JobID :: "foo"}}
+<0>{#Workflow: <1>C{jobs: <2>{[]: <3>(jobID: string)-><4>C{}, }, #JobID: or ([ <5>for k, _ in <6>.jobs yield <5>.k ])}, foo: <7>C{jobs: <8>{[]: <9>(jobID: string)-><10>C{}, foo: <11>C{}}, #JobID: "foo"}}
diff --git "a/cue/testdata/fulleval/033_Issue_\043153.txtar" "b/cue/testdata/fulleval/033_Issue_\043153.txtar"
index 778cd79..8d208ba 100644
--- "a/cue/testdata/fulleval/033_Issue_\043153.txtar"
+++ "b/cue/testdata/fulleval/033_Issue_\043153.txtar"
@@ -4,10 +4,10 @@
 #evalFull
 -- in.cue --
 Foo: {
-	listOfCloseds: [...Closed]
+	listOfCloseds: [...#Closed]
 }
 
-Closed :: {
+#Closed: {
 	a: int | *0
 }
 
@@ -24,15 +24,39 @@
 }
 -- out/def --
 Foo: {
-	listOfCloseds: [...Closed]
+	listOfCloseds: [...#Closed]
 }
 listOfCloseds: [_|_, // field "b" not allowed in closed struct
 ]
-Closed :: {
+#Closed: {
 	a: int | *0
 }
 Junk: {
 	b: 2
 }
 -- out/legacy-debug --
-<0>{<1>{listOfCloseds: [_|_(<2>.v:field "b" not allowed in closed struct)]}, Foo: <3>{listOfCloseds: []}, Closed :: <4>C{a: 0}, Junk: <5>{b: 2}}
+<0>{<1>{listOfCloseds: [_|_(<2>.v:field "b" not allowed in closed struct)]}, Foo: <3>{listOfCloseds: []}, #Closed: <4>C{a: 0}, Junk: <5>{b: 2}}
+-- out/compile --
+--- in.cue
+{
+  Foo: {
+    listOfCloseds: [
+      ...〈1;#Closed〉,
+    ]
+  }
+  #Closed: {
+    a: (int|*0)
+  }
+  Junk: {
+    b: 2
+  }
+  (〈0;Foo〉 & {
+    listOfCloseds: [
+      {
+        for k, v in 〈2;Junk〉 {
+          "\(〈1;k〉)": 〈1;v〉
+        }
+      },
+    ]
+  })
+}
diff --git a/cue/testdata/fulleval/034_label_and_field_aliases.txtar b/cue/testdata/fulleval/034_label_and_field_aliases.txtar
index 71be1b6..6da9b27 100644
--- a/cue/testdata/fulleval/034_label_and_field_aliases.txtar
+++ b/cue/testdata/fulleval/034_label_and_field_aliases.txtar
@@ -43,3 +43,19 @@
 {"p":{},"foo=bar":"str","a":"str","bb":4,"b1":4,"c":5,"str":5}
 -- out/legacy-debug --
 <0>{p: <1>{[]: <2>(ID: string)-><3>{name: <2>.ID}, }, "foo=bar": "str", a: "str", bb: 4, b1: 4, c: 5, str: 5}
+-- out/compile --
+--- in.cue
+{
+  p: {
+    [string]: {
+      name: 〈1;-〉
+    }
+  }
+  "foo=bar": "str"
+  a: 〈0;"foo=bar"〉
+  bb: 4
+  b1: 〈0;bb〉
+  b1: 〈0;bb〉
+  "\(〈0;a〉)": 5
+  c: 〈0;("\(〈0;a〉)")〉
+}
diff --git a/cue/testdata/fulleval/035_optionals_with_label_filters.txtar b/cue/testdata/fulleval/035_optionals_with_label_filters.txtar
new file mode 100644
index 0000000..db328a6
--- /dev/null
+++ b/cue/testdata/fulleval/035_optionals_with_label_filters.txtar
@@ -0,0 +1,102 @@
+# DO NOT EDIT; generated by go run testdata/gen.go
+#
+#name: optionals with label filters
+#evalFull
+-- in.cue --
+#JobID: =~"^[a-zA-Z]*$"
+#Job: {
+	name: string
+	cmd:  string
+}
+#Jobs: {
+	{[#JobID]: #Job}
+
+	{[=~"Test$"]: name: =~"^test"}// Must work without ...
+}
+
+jobs: foo: name: "allGood"
+jobs: foo: name: "allGood"
+
+jobs1:          #Jobs
+jobs1: foo1: {} // faulty
+
+jobs2: #Jobs
+jobs2: fooTest: name: "badName" // faulty
+
+jobs3: #Jobs
+jobs3: [string]: #Job
+jobs3: fooTest1: name: "badName" // faulty
+-- out/def --
+#JobID: =~"^[a-zA-Z]*$"
+#Job: {
+	name: string
+	cmd:  string
+}
+#Jobs: {
+	{[#JobID]: #Job}
+	{[=~"Test$"]: {
+		name: =~"^test", ...
+	}}
+}
+jobs: {
+	foo: {
+		name: "allGood"
+	}
+}
+jobs1: _|_ // field "foo1" not allowed in closed struct
+jobs2: #Jobs & {
+	fooTest: {
+		name: "badName"
+	}
+}
+jobs3: _|_ // field "fooTest1" not allowed in closed struct
+-- out/legacy-debug --
+<0>{#JobID: =~"^[a-zA-Z]*$", #Job: <1>C{name: string, cmd: string}, #Jobs: <2>C{[=~"^[a-zA-Z]*$"]: <3>(_: string)-><4>.#Job, [=~"Test$"]: <5>(_: string)-><6>C{name: =~"^test"}, }, jobs: <7>{foo: <8>{name: "allGood"}}, jobs1: _|_(<9>{}:field "foo1" not allowed in closed struct), jobs2: <10>C{[=~"^[a-zA-Z]*$"]: <11>(_: string)-><4>.#Job, [=~"Test$"]: <12>(_: string)-><13>C{name: =~"^test"}, fooTest: _|_(string:field "cmd" not allowed in closed struct)}, jobs3: _|_(<14>{name: "badName"}:field "fooTest1" not allowed in closed struct)}
+-- out/compile --
+--- in.cue
+{
+  #JobID: =~"^[a-zA-Z]*$"
+  #Job: {
+    name: string
+    cmd: string
+  }
+  #Jobs: {
+    {
+      [〈2;#JobID〉]: 〈2;#Job〉
+    }
+    {
+      [=~"Test$"]: {
+        name: =~"^test"
+      }
+    }
+  }
+  jobs: {
+    foo: {
+      name: "allGood"
+    }
+  }
+  jobs: {
+    foo: {
+      name: "allGood"
+    }
+  }
+  jobs1: 〈0;#Jobs〉
+  jobs1: {
+    foo1: {}
+  }
+  jobs2: 〈0;#Jobs〉
+  jobs2: {
+    fooTest: {
+      name: "badName"
+    }
+  }
+  jobs3: 〈0;#Jobs〉
+  jobs3: {
+    [string]: 〈1;#Job〉
+  }
+  jobs3: {
+    fooTest1: {
+      name: "badName"
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/035_optionals_with_label_fiters.txtar b/cue/testdata/fulleval/035_optionals_with_label_fiters.txtar
deleted file mode 100644
index eef1089..0000000
--- a/cue/testdata/fulleval/035_optionals_with_label_fiters.txtar
+++ /dev/null
@@ -1,53 +0,0 @@
-# DO NOT EDIT; generated by go run testdata/gen.go
-#
-#name: optionals with label fiters
-#evalFull
--- in.cue --
-JobID :: =~"^[a-zA-Z]*$"
-Job :: {
-	name: string
-	cmd:  string
-}
-Jobs :: {
-	[JobID]: Job
-	[=~"Test$"]: name: =~"^test" // Must work without ...
-}
-
-jobs: foo: name: "allGood"
-jobs: foo: name: "allGood"
-
-jobs1:          Jobs
-jobs1: foo1: {} // faulty
-
-jobs2: Jobs
-jobs2: fooTest: name: "badName" // faulty
-
-jobs3: Jobs
-jobs3: [string]: Job
-jobs3: fooTest1: name: "badName" // faulty
--- out/def --
-JobID :: =~"^[a-zA-Z]*$"
-Job :: {
-	name: string
-	cmd:  string
-}
-Jobs :: {
-	{[JobID]: Job}
-	{[=~"Test$"]: {
-		name: =~"^test"
-	}}
-}
-jobs: {
-	foo: {
-		name: "allGood"
-	}
-}
-jobs1: _|_ // field "foo1" not allowed in closed struct
-jobs2: Jobs & {
-	fooTest: {
-		name: "badName"
-	}
-}
-jobs3: _|_ // field "fooTest1" not allowed in closed struct
--- out/legacy-debug --
-<0>{JobID :: =~"^[a-zA-Z]*$", Job :: <1>C{name: string, cmd: string}, Jobs :: <2>C{[=~"^[a-zA-Z]*$"]: <3>(_: string)-><4>.Job, [=~"Test$"]: <5>(_: string)-><6>C{name: =~"^test"}, }, jobs: <7>{foo: <8>{name: "allGood"}}, jobs1: _|_(<9>{}:field "foo1" not allowed in closed struct), jobs2: <10>C{[=~"^[a-zA-Z]*$"]: <11>(_: string)-><4>.Job, [=~"Test$"]: <12>(_: string)-><13>C{name: =~"^test"}, fooTest: _|_(string:field "cmd" not allowed in closed struct)}, jobs3: _|_(<14>{name: "badName"}:field "fooTest1" not allowed in closed struct)}
diff --git a/cue/testdata/fulleval/036_optionals_in_open_structs.txtar b/cue/testdata/fulleval/036_optionals_in_open_structs.txtar
index 5fded3b..584ab4c 100644
--- a/cue/testdata/fulleval/036_optionals_in_open_structs.txtar
+++ b/cue/testdata/fulleval/036_optionals_in_open_structs.txtar
@@ -9,8 +9,8 @@
 B: {
 	[=~"^[m-z]*$"]: int
 }
-C :: {A & B}
-c: C & {aaa: 3}
+#C: {A & B}
+c: #C & {aaa: 3}
 -- out/def --
 A: {
 	[=~"^[a-s]*$"]: int
@@ -18,10 +18,10 @@
 B: {
 	[=~"^[m-z]*$"]: int
 }
-C :: {
+#C: {
 	A & B
 }
-c: C & {
+c: #C & {
 	aaa: 3
 }
 -- out/export --
@@ -38,4 +38,20 @@
 -- out/json --
 {"A":{},"B":{},"c":{"aaa":3}}
 -- out/legacy-debug --
-<0>{A: <1>{[=~"^[a-s]*$"]: <2>(_: string)->int, }, B: <3>{[=~"^[m-z]*$"]: <4>(_: string)->int, }, C :: <5>C{[=~"^[a-s]*$"]: <6>(_: string)->int, [=~"^[m-z]*$"]: <7>(_: string)->int, }, c: <8>C{[=~"^[a-s]*$"]: <9>(_: string)->int, [=~"^[m-z]*$"]: <10>(_: string)->int, aaa: 3}}
+<0>{A: <1>{[=~"^[a-s]*$"]: <2>(_: string)->int, }, B: <3>{[=~"^[m-z]*$"]: <4>(_: string)->int, }, #C: <5>C{[=~"^[a-s]*$"]: <6>(_: string)->int, [=~"^[m-z]*$"]: <7>(_: string)->int, }, c: <8>C{[=~"^[a-s]*$"]: <9>(_: string)->int, [=~"^[m-z]*$"]: <10>(_: string)->int, aaa: 3}}
+-- out/compile --
+--- in.cue
+{
+  A: {
+    [=~"^[a-s]*$"]: int
+  }
+  B: {
+    [=~"^[m-z]*$"]: int
+  }
+  #C: {
+    (〈1;A〉 & 〈1;B〉)
+  }
+  c: (〈0;#C〉 & {
+    aaa: 3
+  })
+}
diff --git a/cue/testdata/fulleval/037_conjunction_of_optional_sets.txtar b/cue/testdata/fulleval/037_conjunction_of_optional_sets.txtar
index 1679797..ceaed37 100644
--- a/cue/testdata/fulleval/037_conjunction_of_optional_sets.txtar
+++ b/cue/testdata/fulleval/037_conjunction_of_optional_sets.txtar
@@ -3,30 +3,50 @@
 #name: conjunction of optional sets
 #evalFull
 -- in.cue --
-A :: {
+#A: {
 	[=~"^[a-s]*$"]: int
 }
-B :: {
+#B: {
 	[=~"^[m-z]*$"]: int
 }
 
-C :: A & B
-c:   C & {aaa: 3}
+#C: #A & #B
+c:  #C & {aaa: 3}
 
-D :: {A & B}
-d: D & {aaa: 3}
+#D: {#A & #B}
+d: #D & {aaa: 3}
 -- out/def --
-A :: {
+#A: {
 	[=~"^[a-s]*$"]: int
 }
-B :: {
+#B: {
 	[=~"^[m-z]*$"]: int
 }
-C :: A & B
-c:   _|_ // field "aaa" not allowed in closed struct
-D :: {
-	A & B
+#C: #A & #B
+c:  _|_ // field "aaa" not allowed in closed struct
+#D: {
+	#A & #B
 }
 d: _|_ // field "aaa" not allowed in closed struct
 -- out/legacy-debug --
-<0>{A :: <1>C{[=~"^[a-s]*$"]: <2>(_: string)->int, }, B :: <3>C{[=~"^[m-z]*$"]: <4>(_: string)->int, }, C :: <5>C{(C{[=~"^[a-s]*$"]: <6>(_: string)->int} & C{[=~"^[m-z]*$"]: <7>(_: string)->int}), }, c: _|_(3:field "aaa" not allowed in closed struct), D :: <8>C{(C{[=~"^[a-s]*$"]: <9>(_: string)->int} & C{[=~"^[m-z]*$"]: <10>(_: string)->int}), }, d: _|_(3:field "aaa" not allowed in closed struct)}
+<0>{#A: <1>C{[=~"^[a-s]*$"]: <2>(_: string)->int, }, #B: <3>C{[=~"^[m-z]*$"]: <4>(_: string)->int, }, #C: <5>C{(C{[=~"^[a-s]*$"]: <6>(_: string)->int} & C{[=~"^[m-z]*$"]: <7>(_: string)->int}), }, c: _|_(3:field "aaa" not allowed in closed struct), #D: <8>C{(C{[=~"^[a-s]*$"]: <9>(_: string)->int} & C{[=~"^[m-z]*$"]: <10>(_: string)->int}), }, d: _|_(3:field "aaa" not allowed in closed struct)}
+-- out/compile --
+--- in.cue
+{
+  #A: {
+    [=~"^[a-s]*$"]: int
+  }
+  #B: {
+    [=~"^[m-z]*$"]: int
+  }
+  #C: (〈0;#A〉 & 〈0;#B〉)
+  c: (〈0;#C〉 & {
+    aaa: 3
+  })
+  #D: {
+    (〈1;#A〉 & 〈1;#B〉)
+  }
+  d: (〈0;#D〉 & {
+    aaa: 3
+  })
+}
diff --git a/cue/testdata/fulleval/038_continue_recursive_closing_for_optionals.txtar b/cue/testdata/fulleval/038_continue_recursive_closing_for_optionals.txtar
index 4784ad6..b0bf47e 100644
--- a/cue/testdata/fulleval/038_continue_recursive_closing_for_optionals.txtar
+++ b/cue/testdata/fulleval/038_continue_recursive_closing_for_optionals.txtar
@@ -3,22 +3,36 @@
 #name: continue recursive closing for optionals
 #evalFull
 -- in.cue --
-S :: {
+#S: {
 	[string]: {a: int}
 }
-a: S & {
+a: #S & {
 	v: {b: int}
 }
 -- out/def --
-S :: {
+#S: {
 	[string]: {
 		a: int
 	}
 }
-a: S & {
+a: #S & {
 	v: {
 		b: int
 	}
 }
 -- out/legacy-debug --
-<0>{S :: <1>{[]: <2>(_: string)-><3>C{a: int}, }, a: <4>{[]: <5>(_: string)-><6>C{a: int}, v: _|_(int:field "b" not allowed in closed struct)}}
+<0>{#S: <1>{[]: <2>(_: string)-><3>C{a: int}, }, a: <4>{[]: <5>(_: string)-><6>C{a: int}, v: _|_(int:field "b" not allowed in closed struct)}}
+-- out/compile --
+--- in.cue
+{
+  #S: {
+    [string]: {
+      a: int
+    }
+  }
+  a: (〈0;#S〉 & {
+    v: {
+      b: int
+    }
+  })
+}
diff --git a/cue/testdata/fulleval/039_augment_closed_optionals.txtar b/cue/testdata/fulleval/039_augment_closed_optionals.txtar
index 2bc1433..daabec7 100644
--- a/cue/testdata/fulleval/039_augment_closed_optionals.txtar
+++ b/cue/testdata/fulleval/039_augment_closed_optionals.txtar
@@ -3,41 +3,41 @@
 #name: augment closed optionals
 #evalFull
 -- in.cue --
-A :: {
+#A: {
 	[=~"^[a-s]*$"]: int
 }
-B :: {
+#B: {
 	[=~"^[m-z]*?"]: int
 }
-C :: {
-	A & B
-	[=~"^Q*$"]: int
-}
-c: C & {QQ: 3}
-D :: {
-	A
-	B
-}
-d: D & {aaa: 4}
--- out/def --
-A :: {
-	[=~"^[a-s]*$"]: int
-}
-B :: {
-	[=~"^[m-z]*?"]: int
-}
-C :: {
+#C: {
+	#A & #B
 	{[=~"^Q*$"]: int}
-	A & B
 }
-c: C & {
+c: #C & {QQ: 3}
+#D: {
+	#A
+	#B
+}
+d: #D & {aaa: 4}
+-- out/def --
+#A: {
+	[=~"^[a-s]*$"]: int
+}
+#B: {
+	[=~"^[m-z]*?"]: int
+}
+#C: {
+	#A & #B
+	{[=~"^Q*$"]: int}
+}
+c: #C & {
 	QQ: 3
 }
-D :: {
-	A
-	B
+#D: {
+	#A
+	#B
 }
-d: D & {
+d: #D & {
 	aaa: 4
 }
 -- out/export --
@@ -55,4 +55,30 @@
 -- out/json --
 {"c":{"QQ":3},"d":{"aaa":4}}
 -- out/legacy-debug --
-<0>{A :: <1>C{[=~"^[a-s]*$"]: <2>(_: string)->int, }, B :: <3>C{[=~"^[m-z]*?"]: <4>(_: string)->int, }, C :: <5>C{C{[=~"^Q*$"]: <6>(_: string)->int}, C{(C{[=~"^[a-s]*$"]: <7>(_: string)->int} & C{[=~"^[m-z]*?"]: <8>(_: string)->int})}, }, c: <9>C{C{[=~"^Q*$"]: <10>(_: string)->int}, C{(C{[=~"^[a-s]*$"]: <11>(_: string)->int} & C{[=~"^[m-z]*?"]: <12>(_: string)->int})}, QQ: 3}, D :: <13>C{[=~"^[a-s]*$"]: <14>(_: string)->int, [=~"^[m-z]*?"]: <15>(_: string)->int, }, d: <16>C{[=~"^[a-s]*$"]: <17>(_: string)->int, [=~"^[m-z]*?"]: <18>(_: string)->int, aaa: 4}}
+<0>{#A: <1>C{[=~"^[a-s]*$"]: <2>(_: string)->int, }, #B: <3>C{[=~"^[m-z]*?"]: <4>(_: string)->int, }, #C: <5>C{C{[=~"^Q*$"]: <6>(_: string)->int}, C{(C{[=~"^[a-s]*$"]: <7>(_: string)->int} & C{[=~"^[m-z]*?"]: <8>(_: string)->int})}, }, c: <9>C{C{[=~"^Q*$"]: <10>(_: string)->int}, C{(C{[=~"^[a-s]*$"]: <11>(_: string)->int} & C{[=~"^[m-z]*?"]: <12>(_: string)->int})}, QQ: 3}, #D: <13>C{[=~"^[a-s]*$"]: <14>(_: string)->int, [=~"^[m-z]*?"]: <15>(_: string)->int, }, d: <16>C{[=~"^[a-s]*$"]: <17>(_: string)->int, [=~"^[m-z]*?"]: <18>(_: string)->int, aaa: 4}}
+-- out/compile --
+--- in.cue
+{
+  #A: {
+    [=~"^[a-s]*$"]: int
+  }
+  #B: {
+    [=~"^[m-z]*?"]: int
+  }
+  #C: {
+    (〈1;#A〉 & 〈1;#B〉)
+    {
+      [=~"^Q*$"]: int
+    }
+  }
+  c: (〈0;#C〉 & {
+    QQ: 3
+  })
+  #D: {
+    〈1;#A〉
+    〈1;#B〉
+  }
+  d: (〈0;#D〉 & {
+    aaa: 4
+  })
+}
diff --git a/cue/testdata/fulleval/040.txtar b/cue/testdata/fulleval/040.txtar
index dc24e55..8a6a51c 100644
--- a/cue/testdata/fulleval/040.txtar
+++ b/cue/testdata/fulleval/040.txtar
@@ -2,7 +2,7 @@
 #
 #evalFull
 -- in.cue --
-Task :: {
+#Task: {
 	{
 		op:          "pull"
 		tag:         *"latest" | string
@@ -14,9 +14,9 @@
 	}
 }
 
-foo: Task & {"op": "pull"}
+foo: #Task & {"op": "pull"}
 -- out/def --
-Task :: {
+#Task: {
 	op:          "pull"
 	tag:         *"latest" | string
 	refToTag:    tag
@@ -25,7 +25,7 @@
 } | {
 	op: "scratch"
 }
-foo: Task & {
+foo: #Task & {
 	op: "pull"
 }
 -- out/export --
@@ -46,4 +46,22 @@
 -- out/json --
 {"foo":{"op":"pull","tag":"latest","refToTag":"latest","tagExpr":"latestdd","tagInString":"latest"}}
 -- out/legacy-debug --
-<0>{Task :: (<1>C{op: "pull", tag: (*"latest" | string), refToTag: <1>.tag, tagExpr: (<1>.tag + "dd"), tagInString: ""+<1>.tag+""} | <2>C{op: "scratch"}), foo: <3>C{op: "pull", tag: "latest", refToTag: "latest", tagExpr: "latestdd", tagInString: "latest"}}
+<0>{#Task: (<1>C{op: "pull", tag: (*"latest" | string), refToTag: <1>.tag, tagExpr: (<1>.tag + "dd"), tagInString: ""+<1>.tag+""} | <2>C{op: "scratch"}), foo: <3>C{op: "pull", tag: "latest", refToTag: "latest", tagExpr: "latestdd", tagInString: "latest"}}
+-- out/compile --
+--- in.cue
+{
+  #Task: {
+    ({
+      op: "pull"
+      tag: (*"latest"|string)
+      refToTag: 〈0;tag〉
+      tagExpr: (〈0;tag〉 + "dd")
+      tagInString: "\(〈0;tag〉)"
+    }|{
+      op: "scratch"
+    })
+  }
+  foo: (〈0;#Task〉 & {
+    op: "pull"
+  })
+}
diff --git a/cue/testdata/fulleval/041.txtar b/cue/testdata/fulleval/041.txtar
index 4776cd5..ea9458f 100644
--- a/cue/testdata/fulleval/041.txtar
+++ b/cue/testdata/fulleval/041.txtar
@@ -3,21 +3,34 @@
 #evalFull
 -- in.cue --
 t: {
-	ok :: *true | bool
-	if ok {
+	#ok: *true | bool
+	if #ok {
 		x: int
 	}
 }
 s: t & {
-	ok :: false
+	#ok: false
 }
 -- out/def --
 t: {
-	x:    int
-	ok :: *true | bool
+	x:   int
+	#ok: *true | bool
 }
 s: t & {
-	ok :: false
+	#ok: false
 }
 -- out/legacy-debug --
-<0>{t: <1>{x: int, ok :: true}, s: <2>{ok :: false}}
+<0>{t: <1>{x: int, #ok: true}, s: <2>{#ok: false}}
+-- out/compile --
+--- in.cue
+{
+  t: {
+    #ok: (*true|bool)
+    if 〈0;#ok〉 {
+      x: int
+    }
+  }
+  s: (〈0;t〉 & {
+    #ok: false
+  })
+}
diff --git a/cue/testdata/fulleval/042_cross-dependent_comprehension.txtar b/cue/testdata/fulleval/042_cross-dependent_comprehension.txtar
index 8df3a21..ba83101 100644
--- a/cue/testdata/fulleval/042_cross-dependent_comprehension.txtar
+++ b/cue/testdata/fulleval/042_cross-dependent_comprehension.txtar
@@ -3,22 +3,38 @@
 #name: cross-dependent comprehension
 #evalFull
 -- in.cue --
-a :: {
+#a: {
 	if b {
 		c: 4
 	}
 	b: bool
 }
-x: (a & {b: true}) & {c: 4}
+x: (#a & {b: true}) & {c: 4}
 y: x
 -- out/def --
 x: _|_ // field "c" not allowed in closed struct
 y: _|_ // field "c" not allowed in closed struct
-a :: {
+#a: {
 	b: bool
 	if b {
 		c: 4
 	}
 }
 -- out/legacy-debug --
-<0>{x: _|_(4:field "c" not allowed in closed struct), y: _|_(4:field "c" not allowed in closed struct), a :: <1>C{b: bool if <2>.b yield <3>C{c: 4}}}
+<0>{x: _|_(4:field "c" not allowed in closed struct), y: _|_(4:field "c" not allowed in closed struct), #a: <1>C{b: bool if <2>.b yield <3>C{c: 4}}}
+-- out/compile --
+--- in.cue
+{
+  #a: {
+    if 〈0;b〉 {
+      c: 4
+    }
+    b: bool
+  }
+  x: ((〈0;#a〉 & {
+    b: true
+  }) & {
+    c: 4
+  })
+  y: 〈0;x〉
+}
diff --git a/cue/testdata/fulleval/043_optional_expanded_before_lookup.txtar b/cue/testdata/fulleval/043_optional_expanded_before_lookup.txtar
index b9e21e1..6240798 100644
--- a/cue/testdata/fulleval/043_optional_expanded_before_lookup.txtar
+++ b/cue/testdata/fulleval/043_optional_expanded_before_lookup.txtar
@@ -52,3 +52,19 @@
 {"test":{"A":{"name":"A","field1":"1","field2":"2"}},"B":{"name":"A","field1":"1","field2":"2"}}
 -- out/legacy-debug --
 <0>{test: <1>{[]: <2>(ID: string)-><3>{name: <2>.ID}, A: <4>{name: "A", field1: "1", field2: "2"}}, B: <5>{name: "A", field1: "1", field2: "2"}}
+-- out/compile --
+--- in.cue
+{
+  test: {
+    [_]: {
+      name: 〈1;-〉
+    }
+  }
+  test: {
+    A: {
+      field1: "1"
+      field2: "2"
+    }
+  }
+  B: (〈0;test〉.A & {})
+}
diff --git a/cue/testdata/fulleval/045_comprehension_and_skipped_field.txtar b/cue/testdata/fulleval/045_comprehension_and_skipped_field.txtar
index 2e6c45a..c3eabd7 100644
--- a/cue/testdata/fulleval/045_comprehension_and_skipped_field.txtar
+++ b/cue/testdata/fulleval/045_comprehension_and_skipped_field.txtar
@@ -1,6 +1,7 @@
 # DO NOT EDIT; generated by go run testdata/gen.go
 #
 #name: comprehension and skipped field
+#bug: true
 #evalFull
 -- in.cue --
 
@@ -17,5 +18,34 @@
 	}
 	_p: 3
 }
+-- out/export --
+x: {
+	v: {
+		"1": 2
+	}
+}
+-- out/yaml --
+x:
+  v:
+    "1": 2
+-- out/json --
 -- out/legacy-debug --
 <0>{x: <1>{v: <2>{"1": 2}, _p: 3}}
+-- out/compile --
+--- in.cue
+{
+  for key, value in {
+    x: {
+      v: 1
+    }
+  } {
+    "\(〈1;key〉)": {
+      v: (*{
+        for pod, _ in 〈3;value〉.v {}
+      }|{
+        "\(〈3;value〉.v)": 2
+      })
+      _p: 3
+    }
+  }
+}
diff --git a/cue/testdata/fulleval/046_non-structural_direct_cycles.txtar b/cue/testdata/fulleval/046_non-structural_direct_cycles.txtar
index 6e08cf7..6671153 100644
--- a/cue/testdata/fulleval/046_non-structural_direct_cycles.txtar
+++ b/cue/testdata/fulleval/046_non-structural_direct_cycles.txtar
@@ -14,3 +14,15 @@
 c2: _|_ // conflicting values {bar: 1} and 1 (mismatched types struct and int)
 -- out/legacy-debug --
 <0>{c1: <1>{bar: <2>{baz: 2}, baz: 2}, c2: _|_(conflicting values {bar: 1} and 1 (mismatched types struct and int))}
+-- out/compile --
+--- in.cue
+{
+  c1: ({
+    bar: {
+      baz: 2
+    }
+  } & 〈0;c1〉.bar)
+  c2: ({
+    bar: 1
+  } & 〈0;c2〉.bar)
+}
diff --git a/cue/testdata/fulleval/047_dont_bind_to_string_labels.txtar b/cue/testdata/fulleval/047_dont_bind_to_string_labels.txtar
index 617284d..0092645 100644
--- a/cue/testdata/fulleval/047_dont_bind_to_string_labels.txtar
+++ b/cue/testdata/fulleval/047_dont_bind_to_string_labels.txtar
@@ -1,6 +1,6 @@
 # DO NOT EDIT; generated by go run testdata/gen.go
 #
-#name: don't bind to string labels
+#name: dont bind to string labels
 #evalFull
 -- in.cue --
 x: 1
@@ -29,3 +29,12 @@
 {"x":1,"y":{"x":2,"z":1}}
 -- out/legacy-debug --
 <0>{x: 1, y: <1>{x: 2, z: 1}}
+-- out/compile --
+--- in.cue
+{
+  x: 1
+  y: {
+    x: 2
+    z: 〈1;x〉
+  }
+}
diff --git a/cue/testdata/fulleval/048_dont_pass_incomplete_values_to_builtins.txtar b/cue/testdata/fulleval/048_dont_pass_incomplete_values_to_builtins.txtar
index 7cd10c1..a180d34 100644
--- a/cue/testdata/fulleval/048_dont_pass_incomplete_values_to_builtins.txtar
+++ b/cue/testdata/fulleval/048_dont_pass_incomplete_values_to_builtins.txtar
@@ -1,6 +1,6 @@
 # DO NOT EDIT; generated by go run testdata/gen.go
 #
-#name: don't pass incomplete values to builtins
+#name: dont pass incomplete values to builtins
 #evalFull
 -- in.cue --
 import "encoding/json"
diff --git a/cue/testdata/fulleval/049_alias_reuse_in_nested_scope.txtar b/cue/testdata/fulleval/049_alias_reuse_in_nested_scope.txtar
index 78efaa2..cf00d94 100644
--- a/cue/testdata/fulleval/049_alias_reuse_in_nested_scope.txtar
+++ b/cue/testdata/fulleval/049_alias_reuse_in_nested_scope.txtar
@@ -3,23 +3,23 @@
 #name: alias reuse in nested scope
 #evalFull
 -- in.cue --
-Foo :: {
+#Foo: {
 	let X = or([ for k, _ in {} {k}])
 	connection: [X]: X
 }
-A :: {
+#A: {
 	foo: "key"
 	let X = foo
 	a: foo: [X]: X
 }
-B :: {
+#B: {
 	foo: string
 	let X = foo
 	a: foo: [X]: X
 }
-b: B & {foo: "key"}
+b: #B & {foo: "key"}
 -- out/def --
-Foo :: {
+#Foo: {
 	connection: {
 		[or([ for k, _ in {
 				...
@@ -28,7 +28,7 @@
 		} { k } ])
 	}
 }
-A :: {
+#A: {
 	foo: "key"
 	a: {
 		foo: {
@@ -36,7 +36,7 @@
 		}
 	}
 }
-B :: {
+#B: {
 	foo: string
 	FOO = foo
 	a: {
@@ -45,7 +45,7 @@
 		}
 	}
 }
-b: B & {
+b: #B & {
 	foo: "key"
 }
 -- out/export --
@@ -63,4 +63,4 @@
 -- out/json --
 {"b":{"foo":"key","a":{"foo":{}}}}
 -- out/legacy-debug --
-<0>{Foo :: <1>C{connection: <2>C{[or ([ <3>for k, _ in <4>{} yield <3>.k ])]: <5>(_: string)->or ([ <3>for k, _ in <4>{} yield <3>.k ]), }}, A :: <6>C{foo: "key", a: <7>C{foo: <8>C{["key"]: <9>(_: string)-><10>.foo, }}}, B :: <11>C{foo: string, a: <12>C{foo: <13>C{[string]: <14>(_: string)-><15>.foo, }}}, b: <16>C{foo: "key", a: <17>C{foo: <18>C{["key"]: <19>(_: string)-><20>.foo, }}}}
+<0>{#Foo: <1>C{connection: <2>C{[or ([ <3>for k, _ in <4>{} yield <3>.k ])]: <5>(_: string)->or ([ <3>for k, _ in <4>{} yield <3>.k ]), }}, #A: <6>C{foo: "key", a: <7>C{foo: <8>C{["key"]: <9>(_: string)-><10>.foo, }}}, #B: <11>C{foo: string, a: <12>C{foo: <13>C{[string]: <14>(_: string)-><15>.foo, }}}, b: <16>C{foo: "key", a: <17>C{foo: <18>C{["key"]: <19>(_: string)-><20>.foo, }}}}
diff --git a/cue/testdata/fulleval/051_detectIncompleteYAML.txtar b/cue/testdata/fulleval/051_detectIncompleteYAML.txtar
index c813ca7..1cb714c 100644
--- a/cue/testdata/fulleval/051_detectIncompleteYAML.txtar
+++ b/cue/testdata/fulleval/051_detectIncompleteYAML.txtar
@@ -7,17 +7,17 @@
 
 import yaml "encoding/yaml"
 
-Spec :: {
+#Spec: {
 	_vars: {something: string}
 	data: {
-		foo :: {
+		#foo: {
 			use: _vars.something
 		}
 		baz:    yaml.Marshal(_vars.something)
-		foobar: yaml.Marshal(foo)
+		foobar: yaml.Marshal(#foo)
 	}
 }
-Val: Spec & {
+Val: #Spec & {
 	_vars: something: "var-string"
 }
 -- out/def --
@@ -25,19 +25,19 @@
 
 import "encoding/yaml"
 
-Spec :: {
+#Spec: {
 	_vars: {
 		something: string
 	}
 	data: {
-		foo :: {
+		#foo: {
 			use: _vars.something
 		}
 		baz:    yaml.Marshal(_vars.something)
-		foobar: yaml.Marshal(foo)
+		foobar: yaml.Marshal(#foo)
 	}
 }
-Val: Spec & {
+Val: #Spec & {
 	_vars: {
 		something: "var-string"
 	}
@@ -65,4 +65,4 @@
 -- out/json --
 {"Val":{"data":{"baz":"var-string\n","foobar":"use: var-string\n"}}}
 -- out/legacy-debug --
-<0>{Spec :: <1>C{_vars: <2>C{something: string}, data: <3>C{foo :: <4>C{use: string}, baz: <5>.Marshal (<6>._vars.something), foobar: <5>.Marshal (<7>.foo)}}, Val: <8>C{_vars: <9>C{something: "var-string"}, data: <10>C{foo :: <11>C{use: "var-string"}, baz: "var-string\n", foobar: "use: var-string\n"}}}
+<0>{#Spec: <1>C{_vars: <2>C{something: string}, data: <3>C{#foo: <4>C{use: string}, baz: <5>.Marshal (<6>._vars.something), foobar: <5>.Marshal (<7>.#foo)}}, Val: <8>C{_vars: <9>C{something: "var-string"}, data: <10>C{#foo: <11>C{use: "var-string"}, baz: "var-string\n", foobar: "use: var-string\n"}}}
diff --git a/cue/testdata/fulleval/052_detectIncompleteJSON.txtar b/cue/testdata/fulleval/052_detectIncompleteJSON.txtar
index 0a45cf2..5562506 100644
--- a/cue/testdata/fulleval/052_detectIncompleteJSON.txtar
+++ b/cue/testdata/fulleval/052_detectIncompleteJSON.txtar
@@ -7,17 +7,17 @@
 
 import "encoding/json"
 
-Spec :: {
+#Spec: {
 	_vars: {something: string}
 	data: {
-		foo :: {
+		#foo: {
 			use: _vars.something
 		}
 		baz:    json.Marshal(_vars.something)
-		foobar: json.Marshal(foo)
+		foobar: json.Marshal(#foo)
 	}
 }
-Val: Spec & {
+Val: #Spec & {
 	_vars: something: "var-string"
 }
 -- out/def --
@@ -25,19 +25,19 @@
 
 import "encoding/json"
 
-Spec :: {
+#Spec: {
 	_vars: {
 		something: string
 	}
 	data: {
-		foo :: {
+		#foo: {
 			use: _vars.something
 		}
 		baz:    json.Marshal(_vars.something)
-		foobar: json.Marshal(foo)
+		foobar: json.Marshal(#foo)
 	}
 }
-Val: Spec & {
+Val: #Spec & {
 	_vars: {
 		something: "var-string"
 	}
@@ -57,4 +57,4 @@
 -- out/json --
 {"Val":{"data":{"baz":"\"var-string\"","foobar":"{\"use\":\"var-string\"}"}}}
 -- out/legacy-debug --
-<0>{Spec :: <1>C{_vars: <2>C{something: string}, data: <3>C{foo :: <4>C{use: string}, baz: <5>.Marshal (<6>._vars.something), foobar: <5>.Marshal (<7>.foo)}}, Val: <8>C{_vars: <9>C{something: "var-string"}, data: <10>C{foo :: <11>C{use: "var-string"}, baz: "\"var-string\"", foobar: "{\"use\":\"var-string\"}"}}}
+<0>{#Spec: <1>C{_vars: <2>C{something: string}, data: <3>C{#foo: <4>C{use: string}, baz: <5>.Marshal (<6>._vars.something), foobar: <5>.Marshal (<7>.#foo)}}, Val: <8>C{_vars: <9>C{something: "var-string"}, data: <10>C{#foo: <11>C{use: "var-string"}, baz: "\"var-string\"", foobar: "{\"use\":\"var-string\"}"}}}
diff --git a/cue/testdata/fulleval/054_issue312.txtar b/cue/testdata/fulleval/054_issue312.txtar
index 9d98a87..8959563 100644
--- a/cue/testdata/fulleval/054_issue312.txtar
+++ b/cue/testdata/fulleval/054_issue312.txtar
@@ -20,3 +20,15 @@
 {"y":1,"a":2}
 -- out/legacy-debug --
 <0>{y: 1, a: 2}
+-- out/compile --
+--- in.cue
+{
+  y: (*1|{
+    a: 2
+  })
+  for _, x in [
+    1,
+  ] {
+    〈2;y〉
+  }
+}
diff --git a/cue/testdata/fulleval/055_issue318.txtar b/cue/testdata/fulleval/055_issue318.txtar
index 424b9fb..dc1ea58 100644
--- a/cue/testdata/fulleval/055_issue318.txtar
+++ b/cue/testdata/fulleval/055_issue318.txtar
@@ -3,7 +3,7 @@
 #name: issue318
 #evalFull
 -- in.cue --
-T :: {
+#T: {
 	arg: x: string
 	out1: "\(arg.x) \(arg.y)"
 	out2: "\(arg.y)"
@@ -11,7 +11,7 @@
 	vy:   arg.y
 }
 -- out/def --
-T :: {
+#T: {
 	arg: {
 		x: string
 	}
@@ -27,4 +27,17 @@
 -- out/json --
 {}
 -- out/legacy-debug --
-<0>{T :: <1>C{arg: <2>C{x: string}, out1: _|_(<3>.arg.y:undefined field "y"), out2: _|_(<3>.arg.y:undefined field "y"), vx: string, vy: _|_(<3>.arg.y:undefined field "y")}}
+<0>{#T: <1>C{arg: <2>C{x: string}, out1: _|_(<3>.arg.y:undefined field "y"), out2: _|_(<3>.arg.y:undefined field "y"), vx: string, vy: _|_(<3>.arg.y:undefined field "y")}}
+-- out/compile --
+--- in.cue
+{
+  #T: {
+    arg: {
+      x: string
+    }
+    out1: "\(〈0;arg〉.x) \(〈0;arg〉.y)"
+    out2: "\(〈0;arg〉.y)"
+    vx: 〈0;arg〉.x
+    vy: 〈0;arg〉.y
+  }
+}
diff --git a/cue/testdata/fulleval/056_issue314.txtar b/cue/testdata/fulleval/056_issue314.txtar
index 26521a3..bd175a7 100644
--- a/cue/testdata/fulleval/056_issue314.txtar
+++ b/cue/testdata/fulleval/056_issue314.txtar
@@ -11,22 +11,22 @@
 
 x: {
 	s: "myname"
-	T
+	#T
 }
 
-T :: {
+#T: {
 	s:   string
 	out: template.Execute("{{.s}}", {
 		"s": s
 	})
 }
 
-V :: {
+#V: {
 	s:   string
 	out: json.Marshal({"s": s})
 }
 
-U :: {
+#U: {
 	s:   string
 	out: yaml.Marshal({"s": s})
 }
@@ -37,25 +37,25 @@
 	"text/template"
 )
 
-T :: {
+x: {
+	s: "myname"
+	#T
+}
+#T: {
 	s: string
 	S = s
 	out: template.Execute("{{.s}}", {
 		s: S
 	})
 }
-x: {
-	s: "myname"
-	T
-}
-V :: {
+#V: {
 	s: string
 	S658221 = s
 	out: json.Marshal({
 		s: S658221
 	})
 }
-U :: {
+#U: {
 	s: string
 	S629a0f = s
 	out: yaml.Marshal({
@@ -74,4 +74,4 @@
 -- out/json --
 {"x":{"s":"myname","out":"myname"}}
 -- out/legacy-debug --
-<0>{T :: <1>C{s: string, out: <2>.Execute ("{{.s}}",<3>C{s: <4>.s})}, x: <5>C{s: "myname", out: "myname"}, V :: <6>C{s: string, out: <7>.Marshal (<8>C{s: <9>.s})}, U :: <10>C{s: string, out: <11>.Marshal (<12>C{s: <13>.s})}}
+<0>{x: <1>C{s: "myname", out: "myname"}, #T: <2>C{s: string, out: <3>.Execute ("{{.s}}",<4>C{s: <5>.s})}, #V: <6>C{s: string, out: <7>.Marshal (<8>C{s: <9>.s})}, #U: <10>C{s: string, out: <11>.Marshal (<12>C{s: <13>.s})}}
diff --git a/cue/testdata/gen.go b/cue/testdata/gen.go
index f0269ea..5b91180 100644
--- a/cue/testdata/gen.go
+++ b/cue/testdata/gen.go
@@ -34,10 +34,15 @@
 	"cuelang.org/go/cue"
 	cueast "cuelang.org/go/cue/ast"
 	cueformat "cuelang.org/go/cue/format"
+	"cuelang.org/go/cue/parser"
 	"cuelang.org/go/internal"
 	"cuelang.org/go/pkg/encoding/yaml"
+	"cuelang.org/go/tools/fix"
 )
 
+//go:generate go run gen.go
+//go:generate go test ../internal/compile --update
+
 func main() {
 	flag.Parse()
 	log.SetFlags(log.Lshortfile)
@@ -213,6 +218,15 @@
 		case "in":
 			src := []byte(e.stringConst(f.Value))
 			src, err := cueformat.Source(src)
+
+			if f, err := parser.ParseFile("in.cue", src, parser.ParseComments); err == nil {
+				f = fix.File(f)
+				b, err := cueformat.Node(f)
+				if err == nil {
+					src = b
+				}
+			}
+
 			if err != nil {
 				fmt.Fprintln(e.header, "#skip")
 				e.warnf("Skipped: %v", err)
diff --git a/cue/testdata/readme.md b/cue/testdata/readme.md
index c8ca873..73a4b58 100644
--- a/cue/testdata/readme.md
+++ b/cue/testdata/readme.md
@@ -1,18 +1,21 @@
-## CUE Test Suite
+# CUE Test Suite
 
 This directory contains a test suite for testing the CUE language. This is only
 intended to test language evaluation and exporting. Eventually it will also
 contains tests for parsing and formatting. It is not intended to cover
 testing of the API itself.
 
-WORK IN PROGRESS
+## Overview
+
+### Work in progress
 
 The tests are currently converted from various internal Go tests and the
 grouping reflect properties of the current implementation. Once the transition
 to the new implementation is completed, tests should be reordered along more
 logical lines: such as literals, expressions, references, cycles, etc.
 
-FORESEEN STRUCTURE
+
+## Forseen Structure
 
 The txtar format allows a collection of files to be defined. Any .cue file
 is used as an input. The out/* files, which should not have an extension,
@@ -28,4 +31,19 @@
 Lines not starting with a `#` are for interpretation by the testscript package.
 
 This organization allows the same test sets to be used for the testing of
-tooling as well as internal libraries.
\ No newline at end of file
+tooling as well as internal libraries.
+
+## Common options
+
+- `#skip`: skip this test case for all tests
+- `#skip-{name}`: skip this test for the namesake test
+- `#todo-{name}`: skip this test for the namesake test, but run it if the
+   `--todo` flag is specified.
+
+
+## Tests
+
+### cue/internal/compile
+
+Compiles all *.cue files and prints the debug string of the internal
+representation. This is not valid CUE.
\ No newline at end of file
diff --git a/cue/testdata/resolve/000_convert___to_top.txtar b/cue/testdata/resolve/000_convert___to_top.txtar
index 225b213..e2f3713 100644
--- a/cue/testdata/resolve/000_convert___to_top.txtar
+++ b/cue/testdata/resolve/000_convert___to_top.txtar
@@ -16,3 +16,10 @@
 {"a":{}}
 -- out/legacy-debug --
 <0>{a: <1>{...}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    [_]: _
+  }
+}
diff --git a/cue/testdata/resolve/001.txtar b/cue/testdata/resolve/001.txtar
index e29c98d..b4af334 100644
--- a/cue/testdata/resolve/001.txtar
+++ b/cue/testdata/resolve/001.txtar
@@ -45,3 +45,19 @@
 {"a":3,"b":{"c":{"d":3}},"c":{"c":2},"d":{"d":2}}
 -- out/legacy-debug --
 <0>{a: 3, b: <1>{c: <2>{d: 3}}, c: <3>{c: 2}, d: <4>{d: 2}}
+-- out/compile --
+--- in.cue
+{
+  a: 〈0;b〉.c.d
+  b: {
+    c: {
+      d: 3
+    }
+  }
+  c: {
+    c: 〈1;d〉.d
+  }
+  d: {
+    d: 2
+  }
+}
diff --git a/cue/testdata/resolve/004.txtar b/cue/testdata/resolve/004.txtar
index fb78102..049a5aa 100644
--- a/cue/testdata/resolve/004.txtar
+++ b/cue/testdata/resolve/004.txtar
@@ -27,3 +27,14 @@
 {"a":{"d":1},"b":{"d":1}}
 -- out/legacy-debug --
 <0>{a: <1>{d: 1}, b: <2>{d: 1}}
+-- out/compile --
+--- in.cue
+{
+  a: _
+  b: 〈0;a〉
+  a: {
+    d: 1
+    d: _
+  }
+  b: _
+}
diff --git a/cue/testdata/resolve/005_JSON.txtar b/cue/testdata/resolve/005_JSON.txtar
index 96256de..1a39c93 100644
--- a/cue/testdata/resolve/005_JSON.txtar
+++ b/cue/testdata/resolve/005_JSON.txtar
@@ -34,3 +34,13 @@
 {"a":3,"b":3,"o":{"a\nb":2},"c":2}
 -- out/legacy-debug --
 <0>{a: 3, b: 3, o: <1>{"a\nb": 2}, c: 2}
+-- out/compile --
+--- in.cue
+{
+  a: 3
+  b: 〈0;a〉
+  o: {
+    "a\nb": 2
+  }
+  c: 〈0;o〉["a\nb"]
+}
diff --git a/cue/testdata/resolve/006_arithmetic.txtar b/cue/testdata/resolve/006_arithmetic.txtar
index 8578e90..506cb7d 100644
--- a/cue/testdata/resolve/006_arithmetic.txtar
+++ b/cue/testdata/resolve/006_arithmetic.txtar
@@ -18,3 +18,13 @@
 e2: _|_ // conflicting values int and (4.0 / 2.0) (mismatched types int and float)
 -- out/legacy-debug --
 <0>{v1: 5.0000000000e+11, v2: true, n1: 1, v5: 2.0, v6: 1., e2: _|_((int & (4.0 / 2.0)):conflicting values int and (4.0 / 2.0) (mismatched types int and float))}
+-- out/compile --
+--- in.cue
+{
+  v1: (1000000000000 / 2.0)
+  v2: (2.0 == 2)
+  n1: 1
+  v5: (2.0 / 〈0;n1〉)
+  v6: (1.0 / 1.0)
+  e2: (int & (4.0 / 2.0))
+}
diff --git a/cue/testdata/resolve/007_inequality.txtar b/cue/testdata/resolve/007_inequality.txtar
index 4df5fe2..5b6ffad 100644
--- a/cue/testdata/resolve/007_inequality.txtar
+++ b/cue/testdata/resolve/007_inequality.txtar
@@ -34,3 +34,13 @@
 {"a":true,"b":true,"c":false,"d":true,"e":false,"f":true}
 -- out/legacy-debug --
 <0>{a: true, b: true, c: false, d: true, e: false, f: true}
+-- out/compile --
+--- in.cue
+{
+  a: (1 != 2)
+  b: (1 != null)
+  c: (true == null)
+  d: (null != {})
+  e: (null == [])
+  f: (0 == 0.0)
+}
diff --git a/cue/testdata/resolve/008_attributes.txtar b/cue/testdata/resolve/008_attributes.txtar
index 3b4bd00..0fa6191 100644
--- a/cue/testdata/resolve/008_attributes.txtar
+++ b/cue/testdata/resolve/008_attributes.txtar
@@ -19,3 +19,17 @@
 e: _|_ // conflicting attributes for key "foo"
 -- out/legacy-debug --
 <0>{a: <1>{foo: 1 @baz(1) @foo()}, b: <2>{foo: 1 @bar() @foo()}, c: <3>{foo: 1 @bar() @baz(1) @foo()}, e: _|_((<4>.a & <5>{foo: 1 @foo(other)}):conflicting attributes for key "foo")}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    foo: 1
+  }
+  b: {
+    foo: 1
+  }
+  c: (〈0;a〉 & 〈0;b〉)
+  e: (〈0;a〉 & {
+    foo: 1
+  })
+}
diff --git a/cue/testdata/resolve/009_optional_field_unification.txtar b/cue/testdata/resolve/009_optional_field_unification.txtar
index 4e8b4db..d69ba0a 100644
--- a/cue/testdata/resolve/009_optional_field_unification.txtar
+++ b/cue/testdata/resolve/009_optional_field_unification.txtar
@@ -46,3 +46,20 @@
 {"a":{},"b":{"foo":"foo"},"c":{"foo":"foo"},"d":{},"g1":1}
 -- out/legacy-debug --
 <0>{a: <1>{foo?: string}, b: <2>{foo: "foo"}, c: <3>{foo: "foo"}, d: <4>{foo?: "bar"}, g1: 1, g2?: 2}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    foo?: string
+  }
+  b: {
+    foo: "foo"
+  }
+  c: (〈0;a〉 & 〈0;b〉)
+  d: (〈0;a〉 & {
+    foo?: "bar"
+  })
+  g1: 1
+  "g\(1)"?: 1
+  "g\(2)"?: 2
+}
diff --git a/cue/testdata/resolve/010_optional_field_resolves_to_incomplete.txtar b/cue/testdata/resolve/010_optional_field_resolves_to_incomplete.txtar
index 1067bc4..ec54948 100644
--- a/cue/testdata/resolve/010_optional_field_resolves_to_incomplete.txtar
+++ b/cue/testdata/resolve/010_optional_field_resolves_to_incomplete.txtar
@@ -16,3 +16,12 @@
 }
 -- out/legacy-debug --
 <0>{r: <1>{a?: 3, b: <2>.a, c: <3>.r["a"]}}
+-- out/compile --
+--- in.cue
+{
+  r: {
+    a?: 3
+    b: 〈0;a〉
+    c: 〈1;r〉["a"]
+  }
+}
diff --git a/cue/testdata/resolve/011_bounds.txtar b/cue/testdata/resolve/011_bounds.txtar
index ef8b147..adabfe1 100644
--- a/cue/testdata/resolve/011_bounds.txtar
+++ b/cue/testdata/resolve/011_bounds.txtar
@@ -94,3 +94,45 @@
 e9:   _|_ // conflicting values >"a" and <1 (mismatched types string and number)
 -- out/legacy-debug --
 <0>{i1: 5, i2: 5, i3: [], i4: (!=2 & !=4), s1: (>=0 & <=10 & !=1), s2: (>=0 & <=10), s3: >5, s4: <10, s5: !=2, s6: (!=2 & >=2), s7: (>=2 & !=2), s8: >5, s10: (<=10 & >1), s11: (>0 & <12), s20: 10, s22: (>5 & <=6), s22a: 6, s22b: 6, s22c: 5, s22d: 5, s22e: 5, s22f: 5, s23: (>0 & <2), s23a: 1, s23b: 1, s23c: 1, s23d: 1, s23e: (>0.0 & <2.0), s30: int & >0, e1: _|_((!=null & null):invalid value null (excluded by !=null)), e2: _|_((!=null & null):invalid value null (excluded by !=null)), e3: _|_((>1 & 1):invalid value 1 (out of bound >1)), e4: _|_((<0 & 0):invalid value 0 (out of bound <0)), e5: _|_(conflicting bounds >1 and <0), e6: _|_(conflicting bounds >11 and <11), e7: _|_(conflicting bounds >=11 and <11), e8: _|_(conflicting bounds >11 and <=11), e9: _|_((>"a" & <1):conflicting values >"a" and <1 (mismatched types string and number))}
+-- out/compile --
+--- in.cue
+{
+  i1: (>1 & 5)
+  i2: ((>=0 & <=10) & 5)
+  i3: (!=null & [])
+  i4: (!=2 & !=4)
+  s1: ((>=0 & <=10) & !=1)
+  s2: ((>=0 & <=10) & !=11)
+  s3: (>5 & !=5)
+  s4: (<10 & !=10)
+  s5: (!=2 & !=2)
+  s6: (!=2 & >=2)
+  s7: (>=2 & !=2)
+  s8: (!=5 & >5)
+  s10: (((>=0 & <=10) & <12) & >1)
+  s11: (((>0 & >=0) & <=12) & <12)
+  s20: (>=10 & <=10)
+  s22: (>5 & <=6)
+  s22a: (>5 & (<=6 & int))
+  s22b: ((int & >5) & <=6)
+  s22c: (>=5 & (<6 & int))
+  s22d: ((int & >=5) & <6)
+  s22e: ((>=5 & <6) & int)
+  s22f: (int & (>=5 & <6))
+  s23: (>0 & <2)
+  s23a: ((>0 & <2) & int)
+  s23b: (int & (>0 & <2))
+  s23c: ((int & >0) & <2)
+  s23d: (>0 & (int & <2))
+  s23e: (>0.0 & <2.0)
+  s30: (>0 & int)
+  e1: (null & !=null)
+  e2: (!=null & null)
+  e3: (>1 & 1)
+  e4: (<0 & 0)
+  e5: (>1 & <0)
+  e6: (>11 & <11)
+  e7: (>=11 & <11)
+  e8: (>11 & <=11)
+  e9: (>"a" & <1)
+}
diff --git a/cue/testdata/resolve/012_bound_conversions.txtar b/cue/testdata/resolve/012_bound_conversions.txtar
index 9579755..f42d6da 100644
--- a/cue/testdata/resolve/012_bound_conversions.txtar
+++ b/cue/testdata/resolve/012_bound_conversions.txtar
@@ -31,3 +31,18 @@
 c4: _|_ // conflicting values 1.2 and ((>=1 & <2) & int) (mismatched types float and int)
 -- out/legacy-debug --
 <0>{r0: 1, r1: 1, r2: 1, r3: -1, r4: -1, r5: 1.1, r6: 1.1, c1: _|_((>1.3 & 1.2):invalid value 1.2 (out of bound >1.3)), c2: _|_((>1.3 & 1.2):invalid value 1.2 (out of bound >1.3)), c3: 1.2, c4: _|_((1.2 & ((>=1 & <2) & int)):conflicting values 1.2 and ((>=1 & <2) & int) (mismatched types float and int))}
+-- out/compile --
+--- in.cue
+{
+  r0: ((int & >0.1) & <=1.9)
+  r1: ((int & >0.1) & <1.9)
+  r2: ((int & >=0.1) & <1.9)
+  r3: ((int & >=-1.9) & <=-0.1)
+  r4: ((int & >-1.9) & <=-0.1)
+  r5: (>=1.1 & <=1.1)
+  r6: (〈0;r5〉 & 1.1)
+  c1: ((1.2 & >1.3) & <2)
+  c2: (1.2 & (>1.3 & <2))
+  c3: (1.2 & (>=1 & <2))
+  c4: (1.2 & ((>=1 & <2) & int))
+}
diff --git a/cue/testdata/resolve/014_null_coalescing.txtar b/cue/testdata/resolve/014_null_coalescing.txtar
index 97f90ec..3d0605a 100644
--- a/cue/testdata/resolve/014_null_coalescing.txtar
+++ b/cue/testdata/resolve/014_null_coalescing.txtar
@@ -22,3 +22,10 @@
 {"a":null,"b":"b","c":"c"}
 -- out/legacy-debug --
 <0>{a: null, b: "b", c: "c"}
+-- out/compile --
+--- in.cue
+{
+  a: null
+  b: (〈0;a〉.x|"b")
+  c: (〈0;a〉["x"]|"c")
+}
diff --git a/cue/testdata/resolve/015_reference_across_tuples_and_back.txtar b/cue/testdata/resolve/015_reference_across_tuples_and_back.txtar
index f31191b..7f8a0f1 100644
--- a/cue/testdata/resolve/015_reference_across_tuples_and_back.txtar
+++ b/cue/testdata/resolve/015_reference_across_tuples_and_back.txtar
@@ -34,3 +34,15 @@
 {"a":{"c":3,"d":3},"b":{"e":3,"f":3}}
 -- out/legacy-debug --
 <0>{a: <1>{c: 3, d: 3}, b: <2>{e: 3, f: 3}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    c: 〈1;b〉.e
+    d: 〈1;b〉.f
+  }
+  b: {
+    e: 3
+    f: 〈1;a〉.c
+  }
+}
diff --git a/cue/testdata/resolve/016_index.txtar b/cue/testdata/resolve/016_index.txtar
index f5d6b0f..baa96cb 100644
--- a/cue/testdata/resolve/016_index.txtar
+++ b/cue/testdata/resolve/016_index.txtar
@@ -15,8 +15,8 @@
 e5: [1, 2, 3][-1]
 e6: (*[] | {})[1]
 def: {
-	a:   1
-	b :: 3
+	a:  1
+	#b: 3
 }
 e7: def["b"]
 -- out/def --
@@ -32,9 +32,47 @@
 e5: _|_ // invalid list index -1 (index must be non-negative)
 e6: _|_ // index 1 out of bounds
 def: {
-	a:   1
-	b :: 3
+	a:  1
+	#b: 3
 }
-e7: _|_ // field "b" is a definition
+e7: def["b"]
 -- out/legacy-debug --
-<0>{a: 2, b: "bar", c: _|_("3":invalid list index "3" (type string)), l: [], d: _|_([]:index 0 out of bounds), e1: _|_("":invalid list index "" (type string)), e2: _|_(2:invalid operation: 2[2] (type int does not support indexing)), e3: _|_(true:invalid list index true (type bool)), e4: _|_([1,2,3]:index 3 out of bounds), e5: _|_(-1:invalid list index -1 (index must be non-negative)), e6: _|_([]:index 1 out of bounds), def: <1>{a: 1, b :: 3}, e7: _|_(<2>.def["b"]:field "b" is a definition)}
+<0>{a: 2, b: "bar", c: _|_("3":invalid list index "3" (type string)), l: [], d: _|_([]:index 0 out of bounds), e1: _|_("":invalid list index "" (type string)), e2: _|_(2:invalid operation: 2[2] (type int does not support indexing)), e3: _|_(true:invalid list index true (type bool)), e4: _|_([1,2,3]:index 3 out of bounds), e5: _|_(-1:invalid list index -1 (index must be non-negative)), e6: _|_([]:index 1 out of bounds), def: <1>{a: 1, #b: 3}, e7: <2>.def["b"]}
+-- out/compile --
+--- in.cue
+{
+  a: [
+    2,
+  ][0]
+  b: {
+    foo: "bar"
+  }["foo"]
+  c: (*〈0;l〉|{
+    "3": 3
+  })["3"]
+  d: (*[]|[
+    1,
+  ])[0]
+  l: []
+  e1: [
+    2,
+  ][""]
+  e2: 2[2]
+  e3: [][true]
+  e4: [
+    1,
+    2,
+    3,
+  ][3]
+  e5: [
+    1,
+    2,
+    3,
+  ][-1]
+  e6: (*[]|{})[1]
+  def: {
+    a: 1
+    #b: 3
+  }
+  e7: 〈0;def〉["b"]
+}
diff --git a/cue/testdata/resolve/017_disjunctions_of_lists.txtar b/cue/testdata/resolve/017_disjunctions_of_lists.txtar
index 896fef7..bafa8b8 100644
--- a/cue/testdata/resolve/017_disjunctions_of_lists.txtar
+++ b/cue/testdata/resolve/017_disjunctions_of_lists.txtar
@@ -13,3 +13,22 @@
 l2: ["c", "d"]
 -- out/legacy-debug --
 <0>{l: ([int,int] | [string,string]), l1: ["a","b"], l2: ["c","d"]}
+-- out/compile --
+--- in.cue
+{
+  l: ([
+    int,
+    int,
+  ]|[
+    string,
+    string,
+  ])
+  l1: [
+    "a",
+    "b",
+  ]
+  l2: (〈0;l〉 & [
+    "c",
+    "d",
+  ])
+}
diff --git a/cue/testdata/resolve/018_slice.txtar b/cue/testdata/resolve/018_slice.txtar
index 560299f..c14c0f6 100644
--- a/cue/testdata/resolve/018_slice.txtar
+++ b/cue/testdata/resolve/018_slice.txtar
@@ -24,3 +24,30 @@
 e7: _|_ // invalid slice index "9" (type string)
 -- out/legacy-debug --
 <0>{a: [], b: [], e1: _|_(1:slice bounds out of range), e2: _|_([0]:negative slice index), e3: _|_([0]:invalid slice index: 1 > 0), e4: _|_(2:slice bounds out of range), e5: _|_(4:cannot slice 4 (type int)), e6: _|_("":invalid slice index "" (type string)), e7: _|_("9":invalid slice index "9" (type string))}
+-- out/compile --
+--- in.cue
+{
+  a: [
+    2,
+  ][0:0]
+  b: [
+    0,
+  ][1:1]
+  e1: [][1:1]
+  e2: [
+    0,
+  ][-1:0]
+  e3: [
+    0,
+  ][1:0]
+  e4: [
+    0,
+  ][1:2]
+  e5: 4[1:2]
+  e6: [
+    2,
+  ]["":]
+  e7: [
+    2,
+  ][:"9"]
+}
diff --git a/cue/testdata/resolve/019_list_types.txtar b/cue/testdata/resolve/019_list_types.txtar
index 1370d51..d9cf033 100644
--- a/cue/testdata/resolve/019_list_types.txtar
+++ b/cue/testdata/resolve/019_list_types.txtar
@@ -48,3 +48,71 @@
 ]
 -- out/legacy-debug --
 <0>{l0: [1,2,3], l2: [<1>{a: 1},<2>{a: 2, b: 3}], s1: [int], s2: [2], i1: int, i2: 3, t0: [<3>{a: 8}], t1: [, ...int], e0: _|_(([<4>{},<4>{}] & [<5>{}]):conflicting list lengths: conflicting values 2 and 1), e1: [, ..._|_((int & float):conflicting values int and float (mismatched types int and float))]}
+-- out/compile --
+--- in.cue
+{
+  l0: (3 * [
+    int,
+  ])
+  l0: [
+    1,
+    2,
+    3,
+  ]
+  l2: [
+    ...{
+      a: int
+    },
+  ]
+  l2: [
+    {
+      a: 1
+    },
+    {
+      a: 2
+      b: 3
+    },
+  ]
+  s1: (6 * [
+    int,
+  ])[2:3]
+  s2: [
+    0,
+    2,
+    3,
+  ][1:2]
+  i1: (6 * [
+    int,
+  ])[2]
+  i2: [
+    0,
+    2,
+    3,
+  ][2]
+  t0: [
+    ...{
+      a: 8
+    },
+  ]
+  t0: [
+    {},
+  ]
+  t1: [
+    ...,
+  ]
+  t1: [
+    ...int,
+  ]
+  e0: (2 * [
+    {},
+  ])
+  e0: [
+    {},
+  ]
+  e1: [
+    ...int,
+  ]
+  e1: [
+    ...float,
+  ]
+}
diff --git a/cue/testdata/resolve/020_list_arithmetic.txtar b/cue/testdata/resolve/020_list_arithmetic.txtar
index e8d521f..f08f8bc 100644
--- a/cue/testdata/resolve/020_list_arithmetic.txtar
+++ b/cue/testdata/resolve/020_list_arithmetic.txtar
@@ -98,3 +98,241 @@
 s35: [1, 2, 1, 2]
 -- out/legacy-debug --
 <0>{l0: [1,2,3,1,2,3,1,2,3], l1: [], l2: [], l3: (<=2 * []), l4: (<=2 * [int]), l5: (<=2 * (int * [int])), l6: [], l7: [1,1,1], l8: [1,2,1,2,1,2], s0: [], s1: [1], s2: [2], s3: [1,2], s4: [1,2], s5: [1,2], s6: [1,1,2], s7: [1,2,1], s8: [1,2,1,2], s9: [], s10: [1], s11: [2], s12: [1,2], s13: [1,2], s14: [1,2], s15: [1,1,2], s16: [1,2,1], s17: [1,2,1,2], s18: [], s19: [1], s20: [2], s21: [1,2], s22: [1,2], s23: [1,2], s24: [1,1,2], s25: [1,2,1], s26: [1,2,1,2], s27: [], s28: [1], s29: [2], s30: [1,2], s31: [1,2], s32: [1,2], s33: [1,1,2], s34: [1,2,1], s35: [1,2,1,2]}
+-- out/compile --
+--- in.cue
+{
+  l0: (3 * [
+    1,
+    2,
+    3,
+  ])
+  l1: (0 * [
+    1,
+    2,
+    3,
+  ])
+  l2: (10 * [])
+  l3: (<=2 * [])
+  l4: (<=2 * [
+    int,
+  ])
+  l5: (<=2 * (int * [
+    int,
+  ]))
+  l6: (3 * [
+    ...int,
+  ])
+  l7: (3 * [
+    1,
+    ...int,
+  ])
+  l8: (3 * [
+    1,
+    2,
+    ...int,
+  ])
+  s0: ([] + [])
+  s1: ([
+    1,
+  ] + [])
+  s2: ([] + [
+    2,
+  ])
+  s3: ([
+    1,
+  ] + [
+    2,
+  ])
+  s4: ([
+    1,
+    2,
+  ] + [])
+  s5: ([] + [
+    1,
+    2,
+  ])
+  s6: ([
+    1,
+  ] + [
+    1,
+    2,
+  ])
+  s7: ([
+    1,
+    2,
+  ] + [
+    1,
+  ])
+  s8: ([
+    1,
+    2,
+  ] + [
+    1,
+    2,
+  ])
+  s9: ([] + [
+    ...,
+  ])
+  s10: ([
+    1,
+  ] + [
+    ...,
+  ])
+  s11: ([] + [
+    2,
+    ...,
+  ])
+  s12: ([
+    1,
+  ] + [
+    2,
+    ...,
+  ])
+  s13: ([
+    1,
+    2,
+  ] + [
+    ...,
+  ])
+  s14: ([] + [
+    1,
+    2,
+    ...,
+  ])
+  s15: ([
+    1,
+  ] + [
+    1,
+    2,
+    ...,
+  ])
+  s16: ([
+    1,
+    2,
+  ] + [
+    1,
+    ...,
+  ])
+  s17: ([
+    1,
+    2,
+  ] + [
+    1,
+    2,
+    ...,
+  ])
+  s18: ([
+    ...,
+  ] + [])
+  s19: ([
+    1,
+    ...,
+  ] + [])
+  s20: ([
+    ...,
+  ] + [
+    2,
+  ])
+  s21: ([
+    1,
+    ...,
+  ] + [
+    2,
+  ])
+  s22: ([
+    1,
+    2,
+    ...,
+  ] + [])
+  s23: ([
+    ...,
+  ] + [
+    1,
+    2,
+  ])
+  s24: ([
+    1,
+    ...,
+  ] + [
+    1,
+    2,
+  ])
+  s25: ([
+    1,
+    2,
+    ...,
+  ] + [
+    1,
+  ])
+  s26: ([
+    1,
+    2,
+    ...,
+  ] + [
+    1,
+    2,
+  ])
+  s27: ([
+    ...,
+  ] + [
+    ...,
+  ])
+  s28: ([
+    1,
+    ...,
+  ] + [
+    ...,
+  ])
+  s29: ([
+    ...,
+  ] + [
+    2,
+    ...,
+  ])
+  s30: ([
+    1,
+    ...,
+  ] + [
+    2,
+    ...,
+  ])
+  s31: ([
+    1,
+    2,
+    ...,
+  ] + [
+    ...,
+  ])
+  s32: ([
+    ...,
+  ] + [
+    1,
+    2,
+    ...,
+  ])
+  s33: ([
+    1,
+    ...,
+  ] + [
+    1,
+    2,
+    ...,
+  ])
+  s34: ([
+    1,
+    2,
+    ...,
+  ] + [
+    1,
+    ...,
+  ])
+  s35: ([
+    1,
+    2,
+    ...,
+  ] + [
+    1,
+    2,
+    ...,
+  ])
+}
diff --git a/cue/testdata/resolve/021_list_equality.txtar b/cue/testdata/resolve/021_list_equality.txtar
index ecc8e59..7213b1d 100644
--- a/cue/testdata/resolve/021_list_equality.txtar
+++ b/cue/testdata/resolve/021_list_equality.txtar
@@ -213,3 +213,272 @@
 {"eq0":true,"eq1":true,"eq2":true,"eq3":true,"eq4":true,"eq5":true,"eq6":true,"eq7":true,"eq8":true,"eq9":true,"eq10":true,"eq11":true,"ne0":true,"ne1":true,"ne2":true,"ne3":true,"ne4":false,"ne5":false,"ne6":false,"ne7":false,"ne8":false,"ne9":false,"ne10":false,"ne11":false,"feq0":false,"feq1":false,"feq2":false,"feq3":false,"feq4":false,"feq5":false,"feq6":false,"feq7":false,"feq8":false,"feq9":false,"feq10":false,"feq11":false,"fne0":false,"fne1":false,"fne2":false,"fne3":false,"fne4":false,"fne5":false,"fne6":false,"fne7":false,"fne8":false,"fne9":false,"fne10":false,"fne11":false}
 -- out/legacy-debug --
 <0>{eq0: true, eq1: true, eq2: true, eq3: true, eq4: true, eq5: true, eq6: true, eq7: true, eq8: true, eq9: true, eq10: true, eq11: true, ne0: true, ne1: true, ne2: true, ne3: true, ne4: false, ne5: false, ne6: false, ne7: false, ne8: false, ne9: false, ne10: false, ne11: false, feq0: false, feq1: false, feq2: false, feq3: false, feq4: false, feq5: false, feq6: false, feq7: false, feq8: false, feq9: false, feq10: false, feq11: false, fne0: false, fne1: false, fne2: false, fne3: false, fne4: false, fne5: false, fne6: false, fne7: false, fne8: false, fne9: false, fne10: false, fne11: false}
+-- out/compile --
+--- in.cue
+{
+  eq0: ([] == [])
+  eq1: ([
+    ...,
+  ] == [])
+  eq2: ([] == [
+    ...,
+  ])
+  eq3: ([
+    ...,
+  ] == [
+    ...,
+  ])
+  eq4: ([
+    1,
+  ] == [
+    1,
+  ])
+  eq5: ([
+    1,
+    ...,
+  ] == [
+    1,
+  ])
+  eq6: ([
+    1,
+  ] == [
+    1,
+    ...,
+  ])
+  eq7: ([
+    1,
+    ...,
+  ] == [
+    1,
+    ...,
+  ])
+  eq8: ([
+    1,
+    2,
+  ] == [
+    1,
+    2,
+  ])
+  eq9: ([
+    1,
+    2,
+    ...,
+  ] == [
+    1,
+    2,
+  ])
+  eq10: ([
+    1,
+    2,
+  ] == [
+    1,
+    2,
+    ...,
+  ])
+  eq11: ([
+    1,
+    2,
+    ...,
+  ] == [
+    1,
+    2,
+    ...,
+  ])
+  ne0: ([] != [])
+  ne1: ([
+    ...,
+  ] != [])
+  ne2: ([] != [
+    ...,
+  ])
+  ne3: ([
+    ...,
+  ] != [
+    ...,
+  ])
+  ne4: ([
+    1,
+  ] != [
+    1,
+  ])
+  ne5: ([
+    1,
+    ...,
+  ] != [
+    1,
+  ])
+  ne6: ([
+    1,
+  ] != [
+    1,
+    ...,
+  ])
+  ne7: ([
+    1,
+    ...,
+  ] != [
+    1,
+    ...,
+  ])
+  ne8: ([
+    1,
+    2,
+  ] != [
+    1,
+    2,
+  ])
+  ne9: ([
+    1,
+    2,
+    ...,
+  ] != [
+    1,
+    2,
+  ])
+  ne10: ([
+    1,
+    2,
+  ] != [
+    1,
+    2,
+    ...,
+  ])
+  ne11: ([
+    1,
+    2,
+    ...,
+  ] != [
+    1,
+    2,
+    ...,
+  ])
+  feq0: ([] == [
+    1,
+  ])
+  feq1: ([
+    ...,
+  ] == [
+    1,
+  ])
+  feq2: ([] == [
+    1,
+    ...,
+  ])
+  feq3: ([
+    ...,
+  ] == [
+    1,
+    ...,
+  ])
+  feq4: ([
+    1,
+  ] == [])
+  feq5: ([
+    1,
+    ...,
+  ] == [])
+  feq6: ([
+    1,
+  ] == [
+    ...,
+  ])
+  feq7: ([
+    1,
+    ...,
+  ] == [
+    ...,
+  ])
+  feq8: ([
+    1,
+    2,
+  ] == [
+    1,
+  ])
+  feq9: ([
+    1,
+    ...,
+  ] == [
+    1,
+    2,
+  ])
+  feq10: ([
+    1,
+    2,
+  ] == [
+    1,
+    ...,
+  ])
+  feq11: ([
+    1,
+    ...,
+  ] == [
+    1,
+    2,
+    ...,
+  ])
+  fne0: ([] != [
+    1,
+  ])
+  fne1: ([
+    ...,
+  ] != [
+    1,
+  ])
+  fne2: ([] != [
+    1,
+    ...,
+  ])
+  fne3: ([
+    1,
+    ...,
+  ] != [
+    1,
+    ...,
+  ])
+  fne4: ([
+    1,
+  ] != [])
+  fne5: ([
+    1,
+    ...,
+  ] != [])
+  fne6: ([
+    1,
+  ] != [
+    ...,
+  ])
+  fne7: ([
+    1,
+    ...,
+  ] != [
+    ...,
+  ])
+  fne8: ([
+    1,
+    2,
+  ] != [
+    1,
+  ])
+  fne9: ([
+    1,
+    ...,
+  ] != [
+    1,
+    2,
+  ])
+  fne10: ([
+    1,
+    2,
+  ] != [
+    1,
+    ...,
+  ])
+  fne11: ([
+    1,
+    ...,
+  ] != [
+    1,
+    2,
+    ...,
+  ])
+}
diff --git a/cue/testdata/resolve/022_list_unification.txtar b/cue/testdata/resolve/022_list_unification.txtar
index abb794b..7f05375 100644
--- a/cue/testdata/resolve/022_list_unification.txtar
+++ b/cue/testdata/resolve/022_list_unification.txtar
@@ -15,3 +15,20 @@
 }
 -- out/legacy-debug --
 <0>{a: <1>{l: ["foo",<2>.v], v: <2>.l[1]}, b: <3>{l: ["foo","bar"], v: "bar"}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    l: [
+      "foo",
+      〈0;v〉,
+    ]
+    v: 〈0;l〉[1]
+  }
+  b: (〈0;a〉 & {
+    l: [
+      _,
+      "bar",
+    ]
+  })
+}
diff --git a/cue/testdata/resolve/023_correct_error_messages.txtar b/cue/testdata/resolve/023_correct_error_messages.txtar
index 28f8089..20deba0 100644
--- a/cue/testdata/resolve/023_correct_error_messages.txtar
+++ b/cue/testdata/resolve/023_correct_error_messages.txtar
@@ -8,3 +8,8 @@
 a: _|_ // conflicting values "a" and 1 (mismatched types string and int)
 -- out/legacy-debug --
 <0>{a: _|_(("a" & 1):conflicting values "a" and 1 (mismatched types string and int))}
+-- out/compile --
+--- in.cue
+{
+  a: ("a" & 1)
+}
diff --git a/cue/testdata/resolve/024_structs.txtar b/cue/testdata/resolve/024_structs.txtar
index 48d1e33..01b08a5 100644
--- a/cue/testdata/resolve/024_structs.txtar
+++ b/cue/testdata/resolve/024_structs.txtar
@@ -23,3 +23,20 @@
 }
 -- out/legacy-debug --
 <0>{a: <1>{c: 5, d: 15}, t: <2>{c: number, d: (<3>.c * 3)}, b: <4>{c: 7, d: 21}, ti: <5>{c: int, d: (<6>.c * 3)}}
+-- out/compile --
+--- in.cue
+{
+  a: (〈0;t〉 & {
+    c: 5
+  })
+  b: (〈0;ti〉 & {
+    c: 7
+  })
+  t: {
+    c: number
+    d: (〈0;c〉 * 3)
+  }
+  ti: (〈0;t〉 & {
+    c: int
+  })
+}
diff --git a/cue/testdata/resolve/025_definitions.txtar b/cue/testdata/resolve/025_definitions.txtar
index ec38bd5..4094bd2 100644
--- a/cue/testdata/resolve/025_definitions.txtar
+++ b/cue/testdata/resolve/025_definitions.txtar
@@ -3,7 +3,7 @@
 #name: definitions
 #evalPartial
 -- in.cue --
-Foo :: {
+#Foo: {
 	field: int
 	recursive: {
 		field: string
@@ -11,13 +11,13 @@
 }
 
 // Allowed
-Foo1 :: {field: int}
-Foo1 :: {field2: string}
+#Foo1: {field: int}
+#Foo1: {field2: string}
 
-foo: Foo
+foo: #Foo
 foo: {feild: 2}
 
-foo1: Foo
+foo1: #Foo
 foo1: {
 	field: 2
 	recursive: {
@@ -25,20 +25,20 @@
 	}
 }
 
-Bar :: {
+#Bar: {
 	field: int
 	{[A=_]: int}
 }
-bar: Bar
+bar: #Bar
 bar: {feild: 2}
 
-Mixed :: string
-Mixed:   string
+#Mixed: string
+Mixed:  string
 
-mixedRec: {Mixed :: string}
+mixedRec: {#Mixed: string}
 mixedRec: {Mixed: string}
 -- out/def --
-Foo :: {
+#Foo: {
 	field: int
 	recursive: {
 		field: string
@@ -46,25 +46,74 @@
 }
 
 // Allowed
-Foo1 :: {
+#Foo1: {
 	field:  int
 	field2: string
 }
 foo:  _|_ // field "feild" not allowed in closed struct
-foo1: Foo & {
+foo1: #Foo & {
 	field: 2
 	recursive: {
 		feild: 2
 	}
 }
-Bar :: {
+#Bar: {
 	{[A=string]: int}
 	field: int
 }
-bar: Bar & {
+bar: #Bar & {
 	feild: 2
 }
-Mixed:    _|_ // field "Mixed" declared as definition and regular field
-mixedRec: _|_ // field "Mixed" declared as definition and regular field
+#Mixed: string
+Mixed:  string
+mixedRec: {
+	#Mixed: string
+	Mixed:  string
+}
 -- out/legacy-debug --
-<0>{Foo :: <1>C{field: int, recursive: <2>C{field: string}}, Foo1 :: <3>C{field: int, field2: string}, foo: _|_(2:field "feild" not allowed in closed struct), foo1: <4>C{field: 2, recursive: _|_(2:field "feild" not allowed in closed struct)}, Bar :: <5>{[]: <6>(A: string)->int, field: int}, bar: <7>{[]: <8>(A: string)->int, field: int, feild: 2}, Mixed: _|_(field "Mixed" declared as definition and regular field), mixedRec: _|_(field "Mixed" declared as definition and regular field)}
+<0>{#Foo: <1>C{field: int, recursive: <2>C{field: string}}, #Foo1: <3>C{field: int, field2: string}, foo: _|_(2:field "feild" not allowed in closed struct), foo1: <4>C{field: 2, recursive: _|_(2:field "feild" not allowed in closed struct)}, #Bar: <5>{[]: <6>(A: string)->int, field: int}, bar: <7>{[]: <8>(A: string)->int, field: int, feild: 2}, #Mixed: string, Mixed: string, mixedRec: <9>{#Mixed: string, Mixed: string}}
+-- out/compile --
+--- in.cue
+{
+  #Foo: {
+    field: int
+    recursive: {
+      field: string
+    }
+  }
+  #Foo1: {
+    field: int
+  }
+  #Foo1: {
+    field2: string
+  }
+  foo: 〈0;#Foo〉
+  foo: {
+    feild: 2
+  }
+  foo1: 〈0;#Foo〉
+  foo1: {
+    field: 2
+    recursive: {
+      feild: 2
+    }
+  }
+  #Bar: {
+    field: int
+    {
+      [_]: int
+    }
+  }
+  bar: 〈0;#Bar〉
+  bar: {
+    feild: 2
+  }
+  #Mixed: string
+  Mixed: string
+  mixedRec: {
+    #Mixed: string
+  }
+  mixedRec: {
+    Mixed: string
+  }
+}
diff --git a/cue/testdata/resolve/026_combined_definitions.txtar b/cue/testdata/resolve/026_combined_definitions.txtar
index 79d39df..20c0b4b 100644
--- a/cue/testdata/resolve/026_combined_definitions.txtar
+++ b/cue/testdata/resolve/026_combined_definitions.txtar
@@ -4,67 +4,115 @@
 #evalPartial
 -- in.cue --
 // Allow combining of structs within a definition
-D1 :: {
+#D1: {
 	env: a: "A"
 	env: b: "B"
-	def :: {a: "A"}
-	def :: {b: "B"}
+	#def: {a: "A"}
+	#def: {b: "B"}
 }
 
-d1: D1 & {env: c: "C"}
+d1: #D1 & {env: c: "C"}
 
-D2 :: {
+#D2: {
 	a: int
 }
-D2 :: {
+#D2: {
 	b: int
 }
 
-D3 :: {
+#D3: {
 	env: a: "A"
 }
-D3 :: {
+#D3: {
 	env: b: "B"
 }
 
-D4 :: {
-	env: DC
+#D4: {
+	env: #DC
 	env: b: int
 }
 
-DC :: {a: int}
+#DC: {a: int}
 -- out/def --
 // Allow combining of structs within a definition
-D1 :: {
+#D1: {
 	env: {
 		a: "A"
 		b: "B"
 	}
-	def :: {
+	#def: {
 		a: "A"
 		b: "B"
 	}
 }
-d1: D1 & {
+d1: #D1 & {
 	env: {
 		c: "C"
 	}
 }
-D2 :: {
+#D2: {
 	a: int
 	b: int
 }
-D3 :: {
+#D3: {
 	env: {
 		a: "A"
 		b: "B"
 	}
 }
-D4 :: {
+#D4: {
 	env: _|_ // field "b" not allowed in closed struct
 }
-DC :: {
+#DC: {
 	a: int
 }
 -- out/legacy-debug --
-<0>{D1 :: <1>C{env: <2>C{a: "A", b: "B"}, def :: <3>C{a: "A", b: "B"}}, d1: <4>C{env: _|_("C":field "c" not allowed in closed struct), def :: <5>C{a: "A", b: "B"}}, D2 :: <6>C{a: int, b: int}, D3 :: <7>C{env: <8>C{a: "A", b: "B"}}, D4 :: <9>C{env: _|_(int:field "b" not allowed in closed struct)}, DC :: <10>C{a: int}}
+<0>{#D1: <1>C{env: <2>C{a: "A", b: "B"}, #def: <3>C{a: "A", b: "B"}}, d1: <4>C{env: _|_("C":field "c" not allowed in closed struct), #def: <5>C{a: "A", b: "B"}}, #D2: <6>C{a: int, b: int}, #D3: <7>C{env: <8>C{a: "A", b: "B"}}, #D4: <9>C{env: _|_(int:field "b" not allowed in closed struct)}, #DC: <10>C{a: int}}
+-- out/compile --
+--- in.cue
+{
+  #D1: {
+    env: {
+      a: "A"
+    }
+    env: {
+      b: "B"
+    }
+    #def: {
+      a: "A"
+    }
+    #def: {
+      b: "B"
+    }
+  }
+  d1: (〈0;#D1〉 & {
+    env: {
+      c: "C"
+    }
+  })
+  #D2: {
+    a: int
+  }
+  #D2: {
+    b: int
+  }
+  #D3: {
+    env: {
+      a: "A"
+    }
+  }
+  #D3: {
+    env: {
+      b: "B"
+    }
+  }
+  #D4: {
+    env: 〈1;#DC〉
+    env: {
+      b: int
+    }
+  }
+  #DC: {
+    a: int
+  }
+}
diff --git a/cue/testdata/resolve/027_new-style_definitions.txtar b/cue/testdata/resolve/027_new-style_definitions.txtar
index 511ff3c..830748c 100644
--- a/cue/testdata/resolve/027_new-style_definitions.txtar
+++ b/cue/testdata/resolve/027_new-style_definitions.txtar
@@ -46,3 +46,21 @@
 {"#Foo":{"a":1,"b":1},"bulk":{"a":"foo"}}
 -- out/legacy-debug --
 <0>{"#Foo": <1>C{a: 1, b: 1}, #Foo: <2>C{a: 1, b: int}, bulk: <3>{[]: <4>(_: string)->string, a: "foo", #def: 4, _hid: 3}}
+-- out/compile --
+--- in.cue
+{
+  #Foo: {
+    a: 1
+    b: int
+  }
+  "#Foo": (〈0;#Foo〉 & {
+    b: 1
+  })
+  bulk: ({
+    [string]: string
+  } & {
+    #def: 4
+    _hid: 3
+    a: "foo"
+  })
+}
diff --git a/cue/testdata/resolve/028_recursive_closing_starting_at_non-definition.txtar b/cue/testdata/resolve/028_recursive_closing_starting_at_non-definition.txtar
index 0695609..381b092 100644
--- a/cue/testdata/resolve/028_recursive_closing_starting_at_non-definition.txtar
+++ b/cue/testdata/resolve/028_recursive_closing_starting_at_non-definition.txtar
@@ -4,16 +4,16 @@
 #evalPartial
 -- in.cue --
 z: a: {
-	B :: {
+	#B: {
 		c: d: 1
 		c: f: 1
 	}
 }
-A: z & {a: {B :: {c: e: 2}}}
+A: z & {a: {#B: {c: e: 2}}}
 -- out/def --
 z: {
 	a: {
-		B :: {
+		#B: {
 			c: {
 				d: 1
 				f: 1
@@ -23,7 +23,7 @@
 }
 A: z & {
 	a: {
-		B :: {
+		#B: {
 			c: {
 				e: 2
 			}
@@ -45,4 +45,29 @@
 -- out/json --
 {"z":{"a":{}},"A":{"a":{}}}
 -- out/legacy-debug --
-<0>{z: <1>{a: <2>{B :: <3>C{c: <4>C{d: 1, f: 1}}}}, A: <5>{a: <6>{B :: <7>C{c: _|_(2:field "e" not allowed in closed struct)}}}}
+<0>{z: <1>{a: <2>{#B: <3>C{c: <4>C{d: 1, f: 1}}}}, A: <5>{a: <6>{#B: <7>C{c: _|_(2:field "e" not allowed in closed struct)}}}}
+-- out/compile --
+--- in.cue
+{
+  z: {
+    a: {
+      #B: {
+        c: {
+          d: 1
+        }
+        c: {
+          f: 1
+        }
+      }
+    }
+  }
+  A: (〈0;z〉 & {
+    a: {
+      #B: {
+        c: {
+          e: 2
+        }
+      }
+    }
+  })
+}
diff --git a/cue/testdata/resolve/029_non-closed_definition_carries_over_closedness_to_enclosed_template.txtar b/cue/testdata/resolve/029_non-closed_definition_carries_over_closedness_to_enclosed_template.txtar
index b9dca9c..61622b5 100644
--- a/cue/testdata/resolve/029_non-closed_definition_carries_over_closedness_to_enclosed_template.txtar
+++ b/cue/testdata/resolve/029_non-closed_definition_carries_over_closedness_to_enclosed_template.txtar
@@ -3,53 +3,53 @@
 #name: non-closed definition carries over closedness to enclosed template
 #evalPartial
 -- in.cue --
-S :: {
+#S: {
 	[string]: {a: int}
 }
-a: S & {
+a: #S & {
 	v: {b: int}
 }
-Q :: {
+#Q: {
 	[string]: {a: int} | {b: int}
 }
-b: Q & {
+b: #Q & {
 	w: {c: int}
 }
-R :: {
+#R: {
 	[string]: [{a: int}, {b: int}]
 }
-c: R & {
+c: #R & {
 	w: [{d: int}, ...]
 }
 -- out/def --
-S :: {
+#S: {
 	[string]: {
 		a: int
 	}
 }
-a: S & {
+a: #S & {
 	v: {
 		b: int
 	}
 }
-b: Q & {
+b: #Q & {
 	w: {
 		c: int
 	}
 }
-Q :: {
+#Q: {
 	[string]: {
 		a: int
 	} | {
 		b: int
 	}
 }
-c: R & {
+c: #R & {
 	w: [{
 		d: int
 	}, ...]
 }
-R :: {
+#R: {
 	[string]: [{
 		a: int
 	}, {
@@ -57,4 +57,48 @@
 	}]
 }
 -- out/legacy-debug --
-<0>{S :: <1>{[]: <2>(_: string)-><3>C{a: int}, }, a: <4>{[]: <5>(_: string)-><6>C{a: int}, v: _|_(int:field "b" not allowed in closed struct)}, b: <7>{[]: <8>(_: string)->(<9>C{a: int} | <10>C{b: int}), w: _|_(int:empty disjunction: field "c" not allowed in closed struct)}, Q :: <11>{[]: <12>(_: string)->(<13>C{a: int} | <14>C{b: int}), }, c: <15>{[]: <16>(_: string)->[<17>C{a: int},<18>C{b: int}], w: [_|_(int:field "d" not allowed in closed struct),<19>C{b: int}]}, R :: <20>{[]: <21>(_: string)->[<22>C{a: int},<23>C{b: int}], }}
+<0>{#S: <1>{[]: <2>(_: string)-><3>C{a: int}, }, a: <4>{[]: <5>(_: string)-><6>C{a: int}, v: _|_(int:field "b" not allowed in closed struct)}, b: <7>{[]: <8>(_: string)->(<9>C{a: int} | <10>C{b: int}), w: _|_(int:empty disjunction: field "c" not allowed in closed struct)}, #Q: <11>{[]: <12>(_: string)->(<13>C{a: int} | <14>C{b: int}), }, c: <15>{[]: <16>(_: string)->[<17>C{a: int},<18>C{b: int}], w: [_|_(int:field "d" not allowed in closed struct),<19>C{b: int}]}, #R: <20>{[]: <21>(_: string)->[<22>C{a: int},<23>C{b: int}], }}
+-- out/compile --
+--- in.cue
+{
+  #S: {
+    [string]: {
+      a: int
+    }
+  }
+  a: (〈0;#S〉 & {
+    v: {
+      b: int
+    }
+  })
+  #Q: {
+    [string]: ({
+      a: int
+    }|{
+      b: int
+    })
+  }
+  b: (〈0;#Q〉 & {
+    w: {
+      c: int
+    }
+  })
+  #R: {
+    [string]: [
+      {
+        a: int
+      },
+      {
+        b: int
+      },
+    ]
+  }
+  c: (〈0;#R〉 & {
+    w: [
+      {
+        d: int
+      },
+      ...,
+    ]
+  })
+}
diff --git a/cue/testdata/resolve/030_definitions_with_disjunctions.txtar b/cue/testdata/resolve/030_definitions_with_disjunctions.txtar
index 7baaff1..17b2d7e 100644
--- a/cue/testdata/resolve/030_definitions_with_disjunctions.txtar
+++ b/cue/testdata/resolve/030_definitions_with_disjunctions.txtar
@@ -3,35 +3,59 @@
 #name: definitions with disjunctions
 #evalPartial
 -- in.cue --
-Foo :: {
+#Foo: {
 	field: int
 
 	{a: 1} |
 	{b: 2}
 }
 
-foo: Foo
+foo: #Foo
 foo: {a: 1}
 
-bar: Foo
+bar: #Foo
 bar: {c: 2}
 
-baz: Foo
+baz: #Foo
 baz: {b: 2}
 -- out/def --
-Foo :: {
+#Foo: {
 	field: int
 	a:     1
 } | {
 	field: int
 	b:     2
 }
-foo: Foo & {
+foo: #Foo & {
 	a: 1
 }
 bar: _|_ // 
-baz: Foo & {
+baz: #Foo & {
 	b: 2
 }
 -- out/legacy-debug --
-<0>{Foo :: (<1>C{field: int, a: 1} | <2>C{field: int, b: 2}), foo: <3>C{field: int, a: 1}, bar: _|_(2:empty disjunction: field "c" not allowed in closed struct), baz: <4>C{field: int, b: 2}}
+<0>{#Foo: (<1>C{field: int, a: 1} | <2>C{field: int, b: 2}), foo: <3>C{field: int, a: 1}, bar: _|_(2:empty disjunction: field "c" not allowed in closed struct), baz: <4>C{field: int, b: 2}}
+-- out/compile --
+--- in.cue
+{
+  #Foo: {
+    field: int
+    ({
+      a: 1
+    }|{
+      b: 2
+    })
+  }
+  foo: 〈0;#Foo〉
+  foo: {
+    a: 1
+  }
+  bar: 〈0;#Foo〉
+  bar: {
+    c: 2
+  }
+  baz: 〈0;#Foo〉
+  baz: {
+    b: 2
+  }
+}
diff --git a/cue/testdata/resolve/031_definitions_with_disjunctions_recurisive.txtar b/cue/testdata/resolve/031_definitions_with_disjunctions_recurisive.txtar
index cc701ff..86013b4 100644
--- a/cue/testdata/resolve/031_definitions_with_disjunctions_recurisive.txtar
+++ b/cue/testdata/resolve/031_definitions_with_disjunctions_recurisive.txtar
@@ -3,7 +3,7 @@
 #name: definitions with disjunctions recurisive
 #evalPartial
 -- in.cue --
-Foo :: {
+#Foo: {
 	x: {
 		field: int
 
@@ -13,7 +13,7 @@
 	x: c: 3
 }
 -- out/def --
-Foo :: {
+#Foo: {
 	x: {
 		field: int
 		a:     1
@@ -31,4 +31,21 @@
 -- out/json --
 {}
 -- out/legacy-debug --
-<0>{Foo :: <1>C{x: (<2>C{field: int, a: 1, c: 3} | <3>C{field: int, b: 2, c: 3})}}
+<0>{#Foo: <1>C{x: (<2>C{field: int, a: 1, c: 3} | <3>C{field: int, b: 2, c: 3})}}
+-- out/compile --
+--- in.cue
+{
+  #Foo: {
+    x: {
+      field: int
+      ({
+        a: 1
+      }|{
+        b: 2
+      })
+    }
+    x: {
+      c: 3
+    }
+  }
+}
diff --git a/cue/testdata/resolve/032_definitions_with_embedding.txtar b/cue/testdata/resolve/032_definitions_with_embedding.txtar
index 71bd870..bd354a0 100644
--- a/cue/testdata/resolve/032_definitions_with_embedding.txtar
+++ b/cue/testdata/resolve/032_definitions_with_embedding.txtar
@@ -3,44 +3,44 @@
 #name: definitions with embedding
 #evalPartial
 -- in.cue --
-E :: {
+#E: {
 	a: {b: int}
 }
 
-S :: {
-	E
+#S: {
+	#E
 	a: {c: int}
 	b: 3
 }
 
 // adding a field to a nested struct that is closed.
-e1 :: S & {a: d: 4}
+#e1: #S & {a: d: 4}
 
 // literal struct not closed until after unification.
-v1 :: S & {a: c: 4}
+#v1: #S & {a: c: 4}
 -- out/def --
-E :: {
+#E: {
 	a: {
 		b: int
 	}
 }
-S :: {
+#S: {
 	a: {
 		c: int
 	}
 	b: 3
-	E
+	#E
 }
 
 // adding a field to a nested struct that is closed.
-e1 :: S & {
+#e1: #S & {
 	a: {
 		d: 4
 	}
 }
 
 // literal struct not closed until after unification.
-v1 :: S & {
+#v1: #S & {
 	a: {
 		c: 4
 	}
@@ -52,4 +52,30 @@
 -- out/json --
 {}
 -- out/legacy-debug --
-<0>{E :: <1>C{a: <2>C{b: int}}, S :: <3>C{a: <4>C{b: int, c: int}, b: 3}, e1 :: <5>C{a: _|_(4:field "d" not allowed in closed struct), b: 3}, v1 :: <6>C{a: <7>C{b: int, c: 4}, b: 3}}
+<0>{#E: <1>C{a: <2>C{b: int}}, #S: <3>C{a: <4>C{b: int, c: int}, b: 3}, #e1: <5>C{a: _|_(4:field "d" not allowed in closed struct), b: 3}, #v1: <6>C{a: <7>C{b: int, c: 4}, b: 3}}
+-- out/compile --
+--- in.cue
+{
+  #E: {
+    a: {
+      b: int
+    }
+  }
+  #S: {
+    〈1;#E〉
+    a: {
+      c: int
+    }
+    b: 3
+  }
+  #e1: (〈0;#S〉 & {
+    a: {
+      d: 4
+    }
+  })
+  #v1: (〈0;#S〉 & {
+    a: {
+      c: 4
+    }
+  })
+}
diff --git a/cue/testdata/resolve/033_top-level_definition_with_struct_and_disjunction.txtar b/cue/testdata/resolve/033_top-level_definition_with_struct_and_disjunction.txtar
index eeb8159..d219134 100644
--- a/cue/testdata/resolve/033_top-level_definition_with_struct_and_disjunction.txtar
+++ b/cue/testdata/resolve/033_top-level_definition_with_struct_and_disjunction.txtar
@@ -3,13 +3,13 @@
 #name: top-level definition with struct and disjunction
 #evalPartial
 -- in.cue --
-def :: {
+#def: {
 	Type: string
 	Text: string
 	Size: int
 }
 
-def :: {
+#def: {
 	Type: "B"
 	Size: 0
 } | {
@@ -17,7 +17,7 @@
 	Size: 1
 }
 -- out/def --
-def :: {
+#def: {
 	Size: 0
 	Type: "B"
 	Text: string
@@ -33,4 +33,20 @@
 -- out/json --
 {}
 -- out/legacy-debug --
-<0>{def :: (<1>C{Size: (0 & int), Type: ("B" & string), Text: string} | <2>C{Size: (1 & int), Type: ("A" & string), Text: string})}
+<0>{#def: (<1>C{Size: (0 & int), Type: ("B" & string), Text: string} | <2>C{Size: (1 & int), Type: ("A" & string), Text: string})}
+-- out/compile --
+--- in.cue
+{
+  #def: {
+    Type: string
+    Text: string
+    Size: int
+  }
+  #def: ({
+    Type: "B"
+    Size: 0
+  }|{
+    Type: "A"
+    Size: 1
+  })
+}
diff --git a/cue/testdata/resolve/035_excluded_embedding_from_closing.txtar b/cue/testdata/resolve/035_excluded_embedding_from_closing.txtar
index 7db5d93..1fed0d7 100644
--- a/cue/testdata/resolve/035_excluded_embedding_from_closing.txtar
+++ b/cue/testdata/resolve/035_excluded_embedding_from_closing.txtar
@@ -3,20 +3,20 @@
 #name: excluded embedding from closing
 #evalPartial
 -- in.cue --
-S :: {
+#S: {
 	a: {c: int}
 	{
 		c: {d: int}
 	}
-	B = {open: int}
+	let B = {open: int}
 	b: B
 }
-V: S & {
+V: #S & {
 	c: e:     int
 	b: extra: int
 }
 -- out/def --
-S :: {
+#S: {
 	a: {
 		c: int
 	}
@@ -29,7 +29,7 @@
 		...
 	}
 }
-V: S & {
+V: #S & {
 	c: {
 		e: int
 	}
@@ -38,4 +38,27 @@
 	}
 }
 -- out/legacy-debug --
-<0>{S :: <1>C{a: <2>C{c: int}, c: <3>{d: int}, b: <4>{open: int}}, V: <5>C{a: <6>C{c: int}, c: <7>{d: int, e: int}, b: <8>{open: int, extra: int}}}
+<0>{#S: <1>C{a: <2>C{c: int}, c: <3>{d: int}, b: <4>{open: int}}, V: <5>C{a: <6>C{c: int}, c: <7>{d: int, e: int}, b: <8>{open: int, extra: int}}}
+-- out/compile --
+--- in.cue
+{
+  #S: {
+    a: {
+      c: int
+    }
+    {
+      c: {
+        d: int
+      }
+    }
+    b: 〈0;let B〉
+  }
+  V: (〈0;#S〉 & {
+    c: {
+      e: int
+    }
+    b: {
+      extra: int
+    }
+  })
+}
diff --git a/cue/testdata/resolve/036_closing_with_failed_optional.txtar b/cue/testdata/resolve/036_closing_with_failed_optional.txtar
index 2473f54..ec4d97a 100644
--- a/cue/testdata/resolve/036_closing_with_failed_optional.txtar
+++ b/cue/testdata/resolve/036_closing_with_failed_optional.txtar
@@ -3,29 +3,29 @@
 #name: closing with failed optional
 #evalPartial
 -- in.cue --
-k1 :: {a: int, b?: int} & A // closed({a: int})
+#k1: {a: int, b?: int} & #A // closed({a: int})
 
-k2 :: A & {a: int, b?: int} // closed({a: int})
+#k2: #A & {a: int, b?: int} // closed({a: int})
 
 o1: {a?: 3} & {a?: 4} // {a?: _|_}
 
 // Optional fields with error values can be elimintated when closing
-o2 :: {a?: 3} & {a?: 4} // close({})
+#o2: {a?: 3} & {a?: 4} // close({})
 
-d1 :: {a?: 2, b: 4} | {a?: 3, c: 5}
+#d1: {a?: 2, b: 4} | {a?: 3, c: 5}
 
-v1: d1 & {a?: 3, b: 4} // close({b: 4})
+v1: #d1 & {a?: 3, b: 4} // close({b: 4})
 
-A :: {a: int}
+#A: {a: int}
 -- out/def --
-k1 :: {
+#k1: {
 	a:  int
 	b?: int
-} & A
-A :: {
+} & #A
+#A: {
 	a: int
 }
-k2 :: A & {
+#k2: #A & {
 	a:  int
 	b?: int
 }
@@ -34,17 +34,17 @@
 }
 
 // Optional fields with error values can be elimintated when closing
-o2 :: {
+#o2: {
 	a?: _|_ // conflicting values 3 and 4
 }
-d1 :: {
+#d1: {
 	a?: 2
 	b:  4
 } | {
 	a?: 3
 	c:  5
 }
-v1: d1 & {
+v1: #d1 & {
 	a?: 3
 	b:  4
 }
@@ -60,4 +60,40 @@
 -- out/json --
 {"o1":{},"v1":{"b":4}}
 -- out/legacy-debug --
-<0>{k1 :: <1>C{a: int}, A :: <2>C{a: int}, k2 :: <3>C{a: int}, o1: <4>{a?: _|_((3 & 4):conflicting values 3 and 4)}, o2 :: <5>C{a?: _|_((3 & 4):conflicting values 3 and 4)}, d1 :: (<6>C{a?: 2, b: 4} | <7>C{a?: 3, c: 5}), v1: <8>C{a?: _|_((2 & 3):conflicting values 2 and 3), b: 4}}
+<0>{#k1: <1>C{a: int}, #A: <2>C{a: int}, #k2: <3>C{a: int}, o1: <4>{a?: _|_((3 & 4):conflicting values 3 and 4)}, #o2: <5>C{a?: _|_((3 & 4):conflicting values 3 and 4)}, #d1: (<6>C{a?: 2, b: 4} | <7>C{a?: 3, c: 5}), v1: <8>C{a?: _|_((2 & 3):conflicting values 2 and 3), b: 4}}
+-- out/compile --
+--- in.cue
+{
+  #k1: ({
+    a: int
+    b?: int
+  } & 〈0;#A〉)
+  #k2: (〈0;#A〉 & {
+    a: int
+    b?: int
+  })
+  o1: ({
+    a?: 3
+  } & {
+    a?: 4
+  })
+  #o2: ({
+    a?: 3
+  } & {
+    a?: 4
+  })
+  #d1: ({
+    a?: 2
+    b: 4
+  }|{
+    a?: 3
+    c: 5
+  })
+  v1: (〈0;#d1〉 & {
+    a?: 3
+    b: 4
+  })
+  #A: {
+    a: int
+  }
+}
diff --git a/cue/testdata/resolve/037_closing_with_comprehensions.txtar b/cue/testdata/resolve/037_closing_with_comprehensions.txtar
index 6167314..9c30294 100644
--- a/cue/testdata/resolve/037_closing_with_comprehensions.txtar
+++ b/cue/testdata/resolve/037_closing_with_comprehensions.txtar
@@ -3,57 +3,102 @@
 #name: closing with comprehensions
 #evalPartial
 -- in.cue --
-A :: {f1: int, f2: int}
+#A: {f1: int, f2: int}
 
 for k, v in {f3: int} {
-	a: A & {"\(k)": v}
+	a: #A & {"\(k)": v}
 }
 
-B :: {
+#B: {
 	for k, v in {f1: int} {
 		"\(k)": v
 	}
 }
 
-C :: {
+#C: {
 	f1: _
 	for k, v in {f1: int} {
 		"\(k)": v
 	}
 }
 
-D :: {
+#D: {
 	for k, v in {f1: int} {
 		"\(k)": v
 	}
 	...
 }
 
-E :: A & {
+#E: #A & {
 	for k, v in {f3: int} {
 		"\(k)": v
 	}
 }
 -- out/def --
-E :: _|_ // field "f3" not allowed in closed struct
-A :: {
+#A: {
 	f1: int
 	f2: int
 }
 a: _|_ // field "f3" not allowed in closed struct
-B :: {
+#B: {
 	f1: v
 }
-C :: {
+#C: {
 	f1: {
 		_
 		v
 		...
 	}
 }
-D :: {
+#D: {
 	f1: v
 	...
 }
+#E: _|_ // field "f3" not allowed in closed struct
 -- out/legacy-debug --
-<0>{E :: _|_(<1>.v:field "f3" not allowed in closed struct), A :: <2>C{f1: int, f2: int}, a: _|_(<3>.v:field "f3" not allowed in closed struct), B :: <4>C{f1: int}, C :: <5>C{f1: int}, D :: <6>{f1: int, ...}}
+<0>{#A: <1>C{f1: int, f2: int}, a: _|_(<2>.v:field "f3" not allowed in closed struct), #B: <3>C{f1: int}, #C: <4>C{f1: int}, #D: <5>{f1: int, ...}, #E: _|_(<6>.v:field "f3" not allowed in closed struct)}
+-- out/compile --
+--- in.cue
+{
+  #A: {
+    f1: int
+    f2: int
+  }
+  for k, v in {
+    f3: int
+  } {
+    a: (〈2;#A〉 & {
+      "\(〈2;k〉)": 〈2;v〉
+    })
+  }
+  #B: {
+    for k, v in {
+      f1: int
+    } {
+      "\(〈1;k〉)": 〈1;v〉
+    }
+  }
+  #C: {
+    f1: _
+    for k, v in {
+      f1: int
+    } {
+      "\(〈1;k〉)": 〈1;v〉
+    }
+  }
+  #D: {
+    for k, v in {
+      f1: int
+    } {
+      "\(〈1;k〉)": 〈1;v〉
+    }
+    ...
+  }
+  #E: (〈0;#A〉 & {
+    for k, v in {
+      f3: int
+    } {
+      "\(〈1;k〉)": 〈1;v〉
+    }
+  })
+}
diff --git a/cue/testdata/resolve/038_incomplete_comprehensions.txtar b/cue/testdata/resolve/038_incomplete_comprehensions.txtar
index 7cc7ab3..f57accf 100644
--- a/cue/testdata/resolve/038_incomplete_comprehensions.txtar
+++ b/cue/testdata/resolve/038_incomplete_comprehensions.txtar
@@ -28,3 +28,22 @@
 }
 -- out/legacy-debug --
 <0>{A: <1>{src: _, baz: "baz" <2>for _, v in <3>.src yield <4>{""+<2>.v+"": <2>.v}}, B: <5>{src: ["foo","bar"], baz: "baz", foo: "foo", bar: "bar"}}
+-- out/compile --
+--- in.cue
+{
+  A: {
+    for _, v in 〈0;src〉 {
+      "\(〈1;v〉)": 〈1;v〉
+    }
+    src: _
+    if true {
+      baz: "baz"
+    }
+  }
+  B: (〈0;A〉 & {
+    src: [
+      "foo",
+      "bar",
+    ]
+  })
+}
diff --git a/cue/testdata/resolve/039_reference_to_root.txtar b/cue/testdata/resolve/039_reference_to_root.txtar
index 18a63e8..85324e5 100644
--- a/cue/testdata/resolve/039_reference_to_root.txtar
+++ b/cue/testdata/resolve/039_reference_to_root.txtar
@@ -49,3 +49,31 @@
 }
 -- out/legacy-debug --
 <0>{x: <1>{b: int, c: (<2>.b + 5)}, y: <3>{b: 100, c: 105}, a: <4>{b: int}, c: <5>{b: 100, d: (<6>.a.b + 3)}, v: <7>{b: int, c: (<6>.v.b + 5)}, w: <8>{b: 100, c: (<6>.v.b + 5)}, wp: <9>{b: 100, c: (<6>.v.b + 5)}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    b: int
+  }
+  c: (〈0;a〉 & {
+    b: 100
+    d: (〈1;a〉.b + 3)
+  })
+  x: {
+    b: int
+    c: (〈0;b〉 + 5)
+  }
+  y: (〈0;x〉 & {
+    b: 100
+  })
+  v: {
+    b: int
+    c: (〈1;v〉.b + 5)
+  }
+  w: (〈0;v〉 & {
+    b: 100
+  })
+  wp: (〈0;v〉 & {
+    b: 100
+  })
+}
diff --git a/cue/testdata/resolve/040_references_from_template_to_concrete.txtar b/cue/testdata/resolve/040_references_from_template_to_concrete.txtar
index f3115a7..8126739 100644
--- a/cue/testdata/resolve/040_references_from_template_to_concrete.txtar
+++ b/cue/testdata/resolve/040_references_from_template_to_concrete.txtar
@@ -62,3 +62,26 @@
 {"res":[{"x":{"a":"XDDDD","c":"X","b":{"str":"DDDD"}}}],"t":{"x":{"a":"XDDDD","c":"X","b":{"str":"DDDD"}}}}
 -- out/legacy-debug --
 <0>{res: [<1>{[]: <2>(X: string)-><3>{a: (<3>.c + <3>.b.str), c: "X", b: <4>{str: string}}, x: <5>{a: "XDDDD", c: "X", b: <6>{str: "DDDD"}}}], t: <7>{[]: <2>(X: string)-><3>{a: (<3>.c + <3>.b.str), c: "X", b: <4>{str: string}}, x: <8>{a: "XDDDD", c: "X", b: <9>{str: "DDDD"}}}}
+-- out/compile --
+--- in.cue
+{
+  res: [
+    〈0;t〉,
+  ]
+  t: {
+    [string]: {
+      a: (〈0;c〉 + 〈0;b〉.str)
+      b: {
+        str: string
+      }
+      c: "X"
+    }
+  }
+  t: {
+    x: {
+      b: {
+        str: "DDDD"
+      }
+    }
+  }
+}
diff --git a/cue/testdata/resolve/041_interpolation.txtar b/cue/testdata/resolve/041_interpolation.txtar
index 812be45..6e6ee9e 100644
--- a/cue/testdata/resolve/041_interpolation.txtar
+++ b/cue/testdata/resolve/041_interpolation.txtar
@@ -20,3 +20,14 @@
 e: _|_ // expression in interpolation must evaluate to a number kind or string (found list)
 -- out/legacy-debug --
 <0>{a: "4", b: "one 4 two 4one", c: "one", d: ""+<1>.r+"", r: _, u: ""+_+"", e: _|_([]:expression in interpolation must evaluate to a number kind or string (found list))}
+-- out/compile --
+--- in.cue
+{
+  a: "\(4)"
+  b: "one \(〈0;a〉) two \((〈0;a〉 + 〈0;c〉))"
+  c: "one"
+  d: "\(〈0;r〉)"
+  u: "\(_)"
+  r: _
+  e: "\([])"
+}
diff --git a/cue/testdata/resolve/042_multiline_interpolation.txtar b/cue/testdata/resolve/042_multiline_interpolation.txtar
index acab0cd..a36cd3b 100644
--- a/cue/testdata/resolve/042_multiline_interpolation.txtar
+++ b/cue/testdata/resolve/042_multiline_interpolation.txtar
@@ -163,3 +163,31 @@
 {"a1":"before\n4\nafter","a2":"before\n4\n","a3":"\n4\nafter","a4":"\n4\n","m1":"before\n4\nafter","m2":"before\n4\n","m3":"\n4\nafter","m4":"\n4\n"}
 -- out/legacy-debug --
 <0>{a1: "before\n4\nafter", a2: "before\n4\n", a3: "\n4\nafter", a4: "\n4\n", m1: "before\n4\nafter", m2: "before\n4\n", m3: "\n4\nafter", m4: "\n4\n"}
+-- out/compile --
+--- in.cue
+{
+  a1: "before
+  \(4)
+  after"
+  a2: "before
+  \(4)
+  "
+  a3: "
+  \(4)
+  after"
+  a4: "
+  \(4)
+  "
+  m1: "before
+  \(4)
+  after"
+  m2: "before
+  \(4)
+  "
+  m3: "
+  \(4)
+  after"
+  m4: "
+  \(4)
+  "
+}
diff --git a/cue/testdata/resolve/043_diamond-shaped_constraints.txtar b/cue/testdata/resolve/043_diamond-shaped_constraints.txtar
index ac725a8..6b82234 100644
--- a/cue/testdata/resolve/043_diamond-shaped_constraints.txtar
+++ b/cue/testdata/resolve/043_diamond-shaped_constraints.txtar
@@ -78,3 +78,23 @@
 {"T":{"A":{"a":1,"c":3},"B":{"a":1,"b":2,"c":3,"d":4}},"S":{"A":{"a":1},"B":{"a":1,"b":2}}}
 -- out/legacy-debug --
 <0>{T: <1>{A: <2>{a: 1, c: 3}, B: <3>{a: 1, b: 2, c: 3, d: 4}}, S: <4>{A: <5>{a: 1}, B: <6>{a: 1, b: 2}}}
+-- out/compile --
+--- in.cue
+{
+  S: {
+    A: {
+      a: 1
+    }
+    B: (〈0;A〉 & {
+      b: 2
+    })
+  }
+  T: (〈0;S〉 & {
+    A: {
+      c: 3
+    }
+    B: {
+      d: 4
+    }
+  })
+}
diff --git a/cue/testdata/resolve/044_field_templates.txtar b/cue/testdata/resolve/044_field_templates.txtar
index f4e65d6..a2b3aac 100644
--- a/cue/testdata/resolve/044_field_templates.txtar
+++ b/cue/testdata/resolve/044_field_templates.txtar
@@ -94,3 +94,38 @@
 {"a":{"k":1},"b":{"v":{"x":0,"y":1},"w":{"x":0,"y":1}},"c":{"foo":{"y":1,"name":"foo"},"bar":{"y":1,"name":"bar"}}}
 -- out/legacy-debug --
 <0>{a: <1>{[]: <2>(name: string)->int, k: 1}, b: <3>{[]: <4>(X: string)->(<5>{x: 0, y: (*1 | int)} & <6>{}), v: <7>{x: 0, y: (*1 | int)}, w: <8>{x: 0, y: (*1 | int)}}, c: <9>{[]: <10>(Name: string)-><11>{y: 1, name: <10>.Name}, foo: <12>{y: 1, name: "foo"}, bar: <13>{y: 1, name: "bar"}}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    {
+      [_]: int
+    }
+    k: 1
+  }
+  b: {
+    {
+      [_]: {
+        x: 0
+        y: (*1|int)
+      }
+    }
+    v: {}
+    w: {
+      x: 0
+    }
+  }
+  b: {
+    [_]: {}
+  }
+  c: {
+    {
+      [_]: {
+        name: 〈1;-〉
+        y: 1
+      }
+    }
+    foo: {}
+    bar: _
+  }
+}
diff --git a/cue/testdata/resolve/045_range_unification.txtar b/cue/testdata/resolve/045_range_unification.txtar
index 054002d..2a91782 100644
--- a/cue/testdata/resolve/045_range_unification.txtar
+++ b/cue/testdata/resolve/045_range_unification.txtar
@@ -93,3 +93,42 @@
 n5: 2.5
 -- out/legacy-debug --
 <0>{a1: 3, a2: 1, a3: 5, a4: _|_((<=5 & 6):invalid value 6 (out of bound <=5)), a5: _|_((>=1 & 0):invalid value 0 (out of bound >=1)), a6: 3, a7: 1, a8: 5, a9: _|_((<=5 & 6):invalid value 6 (out of bound <=5)), a10: _|_((>=1 & 0):invalid value 0 (out of bound >=1)), b1: (>=1 & <=5), b2: 1, b3: 5, b4: (>=2 & <=3), b5: (>=3 & <=5), b6: 5, b7: _|_(conflicting bounds >=6 and <=5), b8: (>=1 & <=5), b9: 1, b10: 5, b11: (>=2 & <=3), b12: (>=3 & <=5), b13: 5, b14: _|_(conflicting bounds >=6 and <=5), c1: (int & >=1 & <=5), c2: (<=5 & int & >=1), c3: _|_((string & >=1):conflicting values string and >=1 (mismatched types string and number)), c4: _|_(((>=1 & <=5) & string):conflicting values (>=1 & <=5) and string (mismatched types number and string)), s1: "e", s2: "ee", n1: (>=1 & <=2), n2: _|_(conflicting bounds int & >=1.1 and <=1.3), n3: 2, n4: 0.09999, n5: 2.5}
+-- out/compile --
+--- in.cue
+{
+  a1: ((>=1 & <=5) & 3)
+  a2: ((>=1 & <=5) & 1)
+  a3: ((>=1 & <=5) & 5)
+  a4: ((>=1 & <=5) & 6)
+  a5: ((>=1 & <=5) & 0)
+  a6: ((3 & >=1) & <=5)
+  a7: ((1 & >=1) & <=5)
+  a8: ((5 & >=1) & <=5)
+  a9: ((6 & >=1) & <=5)
+  a10: ((0 & >=1) & <=5)
+  b1: (((>=1 & <=5) & >=1) & <=5)
+  b2: (((>=1 & <=5) & >=1) & <=1)
+  b3: (((>=1 & <=5) & >=5) & <=5)
+  b4: (((>=1 & <=5) & >=2) & <=3)
+  b5: (((>=1 & <=5) & >=3) & <=9)
+  b6: (((>=1 & <=5) & >=5) & <=9)
+  b7: (((>=1 & <=5) & >=6) & <=9)
+  b8: (((>=1 & <=5) & >=1) & <=5)
+  b9: (((>=1 & <=1) & >=1) & <=5)
+  b10: (((>=5 & <=5) & >=1) & <=5)
+  b11: (((>=2 & <=3) & >=1) & <=5)
+  b12: (((>=3 & <=9) & >=1) & <=5)
+  b13: (((>=5 & <=9) & >=1) & <=5)
+  b14: (((>=6 & <=9) & >=1) & <=5)
+  c1: ((int & >=1) & <=5)
+  c2: ((>=1 & <=5) & int)
+  c3: ((string & >=1) & <=5)
+  c4: ((>=1 & <=5) & string)
+  s1: ((>="d" & <="z") & "e")
+  s2: ((>="d" & <="z") & "ee")
+  n1: ((number & >=1) & <=2)
+  n2: ((int & >=1.1) & <=1.3)
+  n3: ((>=1.0 & <=3.0) & 2)
+  n4: ((>=0.0 & <=0.1) & 0.09999)
+  n5: ((>=1 & <=5) & 2.5)
+}
diff --git a/cue/testdata/resolve/046_predefined_ranges.txtar b/cue/testdata/resolve/046_predefined_ranges.txtar
index e50f77a..f918a50 100644
--- a/cue/testdata/resolve/046_predefined_ranges.txtar
+++ b/cue/testdata/resolve/046_predefined_ranges.txtar
@@ -17,3 +17,13 @@
 e1: _|_ // invalid value 100000 (out of bound int & <=32767)
 -- out/legacy-debug --
 <0>{k1: 44, k2: -8000000000, e1: _|_((int & <=32767 & 100000):invalid value 100000 (out of bound int & <=32767))}
+-- out/compile --
+--- in.cue
+{
+  k1: (>=-128 & <=127)
+  k1: 44
+  k2: (>=-9223372036854775808 & <=9223372036854775807)
+  k2: -8000000000
+  e1: (>=-32768 & <=32767)
+  e1: 100000
+}
diff --git a/cue/testdata/resolve/047_struct_comprehensions.txtar b/cue/testdata/resolve/047_struct_comprehensions.txtar
index eab9516..b0cd52c 100644
--- a/cue/testdata/resolve/047_struct_comprehensions.txtar
+++ b/cue/testdata/resolve/047_struct_comprehensions.txtar
@@ -11,7 +11,7 @@
 	}
 }
 
-for k, v in {def :: 1, opt?: 2, _hid: 3, reg: 4} {
+for k, v in {#def: 1, opt?: 2, _hid: 3, reg: 4} {
 	"\(k)": v
 }
 -- out/def --
@@ -50,3 +50,30 @@
 {"obj":{"foo":{"a":"bar","sub":{"as":"bar"}}},"reg":4}
 -- out/legacy-debug --
 <0>{obj: <1>{[]: <2>(Name: string)-><3>{a: (*"dummy" | string) if true yield <4>{sub: <5>{as: <3>.a}}}, foo: <6>{a: "bar", sub: <7>{as: "bar"}}}, reg: 4}
+-- out/compile --
+--- in.cue
+{
+  obj: {
+    foo: {
+      a: "bar"
+    }
+  }
+  obj: {
+    [string]: {
+      a: (*"dummy"|string)
+      if true {
+        sub: {
+          as: 〈2;a〉
+        }
+      }
+    }
+  }
+  for k, v in {
+    #def: 1
+    opt?: 2
+    _hid: 3
+    reg: 4
+  } {
+    "\(〈1;k〉)": 〈1;v〉
+  }
+}
diff --git a/cue/testdata/resolve/049_self-reference_cycles_conflicts_with_strings.txtar b/cue/testdata/resolve/049_self-reference_cycles_conflicts_with_strings.txtar
index f430b79..5505a1b 100644
--- a/cue/testdata/resolve/049_self-reference_cycles_conflicts_with_strings.txtar
+++ b/cue/testdata/resolve/049_self-reference_cycles_conflicts_with_strings.txtar
@@ -15,3 +15,14 @@
 }
 -- out/legacy-debug --
 <0>{a: <1>{x: _|_(("hey!?" & "hey"):conflicting values "hey!?" and "hey"), y: "hey!"}}
+-- out/compile --
+--- in.cue
+{
+  a: {
+    x: (〈0;y〉 + "?")
+    y: (〈0;x〉 + "!")
+  }
+  a: {
+    x: "hey"
+  }
+}
diff --git a/cue/testdata/resolve/050_resolved_self-reference_cycles_with_disjunctions.txtar b/cue/testdata/resolve/050_resolved_self-reference_cycles_with_disjunctions.txtar
index da3224f..fcb31da 100644
--- a/cue/testdata/resolve/050_resolved_self-reference_cycles_with_disjunctions.txtar
+++ b/cue/testdata/resolve/050_resolved_self-reference_cycles_with_disjunctions.txtar
@@ -24,3 +24,22 @@
 }
 -- out/legacy-debug --
 <0>{a: (<1>{x: 1, y: 3, z: 2} | <2>{y: 1}), b: (<3>{x: 2} | <4>{x: 1, y: 3, z: 2}), c: (<5>{x: 1, y: 3, z: 2} | <6>{z: 3})}
+-- out/compile --
+--- in.cue
+{
+  a: ((〈0;b〉 & {
+    x: 1
+  })|{
+    y: 1
+  })
+  b: ({
+    x: 2
+  }|(〈0;c〉 & {
+    z: 2
+  }))
+  c: ((〈0;a〉 & {
+    y: 3
+  })|{
+    z: 3
+  })
+}
diff --git a/cue/testdata/resolve/051_resolved_self-reference_cycles_with_disjunction.txtar b/cue/testdata/resolve/051_resolved_self-reference_cycles_with_disjunction.txtar
index 143906b..411f100 100644
--- a/cue/testdata/resolve/051_resolved_self-reference_cycles_with_disjunction.txtar
+++ b/cue/testdata/resolve/051_resolved_self-reference_cycles_with_disjunction.txtar
@@ -120,3 +120,40 @@
 z3:  z1-3 & 8
 -- out/legacy-debug --
 <0>{xa1: 8, xa2: 8, xa4: 10, xa3: 6, xb1: 8, xb2: 8, xb4: 10, xb3: 6, xc1: ((<1>.xc2 & 8) | (<1>.xc4 & 9) | (<1>.xc5 & 9)), xc2: (<1>.xc3 + 2), xc4: (<1>.xc2 + 1), xc5: (<1>.xc2 + 2), xc3: (6 & (<1>.xc1 - 2)), xd1: 8, xd2: 8, xd4: 9, xd5: 10, xd3: 6, xe1: _|_((6 & 7):conflicting values 6 and 7), xe2: _|_((6 & 7):conflicting values 6 and 7), xe4: _|_((6 & 7):conflicting values 6 and 7), xe5: _|_((6 & 7):conflicting values 6 and 7), xe3: _|_((6 & 7):conflicting values 6 and 7), xf1: 8, xf2: 8, xf4: 10, xf3: 6, z1: ((<1>.z2 + 1) | (<1>.z3 + 5)), z2: (<1>.z3 + 2), z3: ((<1>.z1 - 3) & 8)}
+-- out/compile --
+--- in.cue
+{
+  xa1: ((〈0;xa2〉 & 8)|(〈0;xa4〉 & 9))
+  xa2: (〈0;xa3〉 + 2)
+  xa3: (6 & (〈0;xa1〉 - 2))
+  xa4: (〈0;xa2〉 + 2)
+  xb1: ((〈0;xb2〉 & 8)|(〈0;xb4〉 & 9))
+  xb2: (〈0;xb3〉 + 2)
+  xb3: ((6 & (〈0;xb1〉 - 2))|(〈0;xb4〉 & 9))
+  xb4: (〈0;xb2〉 + 2)
+  xc1: ((〈0;xc2〉 & 8)|(〈0;xc4〉 & 9)|(〈0;xc5〉 & 9))
+  xc2: (〈0;xc3〉 + 2)
+  xc3: (6 & (〈0;xc1〉 - 2))
+  xc4: (〈0;xc2〉 + 1)
+  xc5: (〈0;xc2〉 + 2)
+  xd1: ((〈0;xd2〉 & 8)|(〈0;xd4〉 & 9)|(〈0;xd5〉 & 9))
+  xd2: (〈0;xd3〉 + 2)
+  xd3: (6 & (〈0;xd1〉 - 2))
+  xd4: (〈0;xd2〉 + 1)
+  xd5: (〈0;xd2〉 + 2)
+  xd1: 8
+  xe1: ((〈0;xe2〉 & 8)|(〈0;xe4〉 & 9)|(〈0;xe5〉 & 9))
+  xe2: (〈0;xe3〉 + 2)
+  xe3: (6 & (〈0;xe1〉 - 2))
+  xe4: (〈0;xe2〉 + 1)
+  xe5: (〈0;xe2〉 + 2)
+  xe1: 9
+  xf1: ((〈0;xf2〉 & 8)|(〈0;xf4〉 & 9))
+  xf2: (〈0;xf3〉 + 2)
+  xf3: ((6 & (〈0;xf1〉 - 2))|(〈0;xf4〉 & 9))
+  xf4: (〈0;xf2〉 + 2)
+  z1: ((〈0;z2〉 + 1)|(〈0;z3〉 + 5))
+  z2: (〈0;z3〉 + 2)
+  z3: (〈0;z1〉 - 3)
+  z3: 8
+}
diff --git a/cue/testdata/resolve/052_resolved_self-reference_cycles_with_disjunction_with_defaults.txtar b/cue/testdata/resolve/052_resolved_self-reference_cycles_with_disjunction_with_defaults.txtar
index 4fcd4b2..92537aa 100644
--- a/cue/testdata/resolve/052_resolved_self-reference_cycles_with_disjunction_with_defaults.txtar
+++ b/cue/testdata/resolve/052_resolved_self-reference_cycles_with_disjunction_with_defaults.txtar
@@ -95,3 +95,35 @@
 z3:  8
 -- out/legacy-debug --
 <0>{xa1: 8, xa2: 8, xa4: 10, xa3: 6, xb1: 8, xb2: 8, xb4: 10, xb3: 6, xc1: (*8 | 9), xc2: 8, xc4: 9, xc5: 10, xc3: 6, xd1: (*8 | 9), xd2: 8, xd4: 9, xd5: 10, xd3: 6, xe1: _|_((6 & 7):conflicting values 6 and 7), xe2: _|_((6 & 7):conflicting values 6 and 7), xe4: _|_((6 & 7):conflicting values 6 and 7), xe5: _|_((6 & 7):conflicting values 6 and 7), xe3: _|_((6 & 7):conflicting values 6 and 7), z1: (*11 | 13), z2: 10, z3: 8}
+-- out/compile --
+--- in.cue
+{
+  xa1: ((〈0;xa2〉 & 8)|*(〈0;xa4〉 & 9))
+  xa2: (〈0;xa3〉 + 2)
+  xa3: (6 & (〈0;xa1〉 - 2))
+  xa4: (〈0;xa2〉 + 2)
+  xb1: (*(〈0;xb2〉 & 8)|(〈0;xb4〉 & 9))
+  xb2: (〈0;xb3〉 + 2)
+  xb3: (*(6 & (〈0;xb1〉 - 2))|(〈0;xb4〉 & 9))
+  xb4: (〈0;xb2〉 + 2)
+  xc1: (*(〈0;xc2〉 & 8)|(〈0;xc4〉 & 9)|(〈0;xc5〉 & 9))
+  xc2: (〈0;xc3〉 + 2)
+  xc3: (6 & (〈0;xc1〉 - 2))
+  xc4: (〈0;xc2〉 + 1)
+  xc5: (〈0;xc2〉 + 2)
+  xd1: (*(〈0;xd2〉 & 8)|(〈0;xd4〉 & 9)|(〈0;xd5〉 & 9))
+  xd2: (〈0;xd3〉 + 2)
+  xd3: (6 & (〈0;xd1〉 - 2))
+  xd4: (〈0;xd2〉 + 1)
+  xd5: (〈0;xd2〉 + 2)
+  xe1: (*(〈0;xe2〉 & 8)|(〈0;xe4〉 & 9)|(〈0;xe5〉 & 9))
+  xe2: (〈0;xe3〉 + 2)
+  xe3: (6 & (〈0;xe1〉 - 2))
+  xe4: (〈0;xe2〉 + 1)
+  xe5: (〈0;xe2〉 + 2)
+  xe1: 9
+  z1: (*(〈0;z2〉 + 1)|(〈0;z3〉 + 5))
+  z2: (〈0;z3〉 + 2)
+  z3: (〈0;z1〉 - 3)
+  z3: 8
+}
diff --git a/internal/core/adt/expr.go b/internal/core/adt/expr.go
index c36ea9c..0a607ec 100644
--- a/internal/core/adt/expr.go
+++ b/internal/core/adt/expr.go
@@ -251,7 +251,7 @@
 //    =~"Name$"
 //
 type BoundValue struct {
-	Src   ast.Node
+	Src   ast.Expr
 	Op    Op
 	Value Value
 	K     Kind
@@ -467,6 +467,7 @@
 // A Conjunction is a conjunction of values that cannot be represented as a
 // single value. It is the result of unification.
 type Conjunction struct {
+	Src    ast.Expr
 	Values []Value
 }
 
diff --git a/internal/core/compile/compile.go b/internal/core/compile/compile.go
new file mode 100644
index 0000000..018b99b
--- /dev/null
+++ b/internal/core/compile/compile.go
@@ -0,0 +1,843 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compile
+
+import (
+	"fmt"
+	"strings"
+
+	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/errors"
+	"cuelang.org/go/cue/literal"
+	"cuelang.org/go/cue/token"
+	"cuelang.org/go/internal"
+	"cuelang.org/go/internal/core/adt"
+	"cuelang.org/go/internal/core/runtime"
+	"golang.org/x/xerrors"
+)
+
+// Config configures a compilation.
+type Config struct {
+}
+
+// Files compiles the given files as a single instance. It disregards
+// the package names and it is the responsibility of the user to verify that
+// the packages names are consistent.
+//
+// Files may return a completed parse even if it has errors.
+func Files(cfg *Config, r *runtime.Runtime, files ...*ast.File) (*adt.Vertex, errors.Error) {
+	c := &compiler{index: r}
+
+	v := c.compileFiles(files)
+
+	if c.errs != nil {
+		return v, c.errs
+	}
+	return v, nil
+}
+
+type compiler struct {
+	index adt.StringIndexer
+
+	stack      []frame
+	inSelector int
+
+	fileScope map[adt.Feature]bool
+
+	num literal.NumInfo
+
+	errs errors.Error
+}
+
+func (c *compiler) reset() {
+	c.fileScope = nil
+	c.stack = c.stack[:0]
+	c.errs = nil
+}
+
+func (c *compiler) errf(n ast.Node, format string, args ...interface{}) *adt.Bottom {
+	err := &compilerError{
+		n:       n,
+		path:    c.path(),
+		Message: errors.NewMessage(format, args),
+	}
+	c.errs = errors.Append(c.errs, err)
+	return &adt.Bottom{}
+}
+
+func (c *compiler) path() []string {
+	a := []string{}
+	for _, f := range c.stack {
+		if f.label != nil {
+			a = append(a, f.label.labelString())
+		}
+	}
+	return a
+}
+
+type frame struct {
+	label labeler  // path name leading to this frame.
+	scope ast.Node // *ast.File or *ast.Struct
+	field *ast.Field
+	// scope   map[ast.Node]bool
+	upCount int32 // 1 for field, 0 for embedding.
+
+	aliases map[string]aliasEntry
+}
+
+type aliasEntry struct {
+	expr   adt.Expr
+	source ast.Node
+	used   bool
+}
+
+func (c *compiler) insertAlias(id *ast.Ident, a aliasEntry) *adt.Bottom {
+	k := len(c.stack) - 1
+	m := c.stack[k].aliases
+	if m == nil {
+		m = map[string]aliasEntry{}
+		c.stack[k].aliases = m
+	}
+
+	if id == nil || !ast.IsValidIdent(id.Name) {
+		return c.errf(a.source, "invalid identifier name")
+	}
+
+	if e, ok := m[id.Name]; ok {
+		return c.errf(a.source,
+			"alias %q already declared; previous declaration at %s",
+			id.Name, e.source.Pos())
+	}
+
+	m[id.Name] = a
+	return nil
+}
+
+// lookupAlias looks up an alias with the given name at the k'th stack position.
+func (c compiler) lookupAlias(k int, id *ast.Ident) aliasEntry {
+	m := c.stack[k].aliases
+	name := id.Name
+	entry, ok := m[name]
+
+	if !ok {
+		err := c.errf(id, "could not find LetClause associated with identifier %q", name)
+		return aliasEntry{expr: err}
+	}
+
+	entry.used = true
+	m[name] = entry
+	return entry
+}
+
+func (c *compiler) pushScope(n labeler, upCount int32, id ast.Node) *frame {
+	c.stack = append(c.stack, frame{
+		label:   n,
+		scope:   id,
+		upCount: upCount,
+	})
+	return &c.stack[len(c.stack)-1]
+}
+
+func (c *compiler) popScope() {
+	k := len(c.stack) - 1
+	f := c.stack[k]
+	for k, v := range f.aliases {
+		if !v.used {
+			c.errf(v.source, "unreferenced alias or let clause %s", k)
+		}
+	}
+	c.stack = c.stack[:k]
+}
+
+// entry points // USE CONFIG
+func (c *compiler) compileFiles(a []*ast.File) *adt.Vertex { // Or value?
+	c.fileScope = map[adt.Feature]bool{}
+
+	// Populate file scope to handle unresolved references. Note that we do
+	// not allow aliases to be resolved across file boundaries.
+	for _, f := range a {
+		for _, d := range f.Decls {
+			if f, ok := d.(*ast.Field); ok {
+				if id, ok := f.Label.(*ast.Ident); ok {
+					c.fileScope[c.label(id)] = true
+				}
+			}
+		}
+	}
+
+	// TODO: set doc.
+	res := &adt.Vertex{}
+
+	// env := &adt.Environment{Vertex: nil} // runtime: c.runtime
+
+	for _, file := range a {
+		c.pushScope(nil, 0, file) // File scope
+		v := &adt.StructLit{Src: file}
+		c.addDecls(v, file.Decls)
+		res.Conjuncts = append(res.Conjuncts, adt.MakeConjunct(nil, v))
+		c.popScope()
+	}
+
+	return res
+}
+
+// resolve assumes that all existing resolutions are legal. Validation should
+// be done in a separate step if required.
+//
+// TODO: collect validation pass to verify that all resolutions are
+// legal?
+func (c *compiler) resolve(n *ast.Ident) adt.Expr {
+	// X in import "path/X"
+	// X in import X "path"
+	if imp, ok := n.Node.(*ast.ImportSpec); ok {
+		return &adt.ImportReference{
+			Src:        n,
+			ImportPath: c.label(imp.Path),
+			Label:      c.label(n),
+		}
+	}
+
+	label := c.label(n)
+
+	// Unresolved field.
+	if n.Node == nil {
+		upCount := int32(0)
+		for _, c := range c.stack {
+			upCount += c.upCount
+		}
+		if c.fileScope[label] {
+			return &adt.FieldReference{
+				Src:     n,
+				UpCount: upCount,
+				Label:   label,
+			}
+		}
+
+		if p := predeclared(n); p != nil {
+			return p
+		}
+
+		return c.errf(n, "reference %q not found", n.Name)
+	}
+
+	//   X in [X=x]: y  Scope: Field  Node: Expr (x)
+	//   X in X=[x]: y  Scope: Field  Node: Field
+	if f, ok := n.Scope.(*ast.Field); ok {
+		upCount := int32(0)
+
+		k := len(c.stack) - 1
+		for ; k >= 0; k-- {
+			if c.stack[k].field == f {
+				break
+			}
+			upCount += c.stack[k].upCount
+		}
+
+		label := &adt.LabelReference{
+			Src:     n,
+			UpCount: upCount,
+		}
+
+		if f, ok := n.Node.(*ast.Field); ok {
+			_ = c.lookupAlias(k, f.Label.(*ast.Alias).Ident) // mark as used
+			return &adt.DynamicReference{
+				Src:     n,
+				UpCount: upCount,
+				Label:   label,
+			}
+		}
+		return label
+	}
+
+	upCount := int32(0)
+
+	k := len(c.stack) - 1
+	for ; k >= 0; k-- {
+		if c.stack[k].scope == n.Scope {
+			break
+		}
+		upCount += c.stack[k].upCount
+	}
+	if k < 0 {
+		// This is a programmatic error and should never happen if the users
+		// just builds with the cue command or if astutil.Resolve is used
+		// correctly.
+		c.errf(n, "reference %q set to unknown node in AST; "+
+			"this can result from incorrect API usage or a compiler bug",
+			n.Name)
+	}
+
+	switch n.Node.(type) {
+	// Local expressions
+	case *ast.LetClause, *ast.Alias:
+		entry := c.lookupAlias(k, n)
+
+		return &adt.LetReference{
+			Src:     n,
+			UpCount: upCount,
+			Label:   label,
+			X:       entry.expr,
+		}
+	}
+
+	if n.Scope == nil {
+		// Package.
+		// Should have been handled above.
+		panic("unreachable") // Or direct ancestor node?
+	}
+
+	// X=x: y
+	// X=(x): y
+	// X="\(x)": y
+	if f, ok := n.Node.(*ast.Field); ok {
+		a, ok := f.Label.(*ast.Alias)
+		if !ok {
+			return c.errf(n, "illegal reference %s", n.Name)
+		}
+		aliasInfo := c.lookupAlias(k, a.Ident) // marks alias as used.
+		lab, ok := a.Expr.(ast.Label)
+		if !ok {
+			return c.errf(a.Expr, "invalid label expression")
+		}
+		name, _, err := ast.LabelName(lab)
+		switch {
+		case xerrors.Is(err, ast.ErrIsExpression):
+			if aliasInfo.expr == nil {
+				panic("unreachable")
+			}
+			return &adt.DynamicReference{
+				Src:     n,
+				UpCount: upCount,
+				Label:   aliasInfo.expr,
+			}
+
+		case err != nil:
+			return c.errf(n, "invalid label: %v", err)
+
+		case name != "":
+			label = c.label(lab)
+
+		default:
+			return c.errf(n, "unsupported field alias %q", name)
+		}
+	}
+
+	return &adt.FieldReference{
+		Src:     n,
+		UpCount: upCount,
+		Label:   label,
+	}
+}
+
+func (c *compiler) addDecls(st *adt.StructLit, a []ast.Decl) {
+	for _, d := range a {
+		if x := c.decl(d); x != nil {
+			st.Decls = append(st.Decls, x)
+		}
+	}
+}
+
+func (c *compiler) decl(d ast.Decl) adt.Decl {
+	switch x := d.(type) {
+	case *ast.BadDecl:
+		return c.errf(d, "")
+
+	case *ast.Field:
+		lab := x.Label
+		if a, ok := lab.(*ast.Alias); ok {
+			if lab, ok = a.Expr.(ast.Label); !ok {
+				return c.errf(a, "alias expression is not a valid label")
+			}
+
+			e := aliasEntry{source: a}
+
+			switch lab.(type) {
+			case *ast.Ident, *ast.BasicLit:
+				// Even though we won't need the alias, we still register it
+				// for duplicate and failed reference detection.
+			default:
+				e.expr = c.expr(a.Expr)
+			}
+
+			if err := c.insertAlias(a.Ident, e); err != nil {
+				return err
+			}
+		}
+
+		value := c.labeledExpr(x, (*fieldLabel)(x), x.Value)
+
+		switch l := lab.(type) {
+		case *ast.Ident, *ast.BasicLit:
+			label := c.label(lab)
+
+			// TODO(legacy): remove: old-school definitions
+			if x.Token == token.ISA && !label.IsDef() {
+				name, isIdent, err := ast.LabelName(lab)
+				if err == nil && isIdent {
+					idx := c.index.StringToIndex(name)
+					label, _ = adt.MakeLabel(x.Pos(), idx, adt.DefinitionLabel)
+				}
+			}
+
+			if x.Optional == token.NoPos {
+				return &adt.Field{
+					Src:   x,
+					Label: label,
+					Value: value,
+				}
+			} else {
+				return &adt.OptionalField{
+					Src:   x,
+					Label: label,
+					Value: value,
+				}
+			}
+
+		case *ast.ListLit:
+			if len(l.Elts) != 1 {
+				// error
+				return c.errf(x, "list label must have one element")
+			}
+			elem := l.Elts[0]
+			// TODO: record alias for error handling? In principle it is okay
+			// to have duplicates, but we do want it to be used.
+			if a, ok := elem.(*ast.Alias); ok {
+				elem = a.Expr
+			}
+
+			return &adt.BulkOptionalField{
+				Src:    x,
+				Filter: c.expr(elem),
+				Value:  value,
+			}
+
+		case *ast.Interpolation: // *ast.ParenExpr,
+			if x.Token == token.ISA {
+				c.errf(x, "definitions not supported for interpolations")
+			}
+			return &adt.DynamicField{
+				Src:   x,
+				Key:   c.expr(l),
+				Value: value,
+			}
+		}
+
+	// An alias reference will have an expression that is looked up in the
+	// environment cash.
+	case *ast.LetClause:
+		// Cache the parsed expression. Creating a unique expression for each
+		// reference allows the computation to be shared given that we don't
+		// have fields for expressions. This, in turn, prevents exponential
+		// blowup. in x2: x1+x1, x3: x2+x2, ... patterns.
+
+		expr := c.labeledExpr(nil, (*letScope)(x), x.Expr)
+
+		a := aliasEntry{source: x, expr: expr}
+
+		if err := c.insertAlias(x.Ident, a); err != nil {
+			return err
+		}
+
+	case *ast.Alias:
+
+		expr := c.labeledExpr(nil, (*deprecatedAliasScope)(x), x.Expr)
+
+		// TODO(legacy): deprecated, remove this use of Alias
+		a := aliasEntry{source: x, expr: expr}
+
+		if err := c.insertAlias(x.Ident, a); err != nil {
+			return err
+		}
+
+	case *ast.CommentGroup:
+		// Nothing to do for a free-floating comment group.
+
+	case *ast.Attribute:
+		// Nothing to do for now for an attribute declaration.
+
+	case *ast.Ellipsis:
+		return &adt.Ellipsis{
+			Src:   x,
+			Value: c.expr(x.Type),
+		}
+
+	case *ast.Comprehension:
+		return c.comprehension(x)
+
+	case *ast.EmbedDecl: // Deprecated
+		return c.embed(x.Expr)
+
+	case ast.Expr:
+		return c.embed(x)
+	}
+	return nil
+}
+
+func (c *compiler) elem(n ast.Expr) adt.Elem {
+	switch x := n.(type) {
+	case *ast.Ellipsis:
+		return &adt.Ellipsis{
+			Src:   x,
+			Value: c.expr(x.Type),
+		}
+
+	case *ast.Comprehension:
+		return c.comprehension(x)
+
+	case ast.Expr:
+		return c.expr(x)
+	}
+	return nil
+}
+
+func (c *compiler) comprehension(x *ast.Comprehension) adt.Elem {
+	var cur adt.Yielder
+	var first adt.Elem
+	var prev, next *adt.Yielder
+	for _, v := range x.Clauses {
+		switch x := v.(type) {
+		case *ast.ForClause:
+			var key adt.Feature
+			if x.Key != nil {
+				key = c.label(x.Key)
+			}
+			y := &adt.ForClause{
+				Syntax: x,
+				Key:    key,
+				Value:  c.label(x.Value),
+				Src:    c.expr(x.Source),
+			}
+			cur = y
+			c.pushScope((*forScope)(x), 1, v)
+			defer c.popScope()
+			next = &y.Dst
+
+		case *ast.IfClause:
+			y := &adt.IfClause{
+				Src:       x,
+				Condition: c.expr(x.Condition),
+			}
+			cur = y
+			next = &y.Dst
+
+		case *ast.LetClause:
+			y := &adt.LetClause{
+				Src:   x,
+				Label: c.label(x.Ident),
+				Expr:  c.expr(x.Expr),
+			}
+			cur = y
+			c.pushScope((*letScope)(x), 1, v)
+			defer c.popScope()
+			next = &y.Dst
+		}
+
+		if prev != nil {
+			*prev = cur
+		} else {
+			var ok bool
+			if first, ok = cur.(adt.Elem); !ok {
+				return c.errf(x,
+					"first comprehension clause must be 'if' or 'for'")
+			}
+		}
+		prev = next
+	}
+
+	if y, ok := x.Value.(*ast.StructLit); !ok {
+		return c.errf(x.Value,
+			"comprehension value must be struct, found %T", y)
+	}
+
+	y := c.expr(x.Value)
+
+	st, ok := y.(*adt.StructLit)
+	if !ok {
+		// Error must have been generated.
+		return y
+	}
+
+	if prev != nil {
+		*prev = &adt.ValueClause{StructLit: st}
+	} else {
+		return c.errf(x, "comprehension value without clauses")
+	}
+
+	return first
+}
+
+func (c *compiler) embed(expr ast.Expr) adt.Expr {
+	switch n := expr.(type) {
+	case *ast.StructLit:
+		c.pushScope(nil, 1, n)
+		v := &adt.StructLit{Src: n}
+		c.addDecls(v, n.Elts)
+		c.popScope()
+		return v
+	}
+	return c.expr(expr)
+}
+
+func (c *compiler) labeledExpr(f *ast.Field, lab labeler, expr ast.Expr) adt.Expr {
+	k := len(c.stack) - 1
+	if c.stack[k].field != nil {
+		panic("expected nil field")
+	}
+	c.stack[k].label = lab
+	c.stack[k].field = f
+	value := c.expr(expr)
+	c.stack[k].label = nil
+	c.stack[k].field = nil
+	return value
+}
+
+func (c *compiler) expr(expr ast.Expr) adt.Expr {
+	switch n := expr.(type) {
+	case nil:
+		return nil
+	case *ast.Ident:
+		return c.resolve(n)
+
+	case *ast.StructLit:
+		c.pushScope(nil, 1, n)
+		v := &adt.StructLit{Src: n}
+		c.addDecls(v, n.Elts)
+		c.popScope()
+		return v
+
+	case *ast.ListLit:
+		v := &adt.ListLit{Src: n}
+		elts, ellipsis := internal.ListEllipsis(n)
+		for _, d := range elts {
+			elem := c.elem(d)
+
+			switch x := elem.(type) {
+			case nil:
+			case adt.Elem:
+				v.Elems = append(v.Elems, x)
+			default:
+				c.errf(d, "type %T not allowed in ListLit", d)
+			}
+		}
+		if ellipsis != nil {
+			d := &adt.Ellipsis{
+				Src:   ellipsis,
+				Value: c.expr(ellipsis.Type),
+			}
+			v.Elems = append(v.Elems, d)
+		}
+		return v
+
+	case *ast.SelectorExpr:
+		c.inSelector++
+		ret := &adt.SelectorExpr{
+			Src: n,
+			X:   c.expr(n.X),
+			Sel: c.label(n.Sel)}
+		c.inSelector--
+		return ret
+
+	case *ast.IndexExpr:
+		return &adt.IndexExpr{
+			Src:   n,
+			X:     c.expr(n.X),
+			Index: c.expr(n.Index),
+		}
+
+	case *ast.SliceExpr:
+		slice := &adt.SliceExpr{Src: n, X: c.expr(n.X)}
+		if n.Low != nil {
+			slice.Lo = c.expr(n.Low)
+		}
+		if n.High != nil {
+			slice.Hi = c.expr(n.High)
+		}
+		return slice
+
+	case *ast.BottomLit:
+		return &adt.Bottom{Src: n}
+
+	case *ast.BadExpr:
+		return c.errf(n, "invalid expression")
+
+	case *ast.BasicLit:
+		return c.parse(n)
+
+	case *ast.Interpolation:
+		if len(n.Elts) == 0 {
+			return c.errf(n, "invalid interpolation")
+		}
+		first, ok1 := n.Elts[0].(*ast.BasicLit)
+		last, ok2 := n.Elts[len(n.Elts)-1].(*ast.BasicLit)
+		if !ok1 || !ok2 {
+			return c.errf(n, "invalid interpolation")
+		}
+		if len(n.Elts) == 1 {
+			return c.expr(n.Elts[0])
+		}
+		lit := &adt.Interpolation{Src: n, K: adt.StringKind}
+		info, prefixLen, _, err := literal.ParseQuotes(first.Value, last.Value)
+		if err != nil {
+			return c.errf(n, "invalid interpolation: %v", err)
+		}
+		prefix := ""
+		for i := 0; i < len(n.Elts); i += 2 {
+			l, ok := n.Elts[i].(*ast.BasicLit)
+			if !ok {
+				return c.errf(n, "invalid interpolation")
+			}
+			s := l.Value
+			if !strings.HasPrefix(s, prefix) {
+				return c.errf(l, "invalid interpolation: unmatched ')'")
+			}
+			s = l.Value[prefixLen:]
+			x := parseString(c, l, info, s)
+			lit.Parts = append(lit.Parts, x)
+			if i+1 < len(n.Elts) {
+				lit.Parts = append(lit.Parts, c.expr(n.Elts[i+1]))
+			}
+			prefix = ")"
+			prefixLen = 1
+		}
+		return lit
+
+	case *ast.ParenExpr:
+		return c.expr(n.X)
+
+	case *ast.CallExpr:
+		call := &adt.CallExpr{Src: n, Fun: c.expr(n.Fun)}
+		for _, a := range n.Args {
+			call.Args = append(call.Args, c.expr(a))
+		}
+		return call
+
+	case *ast.UnaryExpr:
+		switch n.Op {
+		case token.NOT, token.ADD, token.SUB:
+			return &adt.UnaryExpr{
+				Src: n,
+				Op:  adt.OpFromToken(n.Op),
+				X:   c.expr(n.X),
+			}
+		case token.GEQ, token.GTR, token.LSS, token.LEQ,
+			token.NEQ, token.MAT, token.NMAT:
+			return &adt.BoundExpr{
+				Src:  n,
+				Op:   adt.OpFromToken(n.Op),
+				Expr: c.expr(n.X),
+			}
+
+		case token.MUL:
+			return c.errf(n, "preference mark not allowed at this position")
+		default:
+			return c.errf(n, "unsupported unary operator %q", n.Op)
+		}
+
+	case *ast.BinaryExpr:
+		switch n.Op {
+		case token.OR:
+			d := &adt.DisjunctionExpr{Src: n}
+			c.addDisjunctionElem(d, n.X, false)
+			c.addDisjunctionElem(d, n.Y, false)
+			return d
+
+		default:
+			// return updateBin(c,
+			return &adt.BinaryExpr{
+				Src: n,
+				Op:  adt.OpFromToken(n.Op), // op
+				X:   c.expr(n.X),           // left
+				Y:   c.expr(n.Y),           // right
+			} // )
+		}
+
+	default:
+		panic(fmt.Sprintf("unknown expression type %T", n))
+		// return c.errf(n, "unknown expression type %T", n)
+	}
+}
+
+func (c *compiler) addDisjunctionElem(d *adt.DisjunctionExpr, n ast.Expr, mark bool) {
+	switch x := n.(type) {
+	case *ast.BinaryExpr:
+		if x.Op == token.OR {
+			c.addDisjunctionElem(d, x.X, mark)
+			c.addDisjunctionElem(d, x.Y, mark)
+			return
+		}
+	case *ast.UnaryExpr:
+		if x.Op == token.MUL {
+			d.HasDefaults = true
+			c.addDisjunctionElem(d, x.X, true)
+			return
+		}
+	}
+	d.Values = append(d.Values, adt.Disjunct{Val: c.expr(n), Default: mark})
+}
+
+func (c *compiler) parse(l *ast.BasicLit) (n adt.Expr) {
+	s := l.Value
+	if s == "" {
+		return c.errf(l, "invalid literal %q", s)
+	}
+	switch l.Kind {
+	case token.STRING:
+		info, nStart, _, err := literal.ParseQuotes(s, s)
+		if err != nil {
+			return c.errf(l, err.Error())
+		}
+		s := s[nStart:]
+		return parseString(c, l, info, s)
+
+	case token.FLOAT, token.INT:
+		err := literal.ParseNum(s, &c.num)
+		if err != nil {
+			return c.errf(l, "parse error: %v", err)
+		}
+		kind := adt.FloatKind
+		if c.num.IsInt() {
+			kind = adt.IntKind
+		}
+		n := &adt.Num{Src: l, K: kind}
+		if err = c.num.Decimal(&n.X); err != nil {
+			return c.errf(l, "error converting number to decimal: %v", err)
+		}
+		return n
+
+	case token.TRUE:
+		return &adt.Bool{Src: l, B: true}
+
+	case token.FALSE:
+		return &adt.Bool{Src: l, B: false}
+
+	case token.NULL:
+		return &adt.Null{Src: l}
+
+	default:
+		return c.errf(l, "unknown literal type")
+	}
+}
+
+// parseString decodes a string without the starting and ending quotes.
+func parseString(c *compiler, node ast.Expr, q literal.QuoteInfo, s string) (n adt.Expr) {
+	str, err := q.Unquote(s)
+	if err != nil {
+		return c.errf(node, "invalid string: %v", err)
+	}
+	if q.IsDouble() {
+		return &adt.String{Src: node, Str: str, RE: nil}
+	}
+	return &adt.Bytes{Src: node, B: []byte(str), RE: nil}
+}
diff --git a/internal/core/compile/compile_test.go b/internal/core/compile/compile_test.go
new file mode 100644
index 0000000..4f78d33
--- /dev/null
+++ b/internal/core/compile/compile_test.go
@@ -0,0 +1,121 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compile_test
+
+import (
+	"flag"
+	"fmt"
+	"testing"
+
+	"cuelang.org/go/cue/errors"
+	"cuelang.org/go/cue/parser"
+	"cuelang.org/go/internal/core/compile"
+	"cuelang.org/go/internal/core/debug"
+	"cuelang.org/go/internal/core/runtime"
+	"cuelang.org/go/internal/cuetxtar"
+	"cuelang.org/go/pkg/strings"
+)
+
+var (
+	update = flag.Bool("update", false, "update the test files")
+	todo   = flag.Bool("todo", false, "run tests marked with #todo-compile")
+)
+
+func TestCompile(t *testing.T) {
+	test := cuetxtar.TxTarTest{
+		Root:   "../../../cue/testdata/",
+		Name:   "compile",
+		Update: *update,
+		Skip:   alwaysSkip,
+		ToDo:   needFix,
+	}
+
+	if *todo {
+		test.ToDo = nil
+	}
+
+	r := runtime.New()
+
+	test.Run(t, func(t *cuetxtar.Test) {
+		// TODO: use high-level API.
+
+		a := t.ValidInstances()
+
+		v, err := compile.Files(nil, r, a[0].Files...)
+
+		// Write the results.
+		t.WriteErrors(err)
+
+		if v == nil {
+			return
+		}
+
+		for i, f := range a[0].Files {
+			if i > 0 {
+				fmt.Fprintln(t)
+			}
+			fmt.Fprintln(t, "---", t.Rel(f.Filename))
+			debug.WriteNode(t, r, v.Conjuncts[i].Expr(), &debug.Config{
+				Cwd: t.Dir,
+			})
+		}
+		fmt.Fprintln(t)
+	})
+}
+
+var alwaysSkip = map[string]string{
+	"fulleval/031_comparison against bottom": "fix bin op binding in test",
+}
+
+var needFix = map[string]string{
+	"export/020":                           "builtin",
+	"fulleval/027_len_of_incomplete_types": "builtin",
+	"fulleval/032_or_builtin_should_not_fail_on_non-concrete_empty_list": "builtin",
+	"fulleval/053_issue312":       "builtin",
+	"resolve/034_closing_structs": "builtin",
+	"resolve/048_builtins":        "builtin",
+
+	"fulleval/026_dont_convert_incomplete_errors_to_non-incomplete": "import",
+	"fulleval/044_Issue_#178":                              "import",
+	"fulleval/048_dont_pass_incomplete_values_to_builtins": "import",
+	"fulleval/049_alias_reuse_in_nested_scope":             "import",
+	"fulleval/050_json_Marshaling_detects_incomplete":      "import",
+	"fulleval/051_detectIncompleteYAML":                    "import",
+	"fulleval/052_detectIncompleteJSON":                    "import",
+	"fulleval/056_issue314":                                "import",
+	"resolve/013_custom_validators":                        "import",
+}
+
+// TestX is for debugging. Do not delete.
+func TestX(t *testing.T) {
+	in := `
+	`
+
+	if strings.TrimSpace(in) == "" {
+		t.Skip()
+	}
+
+	file, err := parser.ParseFile("TestX", in)
+	if err != nil {
+		t.Fatal(err)
+	}
+	r := runtime.New()
+
+	arc, err := compile.Files(nil, r, file)
+	if err != nil {
+		t.Error(errors.Details(err, nil))
+	}
+	t.Error(debug.NodeString(r, arc.Conjuncts[0].Expr(), nil))
+}
diff --git a/internal/core/compile/errors.go b/internal/core/compile/errors.go
new file mode 100644
index 0000000..fb97622
--- /dev/null
+++ b/internal/core/compile/errors.go
@@ -0,0 +1,48 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compile
+
+import (
+	"strings"
+
+	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/errors"
+	"cuelang.org/go/cue/token"
+)
+
+var _ errors.Error = &compilerError{}
+
+type compilerError struct {
+	n    ast.Node
+	path []string
+	errors.Message
+}
+
+func (e *compilerError) Position() token.Pos         { return e.n.Pos() }
+func (e *compilerError) InputPositions() []token.Pos { return nil }
+func (e *compilerError) Path() []string              { return e.path }
+func (e *compilerError) Error() string {
+	pos := e.n.Pos()
+	// Import cycles deserve special treatment.
+	if pos.IsValid() {
+		// Omit import stack. The full path to the file where the error
+		// is the most important thing.
+		return pos.String() + ": " + e.Message.Error()
+	}
+	if len(e.path) == 0 {
+		return e.Message.Error()
+	}
+	return strings.Join(e.path, ".") + ": " + e.Message.Error()
+}
diff --git a/internal/core/compile/label.go b/internal/core/compile/label.go
new file mode 100644
index 0000000..1c03298
--- /dev/null
+++ b/internal/core/compile/label.go
@@ -0,0 +1,173 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compile
+
+import (
+	"strings"
+
+	"github.com/cockroachdb/apd/v2"
+	"golang.org/x/text/unicode/norm"
+
+	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/literal"
+	"cuelang.org/go/cue/token"
+	"cuelang.org/go/internal/core/adt"
+)
+
+// LabelFromNode converts an ADT node to a feature.
+func (c *compiler) label(n ast.Node) adt.Feature {
+	index := c.index
+	switch x := n.(type) {
+	case *ast.Ident:
+		s := x.Name
+		i := index.StringToIndex(x.Name)
+		t := adt.StringLabel
+		switch {
+		case strings.HasPrefix(s, "#_"):
+			t = adt.HiddenDefinitionLabel
+		case strings.HasPrefix(s, "#"):
+			t = adt.DefinitionLabel
+		case strings.HasPrefix(s, "_"):
+			t = adt.HiddenLabel
+		}
+		f, err := adt.MakeLabel(n.Pos(), i, t)
+		if err != nil {
+			c.errf(n, "invalid identifier label: %v", err)
+			return adt.InvalidLabel
+		}
+		return f
+
+	case *ast.BasicLit:
+		switch x.Kind {
+		case token.STRING:
+			const msg = "invalid string label: %v"
+			s, err := literal.Unquote(x.Value)
+			if err != nil {
+				c.errf(n, msg, err)
+				return adt.InvalidLabel
+			}
+
+			i := int64(index.StringToIndex(norm.NFC.String(s)))
+			f, err := adt.MakeLabel(n.Pos(), i, adt.StringLabel)
+			if err != nil {
+				c.errf(n, msg, err)
+			}
+			return f
+
+		case token.INT:
+			const msg = "invalid int label: %v"
+			if err := literal.ParseNum(x.Value, &c.num); err != nil {
+				c.errf(n, msg, err)
+				return adt.InvalidLabel
+			}
+
+			var d apd.Decimal
+			if err := c.num.Decimal(&d); err != nil {
+				c.errf(n, msg, err)
+				return adt.InvalidLabel
+			}
+
+			i, err := d.Int64()
+			if err != nil {
+				c.errf(n, msg, err)
+				return adt.InvalidLabel
+			}
+
+			f, err := adt.MakeLabel(n.Pos(), i, adt.IntLabel)
+			if err != nil {
+				c.errf(n, msg, err)
+				return adt.InvalidLabel
+			}
+			return f
+
+		case token.FLOAT:
+			_ = c.errf(n, "float %s cannot be used as label", x.Value)
+			return adt.InvalidLabel
+
+		default: // keywords (null, true, false, for, in, if, let)
+			i := index.StringToIndex(x.Kind.String())
+			f, err := adt.MakeLabel(n.Pos(), i, adt.StringLabel)
+			if err != nil {
+				c.errf(n, "invalid string label: %v", err)
+			}
+			return f
+		}
+
+	default:
+		c.errf(n, "unsupported label node type %T", n)
+		return adt.InvalidLabel
+	}
+}
+
+// A labeler converts an AST node to a string representation.
+type labeler interface {
+	labelString() string
+}
+
+type fieldLabel ast.Field
+
+func (l *fieldLabel) labelString() string {
+	lab := l.Label
+
+	if a, ok := lab.(*ast.Alias); ok {
+		if x, _ := a.Expr.(ast.Label); x != nil {
+			lab = x
+		}
+	}
+
+	switch x := lab.(type) {
+	case *ast.Ident:
+		return x.Name
+
+	case *ast.BasicLit:
+		if x.Kind == token.STRING {
+			s, err := literal.Unquote(x.Value)
+			if err == nil && ast.IsValidIdent(s) {
+				return s
+			}
+		}
+		return x.Value
+
+	case *ast.ListLit:
+		return "[]" // TODO: more detail
+
+	case *ast.Interpolation:
+		return "?"
+		// case *ast.ParenExpr:
+	}
+	return "<unknown>"
+}
+
+type forScope ast.ForClause
+
+func (l *forScope) labelString() string {
+	// TODO: include more info in square brackets.
+	return "for[]"
+}
+
+type letScope ast.LetClause
+
+func (l *letScope) labelString() string {
+	// TODO: include more info in square brackets.
+	return "let[]"
+}
+
+// TODO(legacy): remove
+type deprecatedAliasScope ast.Alias
+
+func (l *deprecatedAliasScope) labelString() string {
+	// TODO: include more info in square brackets.
+	return "let[]"
+}
diff --git a/internal/core/compile/predeclared.go b/internal/core/compile/predeclared.go
new file mode 100644
index 0000000..fcadc36
--- /dev/null
+++ b/internal/core/compile/predeclared.go
@@ -0,0 +1,138 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package compile
+
+import (
+	"strconv"
+
+	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/token"
+	"cuelang.org/go/internal/core/adt"
+)
+
+func predeclared(n *ast.Ident) adt.Expr {
+	// TODO: consider supporting GraphQL-style names:
+	// String, Bytes, Boolean, Integer, Number.
+	// These names will not conflict with idiomatic camel-case JSON.
+	switch n.Name {
+	case "_":
+		return &adt.Top{Src: n}
+	case "string", "__string":
+		return &adt.BasicType{Src: n, K: adt.StringKind}
+	case "bytes", "__bytes":
+		return &adt.BasicType{Src: n, K: adt.BytesKind}
+	case "bool", "__bool":
+		return &adt.BasicType{Src: n, K: adt.BoolKind}
+	case "int", "__int":
+		return &adt.BasicType{Src: n, K: adt.IntKind}
+	case "float", "__float":
+		return &adt.BasicType{Src: n, K: adt.FloatKind}
+	case "number", "__number":
+		return &adt.BasicType{Src: n, K: adt.NumKind}
+
+		// case "len", "__len":
+		// 	return lenBuiltin
+		// case "close", "__close":
+		// 	return closeBuiltin
+		// case "and", "__and":
+		// 	return andBuiltin
+		// case "or", "__or":
+		// 	return orBuiltin
+	}
+
+	if r, ok := predefinedRanges[n.Name]; ok {
+		return r
+	}
+
+	return nil
+}
+
+var predefinedRanges = map[string]adt.Expr{
+	"rune":  mkIntRange("0", strconv.Itoa(0x10FFFF)),
+	"int8":  mkIntRange("-128", "127"),
+	"int16": mkIntRange("-32768", "32767"),
+	"int32": mkIntRange("-2147483648", "2147483647"),
+	"int64": mkIntRange("-9223372036854775808", "9223372036854775807"),
+	"int128": mkIntRange(
+		"-170141183460469231731687303715884105728",
+		"170141183460469231731687303715884105727"),
+
+	// Do not include an alias for "byte", as it would be too easily confused
+	// with the builtin "bytes".
+	"uint":    mkUint(),
+	"uint8":   mkIntRange("0", "255"),
+	"uint16":  mkIntRange("0", "65535"),
+	"uint32":  mkIntRange("0", "4294967295"),
+	"uint64":  mkIntRange("0", "18446744073709551615"),
+	"uint128": mkIntRange("0", "340282366920938463463374607431768211455"),
+
+	// 2**127 * (2**24 - 1) / 2**23
+	"float32": mkFloatRange(
+		"-3.40282346638528859811704183484516925440e+38",
+		"3.40282346638528859811704183484516925440e+38",
+	),
+	// 2**1023 * (2**53 - 1) / 2**52
+	"float64": mkFloatRange(
+		"-1.797693134862315708145274237317043567981e+308",
+		"1.797693134862315708145274237317043567981e+308",
+	),
+}
+
+// TODO: use an adt.BoundValue here.
+
+func mkUint() adt.Expr {
+	from := newBound(adt.GreaterEqualOp, adt.IntKind, parseInt("0"))
+	ident := ast.NewIdent("__int")
+	src := ast.NewBinExpr(token.AND, ident, from.Src)
+	return &adt.Conjunction{
+		Src: src,
+		Values: []adt.Value{
+			&adt.BasicType{Src: ident, K: adt.IntKind}, from,
+		},
+	}
+}
+
+func mkIntRange(a, b string) adt.Expr {
+	from := newBound(adt.GreaterEqualOp, adt.IntKind, parseInt(a))
+	to := newBound(adt.LessEqualOp, adt.IntKind, parseInt(b))
+	return &adt.BinaryExpr{nil, adt.AndOp, from, to}
+}
+
+func mkFloatRange(a, b string) adt.Expr {
+	from := newBound(adt.GreaterEqualOp, adt.NumKind, parseFloat(a))
+	to := newBound(adt.LessEqualOp, adt.NumKind, parseFloat(b))
+	return &adt.BinaryExpr{nil, adt.AndOp, from, to}
+}
+
+func newBound(op adt.Op, k adt.Kind, v adt.Value) *adt.BoundValue {
+	return &adt.BoundValue{Op: op, Value: v}
+}
+
+func parseInt(s string) *adt.Num {
+	return parseNum(adt.IntKind, s)
+}
+
+func parseFloat(s string) *adt.Num {
+	return parseNum(adt.FloatKind, s)
+}
+
+func parseNum(k adt.Kind, s string) *adt.Num {
+	num := &adt.Num{K: k}
+	_, _, err := num.X.SetString(s)
+	if err != nil {
+		panic(err)
+	}
+	return num
+}
diff --git a/internal/core/debug/debug.go b/internal/core/debug/debug.go
new file mode 100644
index 0000000..c0a5d1d
--- /dev/null
+++ b/internal/core/debug/debug.go
@@ -0,0 +1,450 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package debug prints a given ADT node.
+//
+// Note that the result is not valid CUE, but instead prints the internals
+// of an ADT node in human-readable form. It uses a simple indentation algorithm
+// for improved readability and diffing.
+//
+package debug
+
+import (
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+
+	"cuelang.org/go/cue/errors"
+	"cuelang.org/go/internal"
+	"cuelang.org/go/internal/core/adt"
+	"golang.org/x/xerrors"
+)
+
+const (
+	openTuple  = "\u3008"
+	closeTuple = "\u3009"
+)
+
+type Config struct {
+	Cwd string
+}
+
+func WriteNode(w io.Writer, i adt.StringIndexer, n adt.Node, config *Config) {
+	if config == nil {
+		config = &Config{}
+	}
+	p := printer{Writer: w, index: i, cfg: config}
+	p.node(n)
+}
+
+func NodeString(i adt.StringIndexer, n adt.Node, config *Config) string {
+	if config == nil {
+		config = &Config{}
+	}
+	b := &strings.Builder{}
+	p := printer{Writer: b, index: i, cfg: config}
+	p.node(n)
+	return b.String()
+}
+
+type printer struct {
+	io.Writer
+	index  adt.StringIndexer
+	indent string
+	cfg    *Config
+}
+
+func (w *printer) string(s string) {
+	s = strings.Replace(s, "\n", "\n"+w.indent, -1)
+	_, _ = io.WriteString(w, s)
+}
+
+func (w *printer) label(f adt.Feature) {
+	w.string(w.labelString(f))
+}
+
+// TODO: fold into label once :: is no longer supported.
+func (w *printer) labelString(f adt.Feature) string {
+	return f.SelectorString(w.index)
+}
+
+func (w *printer) shortError(errs errors.Error) {
+	for {
+		msg, args := errs.Msg()
+		fmt.Fprintf(w, msg, args...)
+
+		err := xerrors.Unwrap(errs)
+		if err == nil {
+			break
+		}
+
+		if errs, _ = err.(errors.Error); errs != nil {
+			w.string(err.Error())
+			break
+		}
+	}
+}
+
+func (w *printer) node(n adt.Node) {
+	switch x := n.(type) {
+	case *adt.Vertex:
+		var kind adt.Kind
+		if x.Value != nil {
+			kind = x.Value.Kind()
+		}
+
+		kindStr := kind.String()
+		kindStr = strings.ReplaceAll(kindStr, "{...}", "struct")
+		kindStr = strings.ReplaceAll(kindStr, "[...]", "list")
+
+		fmt.Fprintf(w, "(%s){", kindStr)
+
+		if x.Value != nil && kind&^(adt.StructKind|adt.ListKind) != 0 {
+			w.string(" ")
+			w.node(x.Value)
+			w.string(" }")
+			return
+		}
+
+		saved := w.indent
+		w.indent += "  "
+
+		if b, ok := x.Value.(*adt.Bottom); ok {
+			saved := w.indent
+			w.indent += "// "
+			w.string("\n")
+			w.string(strings.TrimSpace(errors.Details(b.Err, &errors.Config{
+				Cwd:     w.cfg.Cwd,
+				ToSlash: true,
+			})))
+			w.indent = saved
+		}
+
+		if len(x.Arcs) > 0 {
+			for _, a := range x.Arcs {
+				w.string("\n")
+				w.label(a.Label)
+				w.string(": ")
+				w.node(a)
+			}
+		}
+
+		if x.Value == nil {
+			w.indent += "// "
+			w.string("// ")
+			for i, c := range x.Conjuncts {
+				if i > 0 {
+					w.string(" & ")
+				}
+				w.node(c.Expr()) // TODO: also include env?
+			}
+		}
+
+		w.indent = saved
+		w.string("\n")
+		w.string("}")
+
+	case *adt.StructMarker:
+		w.string("struct")
+
+	case *adt.ListMarker:
+		w.string("list")
+
+	case *adt.StructLit:
+		if len(x.Decls) == 0 {
+			w.string("{}")
+			break
+		}
+		w.string("{")
+		w.indent += "  "
+		for _, d := range x.Decls {
+			w.string("\n")
+			w.node(d)
+		}
+		w.indent = w.indent[:len(w.indent)-2]
+		w.string("\n}")
+
+	case *adt.ListLit:
+		if len(x.Elems) == 0 {
+			w.string("[]")
+			break
+		}
+		w.string("[")
+		w.indent += "  "
+		for _, d := range x.Elems {
+			w.string("\n")
+			w.node(d)
+			w.string(",")
+		}
+		w.indent = w.indent[:len(w.indent)-2]
+		w.string("\n]")
+
+	case *adt.Field:
+		s := w.labelString(x.Label)
+		w.string(s)
+		w.string(":")
+		if x.Label.IsDef() && !internal.IsDef(s) {
+			w.string(":")
+		}
+		w.string(" ")
+		w.node(x.Value)
+
+	case *adt.OptionalField:
+		s := w.labelString(x.Label)
+		w.string(s)
+		w.string("?:")
+		if x.Label.IsDef() && !internal.IsDef(s) {
+			w.string(":")
+		}
+		w.string(" ")
+		w.node(x.Value)
+
+	case *adt.BulkOptionalField:
+		w.string("[")
+		w.node(x.Filter)
+		w.string("]: ")
+		w.node(x.Value)
+
+	case *adt.DynamicField:
+		w.node(x.Key)
+		if x.IsOptional() {
+			w.string("?")
+		}
+		w.string(": ")
+		w.node(x.Value)
+
+	case *adt.Ellipsis:
+		w.string("...")
+		if x.Value != nil {
+			w.node(x.Value)
+		}
+
+	case *adt.Bottom:
+		w.string(`_|_`)
+		if x.Err != nil {
+			w.string("(")
+			w.shortError(x.Err)
+			w.string(")")
+		}
+
+	case *adt.Null:
+		w.string("null")
+
+	case *adt.Bool:
+		fmt.Fprint(w, x.B)
+
+	case *adt.Num:
+		fmt.Fprint(w, &x.X)
+
+	case *adt.String:
+		w.string(strconv.Quote(x.Str))
+
+	case *adt.Bytes:
+		b := []byte(strconv.Quote(string(x.B)))
+		b[0] = '\''
+		b[len(b)-1] = '\''
+		w.string(string(b))
+
+	case *adt.Top:
+		w.string("_")
+
+	case *adt.BasicType:
+		fmt.Fprint(w, x.K)
+
+	case *adt.BoundExpr:
+		fmt.Fprint(w, x.Op)
+		w.node(x.Expr)
+
+	case *adt.BoundValue:
+		fmt.Fprint(w, x.Op)
+		w.node(x.Value)
+
+	case *adt.FieldReference:
+		w.string(openTuple)
+		w.string(strconv.Itoa(int(x.UpCount)))
+		w.string(";")
+		w.label(x.Label)
+		w.string(closeTuple)
+
+	case *adt.LabelReference:
+		w.string(openTuple)
+		w.string(strconv.Itoa(int(x.UpCount)))
+		w.string(";-")
+		w.string(closeTuple)
+
+	case *adt.DynamicReference:
+		w.string(openTuple)
+		w.string(strconv.Itoa(int(x.UpCount)))
+		w.string(";(")
+		w.node(x.Label)
+		w.string(")")
+		w.string(closeTuple)
+
+	case *adt.ImportReference:
+		w.string(openTuple + "import;")
+		w.label(x.ImportPath)
+		w.string(closeTuple)
+
+	case *adt.LetReference:
+		w.string(openTuple)
+		w.string(strconv.Itoa(int(x.UpCount)))
+		w.string(";let ")
+		w.label(x.Label)
+		w.string(closeTuple)
+
+	case *adt.SelectorExpr:
+		w.node(x.X)
+		w.string(".")
+		w.label(x.Sel)
+
+	case *adt.IndexExpr:
+		w.node(x.X)
+		w.string("[")
+		w.node(x.Index)
+		w.string("]")
+
+	case *adt.SliceExpr:
+		w.node(x.X)
+		w.string("[")
+		if x.Lo != nil {
+			w.node(x.Lo)
+		}
+		w.string(":")
+		if x.Hi != nil {
+			w.node(x.Hi)
+		}
+		if x.Stride != nil {
+			w.string(":")
+			w.node(x.Stride)
+		}
+		w.string("]")
+
+	case *adt.Interpolation:
+		w.string(`"`)
+		for i := 0; i < len(x.Parts); i += 2 {
+			if s, ok := x.Parts[i].(*adt.String); ok {
+				w.string(s.Str)
+			} else {
+				w.string("<bad string>")
+			}
+			if i+1 < len(x.Parts) {
+				w.string(`\(`)
+				w.node(x.Parts[i+1])
+				w.string(`)`)
+			}
+		}
+		w.string(`"`)
+
+	case *adt.UnaryExpr:
+		fmt.Fprint(w, x.Op)
+		w.node(x.X)
+
+	case *adt.BinaryExpr:
+		w.string("(")
+		w.node(x.X)
+		fmt.Fprint(w, " ", x.Op, " ")
+		w.node(x.Y)
+		w.string(")")
+
+	case *adt.CallExpr:
+		w.node(x.Fun)
+		w.string("(")
+		for i, a := range x.Args {
+			if i > 0 {
+				w.string(", ")
+			}
+			w.node(a)
+		}
+		w.string(")")
+
+	case *adt.BuiltinValidator:
+		w.node(x.Fun)
+		w.string("(")
+		for i, a := range x.Args {
+			if i > 0 {
+				w.string(", ")
+			}
+			w.node(a)
+		}
+		w.string(")")
+
+	case *adt.DisjunctionExpr:
+		w.string("(")
+		for i, a := range x.Values {
+			if i > 0 {
+				w.string("|")
+			}
+			// Disjunct
+			if a.Default {
+				w.string("*")
+			}
+			w.node(a.Val)
+		}
+		w.string(")")
+
+	case *adt.Conjunction:
+		w.string("&(")
+		for i, c := range x.Values {
+			if i > 0 {
+				w.string(", ")
+			}
+			w.node(c)
+		}
+		w.string(")")
+
+	case *adt.Disjunction:
+		w.string("|(")
+		for i, c := range x.Values {
+			if i > 0 {
+				w.string(", ")
+			}
+			if i < x.NumDefaults {
+				w.string("*")
+			}
+			w.node(c)
+		}
+		w.string(")")
+
+	case *adt.ForClause:
+		w.string("for ")
+		w.label(x.Key)
+		w.string(", ")
+		w.label(x.Value)
+		w.string(" in ")
+		w.node(x.Src)
+		w.string(" ")
+		w.node(x.Dst)
+
+	case *adt.IfClause:
+		w.string("if ")
+		w.node(x.Condition)
+		w.string(" ")
+		w.node(x.Dst)
+
+	case *adt.LetClause:
+		w.string("let ")
+		w.label(x.Label)
+		w.string(" = ")
+		w.node(x.Expr)
+		w.string(" ")
+		w.node(x.Dst)
+
+	case *adt.ValueClause:
+		w.node(x.StructLit)
+
+	default:
+		panic(fmt.Sprintf("unknown type %T", x))
+	}
+}
diff --git a/internal/core/runtime/index.go b/internal/core/runtime/index.go
new file mode 100644
index 0000000..4907368
--- /dev/null
+++ b/internal/core/runtime/index.go
@@ -0,0 +1,81 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"sync"
+)
+
+// index maps conversions from label names to internal codes.
+//
+// All instances belonging to the same package should share this index.
+type index struct {
+	labelMap map[string]int
+	labels   []string
+
+	offset int
+	parent *index
+
+	mutex     sync.Mutex
+	typeCache sync.Map // map[reflect.Type]evaluated
+}
+
+// work around golang-ci linter bug: fields are used.
+func init() {
+	var i index
+	i.mutex.Lock()
+	i.mutex.Unlock()
+	i.typeCache.Load(1)
+}
+
+// sharedIndex is used for indexing builtins and any other labels common to
+// all instances.
+var sharedIndex = newSharedIndex()
+
+func newSharedIndex() *index {
+	i := &index{
+		labelMap: map[string]int{"": 0},
+		labels:   []string{"_"},
+	}
+	return i
+}
+
+// newIndex creates a new index.
+func newIndex(parent *index) *index {
+	i := &index{
+		labelMap: map[string]int{},
+		offset:   len(parent.labels) + parent.offset,
+		parent:   parent,
+	}
+	return i
+}
+
+func (x *index) IndexToString(i int64) string {
+	for ; int(i) < x.offset; x = x.parent {
+	}
+	return x.labels[int(i)-x.offset]
+}
+
+func (x *index) StringToIndex(s string) int64 {
+	for p := x; p != nil; p = p.parent {
+		if f, ok := p.labelMap[s]; ok {
+			return int64(f)
+		}
+	}
+	index := len(x.labelMap) + x.offset
+	x.labelMap[s] = index
+	x.labels = append(x.labels, s)
+	return int64(index)
+}
diff --git a/internal/core/runtime/runtime.go b/internal/core/runtime/runtime.go
new file mode 100644
index 0000000..ecdaa0a
--- /dev/null
+++ b/internal/core/runtime/runtime.go
@@ -0,0 +1,27 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+// A Runtime maintains data structures for indexing and resuse for evaluation.
+type Runtime struct {
+	*index
+}
+
+// New creates a new Runtime.
+func New() *Runtime {
+	return &Runtime{
+		index: newIndex(sharedIndex),
+	}
+}
diff --git a/internal/cuetxtar/txtar.go b/internal/cuetxtar/txtar.go
index 943d136..241305f 100644
--- a/internal/cuetxtar/txtar.go
+++ b/internal/cuetxtar/txtar.go
@@ -193,8 +193,9 @@
 			return nil
 		}
 
-		p := strings.Index(fullpath, "/testdata/")
-		testName := fullpath[p+len("/testdata/") : len(fullpath)-len(".txtar")]
+		str := filepath.ToSlash(fullpath)
+		p := strings.Index(str, "/testdata/")
+		testName := str[p+len("/testdata/") : len(str)-len(".txtar")]
 
 		t.Run(testName, func(t *testing.T) {
 			a, err := txtar.ParseFile(fullpath)