pkg: added some manually crafted builtins

Change-Id: I1e5d8b987b2fbd2605a9ff5853dc3b1e7eb9b620
diff --git a/pkg/encoding/csv/manual.go b/pkg/encoding/csv/manual.go
new file mode 100644
index 0000000..1e2338c
--- /dev/null
+++ b/pkg/encoding/csv/manual.go
@@ -0,0 +1,60 @@
+// Copyright 2018 The 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 csv
+
+import (
+	"bytes"
+	"encoding/csv"
+	"io"
+
+	"cuelang.org/go/cue"
+)
+
+// Encode encode the given list of lists to CSV.
+func Encode(x cue.Value) (string, error) {
+	buf := &bytes.Buffer{}
+	w := csv.NewWriter(buf)
+	iter, err := x.List()
+	if err != nil {
+		return "", err
+	}
+	for iter.Next() {
+		row, err := iter.Value().List()
+		if err != nil {
+			return "", err
+		}
+		a := []string{}
+		for row.Next() {
+			col := row.Value()
+			if str, err := col.String(); err == nil {
+				a = append(a, str)
+			} else {
+				b, err := col.MarshalJSON()
+				if err != nil {
+					return "", err
+				}
+				a = append(a, string(b))
+			}
+		}
+		w.Write(a)
+	}
+	w.Flush()
+	return buf.String(), nil
+}
+
+// Decode reads in a csv into a list of lists.
+func Decode(r io.Reader) ([][]string, error) {
+	return csv.NewReader(r).ReadAll()
+}
diff --git a/pkg/encoding/hex/manual.go b/pkg/encoding/hex/manual.go
new file mode 100644
index 0000000..9f1ca55
--- /dev/null
+++ b/pkg/encoding/hex/manual.go
@@ -0,0 +1,22 @@
+// Copyright 2018 The 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 hex
+
+import "encoding/hex"
+
+// Encode returns the hexadecimal encoding of src.
+func Encode(src []byte) string {
+	return hex.EncodeToString(src)
+}
diff --git a/pkg/encoding/json/manual.go b/pkg/encoding/json/manual.go
new file mode 100644
index 0000000..9b2d324
--- /dev/null
+++ b/pkg/encoding/json/manual.go
@@ -0,0 +1,104 @@
+// Copyright 2018 The 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 json
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+
+	"cuelang.org/go/cue"
+	"cuelang.org/go/cue/parser"
+	"cuelang.org/go/cue/token"
+)
+
+// Compact generates the JSON-encoded src with insignificant space characters
+// elided.
+func Compact(src []byte) (string, error) {
+	dst := bytes.Buffer{}
+	if err := json.Compact(&dst, src); err != nil {
+		return "", err
+	}
+	return dst.String(), nil
+}
+
+// Indent creates an indented form of the JSON-encoded src.
+// Each element in a JSON object or array begins on a new,
+// indented line beginning with prefix followed by one or more
+// copies of indent according to the indentation nesting.
+// The data appended to dst does not begin with the prefix nor
+// any indentation, to make it easier to embed inside other formatted JSON data.
+// Although leading space characters (space, tab, carriage return, newline)
+// at the beginning of src are dropped, trailing space characters
+// at the end of src are preserved and copied to dst.
+// For example, if src has no trailing spaces, neither will dst;
+// if src ends in a trailing newline, so will dst.
+func Indent(src []byte, prefix, indent string) (string, error) {
+	dst := bytes.Buffer{}
+	if err := json.Indent(&dst, src, prefix, indent); err != nil {
+		return "", err
+	}
+	return dst.String(), nil
+}
+
+// HTMLEscape returns the JSON-encoded src with <, >, &, U+2028 and
+// U+2029 characters inside string literals changed to \u003c, \u003e, \u0026,
+// \u2028, \u2029 so that the JSON will be safe to embed inside HTML <script>
+// tags. For historical reasons, web browsers don't honor standard HTML escaping
+// within <script> tags, so an alternative JSON encoding must be used.
+func HTMLEscape(src []byte) string {
+	dst := &bytes.Buffer{}
+	json.HTMLEscape(dst, src)
+	return dst.String()
+}
+
+// Marshal returns the JSON encoding of v.
+func Marshal(v cue.Value) (string, error) {
+	b, err := json.Marshal(v)
+	return string(b), err
+}
+
+// MarshalStream turns a list into a stream of JSON objects.
+func MarshalStream(v cue.Value) (string, error) {
+	// TODO: return an io.Reader and allow asynchronous processing.
+	iter, err := v.List()
+	if err != nil {
+		return "", err
+	}
+	buf := &bytes.Buffer{}
+	for iter.Next() {
+		b, err := json.Marshal(iter.Value())
+		if err != nil {
+			return "", err
+		}
+		buf.Write(b)
+		buf.WriteByte('\n')
+	}
+	return buf.String(), nil
+}
+
+// Unmarshal parses the JSON-encoded data.
+func Unmarshal(b []byte) (*cue.Instance, error) {
+	if !json.Valid(b) {
+		return nil, fmt.Errorf("json: invalid JSON")
+	}
+	fset := token.NewFileSet()
+	expr, err := parser.ParseExpr(fset, "json", b)
+	if err != nil {
+		// NOTE: should never happen.
+		return nil, fmt.Errorf("json: could not parse JSON: %v", err)
+	}
+	return cue.FromExpr(fset, expr)
+}
diff --git a/pkg/encoding/yaml/manual.go b/pkg/encoding/yaml/manual.go
new file mode 100644
index 0000000..c4e609a
--- /dev/null
+++ b/pkg/encoding/yaml/manual.go
@@ -0,0 +1,61 @@
+// Copyright 2018 The 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 yaml
+
+import (
+	"bytes"
+
+	"cuelang.org/go/cue"
+	"cuelang.org/go/cue/token"
+	"cuelang.org/go/internal/third_party/yaml"
+	goyaml "github.com/ghodss/yaml"
+)
+
+// Marshal returns the YAML encoding of v.
+func Marshal(v cue.Value) (string, error) {
+	b, err := goyaml.Marshal(v)
+	return string(b), err
+}
+
+// MarshalStream returns the YAML encoding of v.
+func MarshalStream(v cue.Value) (string, error) {
+	// TODO: return an io.Reader and allow asynchronous processing.
+	iter, err := v.List()
+	if err != nil {
+		return "", err
+	}
+	buf := &bytes.Buffer{}
+	for i := 0; iter.Next(); i++ {
+		if i > 0 {
+			buf.WriteString("---\n")
+		}
+		b, err := goyaml.Marshal(iter.Value())
+		if err != nil {
+			return "", err
+		}
+		buf.Write(b)
+	}
+	return buf.String(), nil
+}
+
+// Unmarshal parses the YAML to a CUE instance.
+func Unmarshal(data []byte) (*cue.Instance, error) {
+	fset := token.NewFileSet()
+	expr, err := yaml.Unmarshal(fset, "", data)
+	if err != nil {
+		return nil, err
+	}
+	return cue.FromExpr(fset, expr)
+}
diff --git a/pkg/math/bits/manual.go b/pkg/math/bits/manual.go
new file mode 100644
index 0000000..f7376a6
--- /dev/null
+++ b/pkg/math/bits/manual.go
@@ -0,0 +1,129 @@
+// Copyright 2018 The 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.
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bits
+
+import (
+	"math/big"
+	"math/bits"
+)
+
+// And returns the bitwise and of a and b (a & b in Go).
+//
+func And(a, b *big.Int) *big.Int {
+	wa := a.Bits()
+	wb := b.Bits()
+	n := len(wa)
+	if len(wb) < n {
+		n = len(wb)
+	}
+	w := make([]big.Word, n)
+	for i := range w {
+		w[i] = wa[i] & wb[i]
+	}
+	i := &big.Int{}
+	i.SetBits(w)
+	return i
+}
+
+// Or returns the bitwise or of a and b (a | b in Go).
+//
+func Or(a, b *big.Int) *big.Int {
+	wa := a.Bits()
+	wb := b.Bits()
+	var w []big.Word
+	n := len(wa)
+	if len(wa) > len(wb) {
+		w = append(w, wa...)
+		n = len(wb)
+	} else {
+		w = append(w, wb...)
+	}
+	for i := 0; i < n; i++ {
+		w[i] = wa[i] | wb[i]
+	}
+	i := &big.Int{}
+	i.SetBits(w)
+	return i
+}
+
+// Xor returns the bitwise xor of a and b (a ^ b in Go).
+//
+func Xor(a, b *big.Int) *big.Int {
+	wa := a.Bits()
+	wb := b.Bits()
+	var w []big.Word
+	n := len(wa)
+	if len(wa) > len(wb) {
+		w = append(w, wa...)
+		n = len(wb)
+	} else {
+		w = append(w, wb...)
+	}
+	for i := 0; i < n; i++ {
+		w[i] = wa[i] ^ wb[i]
+	}
+	i := &big.Int{}
+	i.SetBits(w)
+	return i
+}
+
+// Clear returns the bitwise and not of a and b (a &^ b in Go).
+//
+func Clear(a, b *big.Int) *big.Int {
+	wa := a.Bits()
+	wb := b.Bits()
+	w := append([]big.Word(nil), wa...)
+	for i, m := range wb {
+		if i >= len(w) {
+			break
+		}
+		w[i] = wa[i] &^ m
+	}
+	i := &big.Int{}
+	i.SetBits(w)
+	return i
+}
+
+// TODO: ShiftLeft, maybe trailing and leading zeros
+
+// OnesCount returns the number of one bits ("population count") in x.
+func OnesCount(x uint64) int {
+	return bits.OnesCount64(x)
+}
+
+// RotateLeft returns the value of x rotated left by (k mod UintSize) bits.
+// To rotate x right by k bits, call RotateLeft(x, -k).
+func RotateLeft(x uint64, k int) uint64 {
+	return bits.RotateLeft64(x, k)
+}
+
+// Reverse returns the value of x with its bits in reversed order.
+func Reverse(x uint64) uint64 {
+	return bits.Reverse64(x)
+}
+
+// ReverseBytes returns the value of x with its bytes in reversed order.
+func ReverseBytes(x uint64) uint64 {
+	return bits.ReverseBytes64(x)
+}
+
+// Len returns the minimum number of bits required to represent x; the result is 0 for x == 0.
+func Len(x uint64) int {
+	return bits.Len64(x)
+}
diff --git a/pkg/path/manual.go b/pkg/path/manual.go
new file mode 100644
index 0000000..99525a7
--- /dev/null
+++ b/pkg/path/manual.go
@@ -0,0 +1,28 @@
+// Copyright 2018 The 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 path
+
+import "path"
+
+var split = path.Split
+
+// Split splits path immediately following the final slash and returns them as
+// the list [dir, file], separating it into a directory and file name component.
+// If there is no slash in path, Split returns an empty dir and file set to
+// path. The returned values have the property that path = dir+file.
+func Split(path string) []string {
+	file, dir := split(path)
+	return []string{file, dir}
+}
diff --git a/pkg/strconv/manual.go b/pkg/strconv/manual.go
new file mode 100644
index 0000000..e179ad4
--- /dev/null
+++ b/pkg/strconv/manual.go
@@ -0,0 +1,24 @@
+// Copyright 2018 The 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 strconv
+
+// Unquote interprets s as a single-quoted, double-quoted,
+// or backquoted CUE string literal, returning the string value
+// that s quotes.
+func Unquote(s string) (string, error) {
+	return Unquote(s)
+}
+
+// TODO: replace parsing functions with parsing to apd
diff --git a/pkg/strings/manual.go b/pkg/strings/manual.go
new file mode 100644
index 0000000..7018115
--- /dev/null
+++ b/pkg/strings/manual.go
@@ -0,0 +1,58 @@
+// Copyright 2018 The 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 strings
+
+import (
+	"strings"
+	"unicode"
+)
+
+// ToTitle returns a copy of the string s with all Unicode letters that begin
+// words mapped to their title case.
+func ToTitle(s string) string {
+	// Use a closure here to remember state.
+	// Hackish but effective. Depends on Map scanning in order and calling
+	// the closure once per rune.
+	prev := ' '
+	return strings.Map(
+		func(r rune) rune {
+			if unicode.IsSpace(prev) {
+				prev = r
+				return unicode.ToTitle(r)
+			}
+			prev = r
+			return r
+		},
+		s)
+}
+
+// ToCamel returns a copy of the string s with all Unicode letters that begin
+// words mapped to lower case.
+func ToCamel(s string) string {
+	// Use a closure here to remember state.
+	// Hackish but effective. Depends on Map scanning in order and calling
+	// the closure once per rune.
+	prev := ' '
+	return strings.Map(
+		func(r rune) rune {
+			if unicode.IsSpace(prev) {
+				prev = r
+				return unicode.ToLower(r)
+			}
+			prev = r
+			return r
+		},
+		s)
+}
diff --git a/pkg/text/tabwriter/manual.go b/pkg/text/tabwriter/manual.go
new file mode 100644
index 0000000..b031a5b
--- /dev/null
+++ b/pkg/text/tabwriter/manual.go
@@ -0,0 +1,38 @@
+// Copyright 2018 The 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 tabwriter
+
+import (
+	"bytes"
+	"text/tabwriter"
+
+	"cuelang.org/go/cue"
+)
+
+// Write formats text in columns. See golang.org/pkg/text/tabwriter for more
+// info.
+func Write(data cue.Value) (string, error) {
+	buf := &bytes.Buffer{}
+	tw := tabwriter.NewWriter(buf, 0, 4, 1, ' ', 0)
+	b, err := data.Bytes()
+	if err != nil {
+		return "", err
+	}
+	_, err = tw.Write(b)
+	if err != nil {
+		return "", err
+	}
+	return buf.String(), err
+}
diff --git a/pkg/text/template/manual.go b/pkg/text/template/manual.go
new file mode 100644
index 0000000..3895917
--- /dev/null
+++ b/pkg/text/template/manual.go
@@ -0,0 +1,35 @@
+// Copyright 2018 The 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 template
+
+import (
+	"bytes"
+	"text/template"
+
+	"cuelang.org/go/cue"
+)
+
+// Execute executes a Go-style template.
+func Execute(templ string, data cue.Value) (string, error) {
+	t, err := template.New("").Parse(templ)
+	if err != nil {
+		return "", err
+	}
+	buf := &bytes.Buffer{}
+	if err := t.Execute(buf, data); err != nil {
+		return "", err
+	}
+	return buf.String(), nil
+}