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)
