Repository: source-academy/js-slang
Pull request #161 (2018-12-13 14:17:16)

Implement a better stringify, etc.
- Better stringify
- No more toString
- toString for functions now overridden instead
- Got rid of `__SOURCE__`, use `defineBuiltin` to hide implementation

coveralls: ## Pull Request Test Coverage Report for [Build 532](https://coveralls.io/builds/20616501)

* **117** of **132**   **(88.64%)**  changed or added relevant lines in **7** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage decreased (**-0.8%**) to **86.728%**

---

|  Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
| :-----|--------------|--------|---: |
| [src/stdlib/list.ts](https://coveralls.io/builds/20616501/source?filename=src%2Fstdlib%2Flist.ts#L167) | 3 | 4 | 75.0%
| [src/types.ts](https://coveralls.io/builds/20616501/source?filename=src%2Ftypes.ts#L136) | 1 | 2 | 50.0%
| [src/createContext.ts](https://coveralls.io/builds/20616501/source?filename=src%2FcreateContext.ts#L69) | 51 | 57 | 89.47%
| [src/interop.ts](https://coveralls.io/builds/20616501/source?filename=src%2Finterop.ts#L28) | 55 | 62 | 88.71%
<!-- | **Total:** | **117** | **132** | **88.64%** | -->


|  Totals | [![Coverage Status](https://coveralls.io/builds/20616501/badge)](https://coveralls.io/builds/20616501) |
| :-- | --: |
| Change from base [Build 528](https://coveralls.io/builds/20610706): |  -0.8% |
| Covered Lines: | 1233 |
| Relevant Lines: | 1406 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/src/createContext.ts b/src/createContext.ts
index b097f7e2..65013e1d 100644
--- a/src/createContext.ts
+++ b/src/createContext.ts
@@ -1,4 +1,4 @@
-import { toString } from './interop'
+import { stringify } from './interop'
 import * as list from './stdlib/list'
 import { list_to_vector } from './stdlib/list'
 import * as misc from './stdlib/misc'
@@ -42,7 +42,7 @@ export const ensureGlobalEnvironmentExist = (context: Context) => {
   }
 }
 
-export const defineSymbol = (context: Context, name: string, value: Value) => {
+const defineSymbol = (context: Context, name: string, value: Value) => {
   const globalFrame = context.runtime.frames[0]
   Object.defineProperty(globalFrame.environment, name, {
     value,
@@ -51,6 +51,21 @@ export const defineSymbol = (context: Context, name: string, value: Value) => {
   })
 }
 
+// Defines a builtin in the given context
+// If the builtin is a function, wrap it such that its toString hides the implementation
+export const defineBuiltin = (context: Context, name: string, value: Value) => {
+  if (typeof value === 'function') {
+    const wrapped = (...args: any) => value(...args)
+    const funName = name.split('(')[0].trim()
+    const repr = `function ${name} {\n\t[implementation hidden]\n}`
+    wrapped.toString = () => repr
+
+    defineSymbol(context, funName, wrapped)
+  } else {
+    defineSymbol(context, name, value)
+  }
+}
+
 export const importExternalSymbols = (context: Context, externalSymbols: string[]) => {
   ensureGlobalEnvironmentExist(context)
 
@@ -61,110 +76,95 @@ export const importExternalSymbols = (context: Context, externalSymbols: string[
 
 /**
  * Imports builtins from standard and external libraries.
- *
- * For externalBuiltIns that need to be curried, the __SOURCE__
- * property must be defined in the currying function.
  */
 export const importBuiltins = (context: Context, externalBuiltIns: CustomBuiltIns) => {
   ensureGlobalEnvironmentExist(context)
 
-  /* Defining the __SOURCE__ property in the curried functions. */
   const display = (v: Value) => externalBuiltIns.display(v, context.externalContext)
-  display.__SOURCE__ = externalBuiltIns.display.__SOURCE__
   const prompt = (v: Value) => externalBuiltIns.prompt(v, context.externalContext)
-  prompt.__SOURCE__ = externalBuiltIns.prompt.__SOURCE__
   const alert = (v: Value) => externalBuiltIns.alert(v, context.externalContext)
-  alert.__SOURCE__ = externalBuiltIns.alert.__SOURCE__
   const visualiseList = (v: Value) => externalBuiltIns.visualiseList(v, context.externalContext)
-  visualiseList.__SOURCE__ = externalBuiltIns.visualiseList.__SOURCE__
 
   if (context.chapter >= 1) {
-    defineSymbol(context, 'runtime', misc.runtime)
-    defineSymbol(context, 'display', display)
-    defineSymbol(context, 'error', misc.error_message)
-    defineSymbol(context, 'prompt', prompt)
-    defineSymbol(context, 'is_number', misc.is_number)
-    defineSymbol(context, 'is_string', misc.is_string)
-    defineSymbol(context, 'is_function', misc.is_function)
-    defineSymbol(context, 'is_boolean', misc.is_boolean)
-    defineSymbol(context, 'is_undefined', misc.is_undefined)
-    defineSymbol(context, 'parse_int', misc.parse_int)
-    defineSymbol(context, 'undefined', undefined)
-    defineSymbol(context, 'NaN', NaN)
-    defineSymbol(context, 'Infinity', Infinity)
+    defineBuiltin(context, 'runtime()', misc.runtime)
+    defineBuiltin(context, 'display(value)', display)
+    defineBuiltin(context, 'stringify(value)', stringify)
+    defineBuiltin(context, 'error(message)', misc.error_message)
+    defineBuiltin(context, 'prompt(message)', prompt)
+    defineBuiltin(context, 'is_number(value)', misc.is_number)
+    defineBuiltin(context, 'is_string(value)', misc.is_string)
+    defineBuiltin(context, 'is_function(value)', misc.is_function)
+    defineBuiltin(context, 'is_boolean(value)', misc.is_boolean)
+    defineBuiltin(context, 'is_undefined(value)', misc.is_undefined)
+    defineBuiltin(context, 'parse_int(str, radix)', misc.parse_int)
+    defineBuiltin(context, 'undefined', undefined)
+    defineBuiltin(context, 'NaN', NaN)
+    defineBuiltin(context, 'Infinity', Infinity)
     // Define all Math libraries
-    const objs = Object.getOwnPropertyNames(Math)
-    for (const i in objs) {
-      if (objs.hasOwnProperty(i)) {
-        const val = objs[i]
-        if (typeof Math[val] === 'function') {
-          defineSymbol(context, 'math_' + val, Math[val].bind())
-        } else {
-          defineSymbol(context, 'math_' + val, Math[val])
-        }
-      }
+    const props = Object.getOwnPropertyNames(Math)
+    for (const prop of props) {
+      defineBuiltin(context, 'math_' + prop, Math[prop])
     }
   }
 
   if (context.chapter >= 2) {
     // List library
-    defineSymbol(context, 'null', null)
-    defineSymbol(context, 'pair', list.pair)
-    defineSymbol(context, 'is_pair', list.is_pair)
-    defineSymbol(context, 'head', list.head)
-    defineSymbol(context, 'tail', list.tail)
-    defineSymbol(context, 'is_null', list.is_null)
-    defineSymbol(context, 'is_list', list.is_list)
-    defineSymbol(context, 'list', list.list)
-    defineSymbol(context, 'length', list.length)
-    defineSymbol(context, 'map', list.map)
-    defineSymbol(context, 'build_list', list.build_list)
-    defineSymbol(context, 'for_each', list.for_each)
-    defineSymbol(context, 'list_to_string', list.list_to_string)
-    defineSymbol(context, 'reverse', list.reverse)
-    defineSymbol(context, 'append', list.append)
-    defineSymbol(context, 'member', list.member)
-    defineSymbol(context, 'remove', list.remove)
-    defineSymbol(context, 'remove_all', list.remove_all)
-    defineSymbol(context, 'filter', list.filter)
-    defineSymbol(context, 'enum_list', list.enum_list)
-    defineSymbol(context, 'list_ref', list.list_ref)
-    defineSymbol(context, 'accumulate', list.accumulate)
-    defineSymbol(context, 'equal', list.equal)
-    defineSymbol(context, 'draw_list', visualiseList)
+    defineBuiltin(context, 'null', null)
+    defineBuiltin(context, 'pair(left, right)', list.pair)
+    defineBuiltin(context, 'is_pair(val)', list.is_pair)
+    defineBuiltin(context, 'head(xs)', list.head)
+    defineBuiltin(context, 'tail(xs)', list.tail)
+    defineBuiltin(context, 'is_null(val)', list.is_null)
+    defineBuiltin(context, 'is_list(val)', list.is_list)
+    defineBuiltin(context, 'list(...values)', list.list)
+    defineBuiltin(context, 'length(xs)', list.length)
+    defineBuiltin(context, 'map(fun, xs)', list.map)
+    defineBuiltin(context, 'build_list(n, fun)', list.build_list)
+    defineBuiltin(context, 'for_each(fun, xs)', list.for_each)
+    defineBuiltin(context, 'list_to_string(xs)', list.list_to_string)
+    defineBuiltin(context, 'reverse(xs)', list.reverse)
+    defineBuiltin(context, 'append(xs, ys)', list.append)
+    defineBuiltin(context, 'member(val, xs)', list.member)
+    defineBuiltin(context, 'remove(val, xs)', list.remove)
+    defineBuiltin(context, 'remove_all(val, xs)', list.remove_all)
+    defineBuiltin(context, 'filter(pred, xs)', list.filter)
+    defineBuiltin(context, 'enum_list(start, end)', list.enum_list)
+    defineBuiltin(context, 'list_ref(xs, n)', list.list_ref)
+    defineBuiltin(context, 'accumulate(fun, initial, xs)', list.accumulate)
+    defineBuiltin(context, 'equal(value1, value2)', list.equal)
+    defineBuiltin(context, 'draw_list(xs)', visualiseList)
   }
 
   if (context.chapter >= 3) {
-    defineSymbol(context, 'set_head', list.set_head)
-    defineSymbol(context, 'set_tail', list.set_tail)
-    defineSymbol(context, 'array_length', misc.array_length)
-    defineSymbol(context, 'is_array', misc.is_array)
+    defineBuiltin(context, 'set_head(xs, val)', list.set_head)
+    defineBuiltin(context, 'set_tail(xs, val)', list.set_tail)
+    defineBuiltin(context, 'array_length(arr)', misc.array_length)
+    defineBuiltin(context, 'is_array(val)', misc.is_array)
   }
 
   if (context.chapter >= 4) {
-    defineSymbol(context, 'stringify', JSON.stringify)
-    defineSymbol(context, 'parse', parser.parse)
-    defineSymbol(
+    defineBuiltin(context, 'parse(program_string)', parser.parse)
+    defineBuiltin(
       context,
-      'apply_in_underlying_javascript',
+      'apply_in_underlying_javascript(fun, args)',
       // tslint:disable-next-line:ban-types
-      (fun: Function, args: Value): Value => fun.apply(fun, list_to_vector(args))
+      (fun: Function, args: Value) => fun.apply(fun, list_to_vector(args))
     )
   }
 
   if (context.chapter >= 100) {
-    defineSymbol(context, 'is_object', misc.is_object)
+    defineBuiltin(context, 'is_object(val)', misc.is_object)
   }
 
   if (context.chapter >= Infinity) {
     // previously week 4
-    defineSymbol(context, 'alert', alert)
+    defineBuiltin(context, 'alert(val)', alert)
     // tslint:disable-next-line:ban-types
-    defineSymbol(context, 'timed', (f: Function) =>
+    defineBuiltin(context, 'timed(fun)', (f: Function) =>
       misc.timed(context, f, context.externalContext, externalBuiltIns.display)
     )
     // previously week 5
-    defineSymbol(context, 'assoc', list.assoc)
+    defineBuiltin(context, 'assoc(val, xs)', list.assoc)
     // previously week 6
   }
 }
@@ -172,7 +172,7 @@ export const importBuiltins = (context: Context, externalBuiltIns: CustomBuiltIn
 const defaultBuiltIns: CustomBuiltIns = {
   display: misc.display,
   // See issue #5
-  prompt: (v: Value, e: any) => toString(v),
+  prompt: misc.display,
   // See issue #11
   alert: misc.display,
   visualiseList: (v: Value) => {
diff --git a/src/index.ts b/src/index.ts
index 5f1b4707..26c2d142 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,4 @@
 import createContext from './createContext'
-import { toString } from './interop'
 import { evaluate } from './interpreter'
 import { InterruptedError } from './interpreter-errors'
 import { parse } from './parser'
@@ -62,4 +61,4 @@ export function interrupt(context: Context) {
   context.errors.push(new InterruptedError(context.runtime.nodes[0]))
 }
 
-export { createContext, toString, Context, Result }
+export { createContext, Context, Result }
diff --git a/src/interop.ts b/src/interop.ts
index 2b2f8332..0e6336d8 100644
--- a/src/interop.ts
+++ b/src/interop.ts
@@ -1,5 +1,4 @@
 import { generate } from 'astring'
-import getParameterNames = require('get-parameter-names')
 
 import { MAX_LIST_DISPLAY_LENGTH } from './constants'
 import { apply } from './interpreter'
@@ -25,47 +24,132 @@ export const closureToJS = (value: Value, context: Context, klass: string) => {
       DummyClass.prototype.constructor = DummyClass
     }
   })
-  DummyClass.toString = () => toString(value)
+  DummyClass.toString = () => stringify(value)
   DummyClass.call = (thisArg: Value, ...args: Value[]): any => {
     return DummyClass.apply(thisArg, args)
   }
   return DummyClass
 }
 
-const arrayToString = (value: Value[], length: number) => {
-  // Normal Array
-  if (value.length > 2 || value.length === 1) {
-    return `[${value.map(v => toString(v, length + 1)).join(', ')}]`
-  } else if (value.length === 0) {
-    return '[]'
+function makeIndent(indent: number | string): string {
+  if (typeof indent === 'number') {
+    if (indent > 10) {
+      indent = 10
+    }
+    return ' '.repeat(indent)
   } else {
-    return `[${toString(value[0], length + 1)}, ${toString(value[1], length + 1)}]`
+    if (indent.length > 10) {
+      indent = indent.substring(0, 10)
+    }
+    return indent
   }
 }
 
-export const toString = (value: Value, length = 0): string => {
-  if (value instanceof Closure) {
-    return generate(value.originalNode)
-  } else if (Array.isArray(value)) {
-    if (length > MAX_LIST_DISPLAY_LENGTH) {
-      return '...<truncated>'
+function indentify(indent: string, s: string): string {
+  return s
+    .split('\n')
+    .map(v => indent + v)
+    .join('\n')
+}
+
+export const stringify = (
+  value: Value,
+  indent: number | string = 2,
+  splitlineThreshold = 80
+): string => {
+  // Used to check if there are any cyclic structures
+  const ancestors = new Set()
+
+  // Precompute useful strings
+  const indentString = makeIndent(indent)
+  const arrPrefix = '[' + indentString.substring(1)
+  const objPrefix = '{' + indentString.substring(1)
+  const arrSuffix = indentString.substring(0, indentString.length - 1) + ']'
+  const objSuffix = indentString.substring(0, indentString.length - 1) + '}'
+
+  // Util functions
+
+  // Determines if the array/object containing these (stringified) values
+  // should be multiline and indented or oneline
+  const shouldMultiline = (valueStrs: string[]) =>
+    indentString !== '' &&
+    (valueStrs.join(', ').length > splitlineThreshold || valueStrs.some(s => s.includes('\n')))
+
+  // Stringify functions
+  // The real one is stringifyValue
+
+  const stringifyArray = (xs: Value[], indentLevel: number) => {
+    ancestors.add(xs)
+    const valueStrs = xs.map(x => stringifyValue(x, 0))
+    ancestors.delete(xs)
+
+    if (shouldMultiline(valueStrs)) {
+      if (xs.length === 2) {
+        // It's (probably) a source list
+        // Don't increase indent on second element
+        // so long lists don't look like crap
+        return `${arrPrefix}${indentify(
+          indentString.repeat(indentLevel + 1),
+          valueStrs[0]
+        ).substring(indentString.length)},
+${indentify(indentString.repeat(indentLevel), valueStrs[1])}${arrSuffix}`
+      } else {
+        // A regular array,
+        // indent second element onwards to match with first element
+        return `${arrPrefix}${indentify(
+          indentString.repeat(indentLevel + 1),
+          valueStrs.join(',\n')
+        ).substring(indentString.length)}${arrSuffix}`
+      }
     } else {
-      return arrayToString(value, length)
+      return `[${valueStrs.join(', ')}]`
     }
-  } else if (typeof value === 'string') {
-    return `"${value}"`
-  } else if (typeof value === 'undefined') {
-    return 'undefined'
-  } else if (typeof value === 'function') {
-    if (value.__SOURCE__) {
-      return `function ${value.__SOURCE__} {\n\t[implementation hidden]\n}`
+  }
+
+  const stringifyObject = (obj: object, indentLevel: number) => {
+    ancestors.add(obj)
+    const valueStrs = Object.entries(obj).map(entry => {
+      const keyStr = stringifyValue(entry[0], 0)
+      const valStr = stringifyValue(entry[1], 0)
+      if (valStr.includes('\n')) {
+        return keyStr + ':\n' + indentify(indentString, valStr)
+      } else {
+        return keyStr + ': ' + valStr
+      }
+    })
+    ancestors.delete(obj)
+
+    if (shouldMultiline(valueStrs)) {
+      return `${objPrefix}${indentify(
+        indentString.repeat(indentLevel + 1),
+        valueStrs.join(',\n')
+      ).substring(indentString.length)}${objSuffix}`
     } else {
-      const params = getParameterNames(value).join(', ')
-      return `function ${value.name}(${params}) {\n\t[implementation hidden]\n}`
+      return `{${valueStrs.join(', ')}}`
+    }
+  }
+
+  const stringifyValue = (v: Value, indentLevel: number = 0): string => {
+    if (v === null) {
+      return 'null'
+    } else if (v === undefined) {
+      return 'undefined'
+    } else if (ancestors.has(v)) {
+      return '...<circular>'
+    } else if (v instanceof Closure) {
+      return generate(v.originalNode)
+    } else if (typeof v === 'string') {
+      return JSON.stringify(v)
+    } else if (typeof v !== 'object') {
+      return v.toString()
+    } else if (ancestors.size > MAX_LIST_DISPLAY_LENGTH) {
+      return '...<truncated>'
+    } else if (Array.isArray(v)) {
+      return stringifyArray(v, indentLevel)
+    } else {
+      return stringifyObject(v, indentLevel)
     }
-  } else if (value === null) {
-    return 'null'
-  } else {
-    return value.toString()
   }
+
+  return stringifyValue(value, 0)
 }
diff --git a/src/interpreter-errors.ts b/src/interpreter-errors.ts
index 6bac5e1d..fdca610e 100644
--- a/src/interpreter-errors.ts
+++ b/src/interpreter-errors.ts
@@ -3,7 +3,7 @@ import { baseGenerator, generate } from 'astring'
 import * as es from 'estree'
 
 import { UNKNOWN_LOCATION } from './constants'
-import { toString } from './interop'
+import { stringify } from './interop'
 import { ErrorSeverity, ErrorType, SourceError, Value } from './types'
 
 export class RuntimeSourceError implements SourceError {
@@ -69,7 +69,7 @@ export class MaximumStackLimitExceeded extends RuntimeSourceError {
     CallExpression(node: any, state: any) {
       state.write(node.callee.name)
       state.write('(')
-      const argsRepr = node.arguments.map((args: any) => toString(args.value))
+      const argsRepr = node.arguments.map((arg: any) => stringify(arg.value))
       state.write(argsRepr.join(', '))
       state.write(')')
     }
@@ -99,7 +99,7 @@ export class CallingNonFunctionValue extends RuntimeSourceError {
   }
 
   public explain() {
-    return `Calling non-function value ${toString(this.callee)}`
+    return `Calling non-function value ${stringify(this.callee)}`
   }
 
   public elaborate() {
diff --git a/src/interpreter.ts b/src/interpreter.ts
index 4e424fc9..74014d70 100644
--- a/src/interpreter.ts
+++ b/src/interpreter.ts
@@ -2,7 +2,6 @@
 /* tslint:disable: object-literal-shorthand*/
 import * as es from 'estree'
 import * as constants from './constants'
-import { toString } from './interop'
 import * as errors from './interpreter-errors'
 import { Closure, Context, Environment, ErrorSeverity, Frame, SourceError, Value } from './types'
 import { createNode } from './utils/node'
@@ -292,8 +291,8 @@ export const evaluators: { [nodeType: string]: Evaluator<es.Node> } = {
     }
   },
   BinaryExpression: function*(node: es.BinaryExpression, context: Context) {
-    let left = yield* evaluate(node.left, context)
-    let right = yield* evaluate(node.right, context)
+    const left = yield* evaluate(node.left, context)
+    const right = yield* evaluate(node.right, context)
 
     const error = rttc.checkBinaryExpression(context, node.operator, left, right)
     if (error) {
@@ -303,16 +302,7 @@ export const evaluators: { [nodeType: string]: Evaluator<es.Node> } = {
     let result
     switch (node.operator) {
       case '+':
-        {
-          const isLeftString = typeof left === 'string'
-          const isRightString = typeof right === 'string'
-          if (isLeftString && !isRightString) {
-            right = toString(right)
-          } else if (isRightString && !isLeftString) {
-            left = toString(left)
-          }
-          result = left + right
-        }
+        result = left + right
         break
       case '-':
         result = left - right
diff --git a/src/stdlib/list.ts b/src/stdlib/list.ts
index f055e451..6062611e 100644
--- a/src/stdlib/list.ts
+++ b/src/stdlib/list.ts
@@ -1,14 +1,6 @@
-import { toString } from '../interop'
+import { stringify } from '../interop'
 import { Value } from '../types'
 
-declare global {
-  // tslint:disable-next-line:interface-name
-  interface Function {
-    __SOURCE__?: string
-  }
-}
-
-// tslint:disable
 // list.js: Supporting lists in the Scheme style, using pairs made
 //          up of two-element JavaScript array (vector)
 // Author: Martin Henz
@@ -25,21 +17,18 @@ function array_test(x: Value) {
     return Array.isArray(x)
   }
 }
-array_test.__SOURCE__ = 'array_test(x)'
 
 // pair constructs a pair using a two-element array
 // LOW-LEVEL FUNCTION, NOT SOURCE
 export function pair(x: Value, xs: Value) {
   return [x, xs]
 }
-pair.__SOURCE__ = 'pair(x, xs)'
 
 // is_pair returns true iff arg is a two-element array
 // LOW-LEVEL FUNCTION, NOT SOURCE
 export function is_pair(x: Value) {
   return array_test(x) && x.length === 2
 }
-is_pair.__SOURCE__ = 'is_pair(x)'
 
 // head returns the first component of the given pair,
 // throws an exception if the argument is not a pair
@@ -48,10 +37,9 @@ export function head(xs: List) {
   if (is_pair(xs)) {
     return xs[0]
   } else {
-    throw new Error('head(xs) expects a pair as ' + 'argument xs, but encountered ' + toString(xs))
+    throw new Error('head(xs) expects a pair as ' + 'argument xs, but encountered ' + stringify(xs))
   }
 }
-head.__SOURCE__ = 'head(xs)'
 
 // tail returns the second component of the given pair
 // throws an exception if the argument is not a pair
@@ -60,17 +48,15 @@ export function tail(xs: List) {
   if (is_pair(xs)) {
     return xs[1]
   } else {
-    throw new Error('tail(xs) expects a pair as ' + 'argument xs, but encountered ' + toString(xs))
+    throw new Error('tail(xs) expects a pair as ' + 'argument xs, but encountered ' + stringify(xs))
   }
 }
-tail.__SOURCE__ = 'tail(xs)'
 
 // is_null returns true if arg is exactly null
 // LOW-LEVEL FUNCTION, NOT SOURCE
 export function is_null(xs: List) {
   return xs === null
 }
-is_null.__SOURCE__ = 'is_null(xs)'
 
 // is_list recurses down the list and checks that it ends with the empty list []
 // does not throw Value exceptions
@@ -84,18 +70,16 @@ export function is_list(xs: List) {
     }
   }
 }
-is_list.__SOURCE__ = 'is_list(xs)'
 
 // list makes a list out of its arguments
 // LOW-LEVEL FUNCTION, NOT SOURCE
 export function list() {
-  let the_list = null
+  let theList = null
   for (let i = arguments.length - 1; i >= 0; i--) {
-    the_list = pair(arguments[i], the_list)
+    theList = pair(arguments[i], theList)
   }
-  return the_list
+  return theList
 }
-list.__SOURCE__ = 'list(x, y, ...)'
 
 // list_to_vector returns vector that contains the elements of the argument list
 // in the given order.
@@ -109,7 +93,6 @@ export function list_to_vector(lst: List) {
   }
   return vector
 }
-list_to_vector.__SOURCE__ = 'list_to_vector(xs)'
 
 // vector_to_list returns a list that contains the elements of the argument vector
 // in the given order.
@@ -122,7 +105,6 @@ export function vector_to_list(vector: Value[]) {
   }
   return result
 }
-vector_to_list.__SOURCE__ = 'vector_to_list(vs)'
 
 // returns the length of a given argument list
 // throws an exception if the argument is not a list
@@ -134,7 +116,6 @@ export function length(xs: List) {
   }
   return i
 }
-length.__SOURCE__ = 'length(xs)'
 
 // map applies first arg f to the elements of the second argument,
 // assumed to be a list.
@@ -143,26 +124,27 @@ length.__SOURCE__ = 'length(xs)'
 // map throws an exception if the second argument is not a list,
 // and if the second argument is a non-empty list and the first
 // argument is not a function.
+// tslint:disable-next-line:ban-types
 export function map(f: Function, xs: List): List | null {
   return is_null(xs) ? null : pair(f(head(xs)), map(f, tail(xs)))
 }
-map.__SOURCE__ = 'map(f, xs)'
 
 // build_list takes a non-negative integer n as first argument,
 // and a function fun as second argument.
 // build_list returns a list of n elements, that results from
 // applying fun to the numbers from 0 to n-1.
+// tslint:disable-next-line:ban-types
 export function build_list(n: number, fun: Function): List | null {
-  function build(i: number, fun: Function, already_built: List | null): List | null {
+  // tslint:disable-next-line:ban-types
+  function build(i: number, alreadyBuilt: List | null): List | null {
     if (i < 0) {
-      return already_built
+      return alreadyBuilt
     } else {
-      return build(i - 1, fun, pair(fun(i), already_built))
+      return build(i - 1, pair(fun(i), alreadyBuilt))
     }
   }
-  return build(n - 1, fun, null)
+  return build(n - 1, null)
 }
-build_list.__SOURCE__ = 'build_list(n, fun)'
 
 // for_each applies first arg fun to the elements of the list passed as
 // second argument. fun is applied element-by-element:
@@ -171,6 +153,7 @@ build_list.__SOURCE__ = 'build_list(n, fun)'
 // for_each throws an exception if the second argument is not a list,
 // and if the second argument is a non-empty list and the
 // first argument is not a function.
+// tslint:disable-next-line:ban-types
 export function for_each(fun: Function, xs: List) {
   if (!is_list(xs)) {
     throw new Error('for_each expects a list as argument xs, but ' + 'encountered ' + xs)
@@ -180,15 +163,13 @@ export function for_each(fun: Function, xs: List) {
   }
   return true
 }
-for_each.__SOURCE__ = 'for_each(fun, xs)'
 
 // list_to_string returns a string that represents the argument list.
 // It applies itself recursively on the elements of the given list.
-// When it encounters a non-list, it applies toString to it.
+// When it encounters a non-list, it applies stringify to it.
 export function list_to_string(l: List): string {
-  return toString(l)
+  return stringify(l)
 }
-list_to_string.__SOURCE__ = 'list_to_string(xs)'
 
 // reverse reverses the argument list
 // reverse throws an exception if the argument is not a list.
@@ -202,7 +183,6 @@ export function reverse(xs: List) {
   }
   return result
 }
-reverse.__SOURCE__ = 'reverse(xs)'
 
 // append first argument list and second argument list.
 // In the result, the [] at the end of the first argument list
@@ -215,7 +195,6 @@ export function append(xs: List, ys: List): List {
     return pair(head(xs), append(tail(xs), ys))
   }
 }
-append.__SOURCE__ = 'append(xs, ys)'
 
 // member looks for a given first-argument element in a given
 // second argument list. It returns the first postfix sublist
@@ -229,7 +208,6 @@ export function member(v: Value, xs: List) {
   }
   return null
 }
-member.__SOURCE__ = 'member(x, xs)'
 
 // removes the first occurrence of a given first-argument element
 // in a given second-argument list. Returns the original list
@@ -245,7 +223,6 @@ export function remove(v: Value, xs: List): List | null {
     }
   }
 }
-remove.__SOURCE__ = 'remove(x, xs)'
 
 // Similar to remove. But removes all instances of v instead of just the first
 export function remove_all(v: Value, xs: List): List | null {
@@ -259,7 +236,6 @@ export function remove_all(v: Value, xs: List): List | null {
     }
   }
 }
-remove_all.__SOURCE__ = 'remove_all(x, xs)'
 // for backwards-compatibility
 export const removeAll = remove_all
 
@@ -272,7 +248,6 @@ export function equal(item1: Value, item2: Value): boolean {
     return item1 === item2
   }
 }
-equal.__SOURCE__ = 'equal(x, y)'
 
 // assoc treats the second argument as an association,
 // a list of (index,value) pairs.
@@ -289,10 +264,10 @@ export function assoc(v: Value, xs: List): boolean {
     return assoc(v, tail(xs))
   }
 }
-assoc.__SOURCE__ = 'assoc(v, xs)'
 
 // filter returns the sublist of elements of given list xs
 // for which the given predicate function returns true.
+// tslint:disable-next-line:ban-types
 export function filter(pred: Function, xs: List): List {
   if (is_null(xs)) {
     return xs
@@ -304,7 +279,6 @@ export function filter(pred: Function, xs: List): List {
     }
   }
 }
-filter.__SOURCE__ = 'filter(pred, xs)'
 
 // enumerates numbers starting from start,
 // using a step size of 1, until the number
@@ -316,7 +290,6 @@ export function enum_list(start: number, end: number): List | null {
     return pair(start, enum_list(start + 1, end))
   }
 }
-enum_list.__SOURCE__ = 'enum_list(start, end)'
 
 // Returns the item in list lst at index n (the first item is at position 0)
 export function list_ref(xs: List, n: number) {
@@ -331,7 +304,6 @@ export function list_ref(xs: List, n: number) {
   }
   return head(xs)
 }
-list_ref.__SOURCE__ = 'list_ref(xs, n)'
 
 // accumulate applies given operation op to elements of a list
 // in a right-to-left order, first apply op to the last element
@@ -349,7 +321,6 @@ export function accumulate<T>(op: (value: Value, acc: T) => T, initial: T, seque
     return op(head(sequence), accumulate(op, initial, tail(sequence)))
   }
 }
-accumulate.__SOURCE__ = 'accumulate(op, initial, xs)'
 
 // set_head(xs,x) changes the head of given pair xs to be x,
 // throws an exception if the argument is not a pair
@@ -361,11 +332,10 @@ export function set_head(xs: List, x: Value) {
     return undefined
   } else {
     throw new Error(
-      'set_head(xs,x) expects a pair as ' + 'argument xs, but encountered ' + toString(xs)
+      'set_head(xs,x) expects a pair as ' + 'argument xs, but encountered ' + stringify(xs)
     )
   }
 }
-set_head.__SOURCE__ = 'set_head(xs, x)'
 
 // set_tail(xs,x) changes the tail of given pair xs to be x,
 // throws an exception if the argument is not a pair
@@ -377,9 +347,7 @@ export function set_tail(xs: List, x: Value) {
     return undefined
   } else {
     throw new Error(
-      'set_tail(xs,x) expects a pair as ' + 'argument xs, but encountered ' + toString(xs)
+      'set_tail(xs,x) expects a pair as ' + 'argument xs, but encountered ' + stringify(xs)
     )
   }
 }
-set_tail.__SOURCE__ = 'set_tail(xs, x)'
-// tslint:enable
diff --git a/src/stdlib/misc.ts b/src/stdlib/misc.ts
index 472f8e9b..751684de 100644
--- a/src/stdlib/misc.ts
+++ b/src/stdlib/misc.ts
@@ -1,5 +1,5 @@
 /* tslint:disable: ban-types*/
-import { toString } from '../interop'
+import { stringify } from '../interop'
 import { Context, Value } from '../types'
 
 /**
@@ -10,18 +10,16 @@ import { Context, Value } from '../types'
  *   any information required for external use (optional).
  */
 export function display(value: Value, externalContext: any) {
-  const output = toString(value)
+  const output = stringify(value)
   // tslint:disable-next-line:no-console
   console.log(output)
   return value
 }
-display.__SOURCE__ = 'display(a)'
 
 export function error_message(value: Value) {
-  const output = toString(value)
+  const output = stringify(value)
   throw new Error(output)
 }
-error_message.__SOURCE__ = 'error(a)'
 
 export function timed(
   context: Context,
@@ -37,57 +35,46 @@ export function timed(
     return result
   }
 }
-timed.__SOURCE__ = 'timed(f)'
 
 export function is_number(v: Value) {
   return typeof v === 'number'
 }
-is_number.__SOURCE__ = 'is_number(v)'
 
 export function is_undefined(xs: Value) {
   return typeof xs === 'undefined'
 }
-is_undefined.__SOURCE__ = 'is_undefined(xs)'
 
 export function is_string(xs: Value) {
   return typeof xs === 'string'
 }
-is_string.__SOURCE__ = 'is_string(xs)'
 
 export function is_boolean(xs: Value) {
   return typeof xs === 'boolean'
 }
-is_boolean.__SOURCE__ = 'is_boolean(xs)'
 
 export function is_object(xs: Value) {
   return typeof xs === 'object' || is_function(xs)
 }
-is_object.__SOURCE__ = 'is_object(xs)'
 
 export function is_function(xs: Value) {
   return typeof xs === 'function'
 }
-is_function.__SOURCE__ = 'is_function(xs)'
 
 export function is_NaN(x: Value) {
   return is_number(x) && isNaN(x)
 }
-is_NaN.__SOURCE__ = 'is_NaN(x)'
 
 export function has_own_property(obj: Value, p: Value) {
   return obj.hasOwnProperty(p)
 }
-has_own_property.__SOURCE__ = 'has_own_property(obj, p)'
 
 export function is_array(a: Value) {
   return a instanceof Array
 }
-is_array.__SOURCE__ = 'is_array(a)'
 
 export function array_length(xs: Value[]) {
   return xs.length
 }
-array_length.__SOURCE__ = 'array_length(xs)'
 
 /**
  * Source version of parseInt. Both arguments are required.
@@ -113,9 +100,7 @@ export function parse_int(str: string, radix: number) {
     )
   }
 }
-parse_int.__SOURCE__ = 'parse_int(s, i)'
 
 export function runtime() {
   return new Date().getTime()
 }
-runtime.__SOURCE__ = 'runtime()'
diff --git a/src/stdlib/parser.ts b/src/stdlib/parser.ts
index 8d9804d1..81d3d05d 100644
--- a/src/stdlib/parser.ts
+++ b/src/stdlib/parser.ts
@@ -6,13 +6,6 @@ import { parse as sourceParse } from '../parser'
 import { Value } from '../types'
 import { vector_to_list } from './list'
 
-declare global {
-  // tslint:disable-next-line:interface-name
-  interface Function {
-    __SOURCE__?: string
-  }
-}
-
 class ParseError extends Error {
   constructor(message: string) {
     super(message)
@@ -417,4 +410,3 @@ export function parse(x: string): Value {
     throw new ParseError('Invalid parse')
   }
 }
-parse.__SOURCE__ = 'parse(program_string)'
diff --git a/src/types.ts b/src/types.ts
index e8150535..0855e35b 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -3,7 +3,7 @@
 import { SourceLocation } from 'acorn'
 import * as es from 'estree'
 
-import { closureToJS } from './interop'
+import { closureToJS, stringify } from './interop'
 
 /**
  * Defines functions that act as built-ins, but might rely on
@@ -183,6 +183,10 @@ export class Closure extends Callable {
     const funJS = closureToJS(this, context, this.functionName)
     this.fun = funJS
   }
+
+  public toString(): string {
+    return stringify(this)
+  }
 }
 
 export interface Error {


Test patch:
diff --git a/src/__tests__/__snapshots__/index.ts.snap b/src/__tests__/__snapshots__/index.ts.snap
index 778112b7..58937da3 100644
--- a/src/__tests__/__snapshots__/index.ts.snap
+++ b/src/__tests__/__snapshots__/index.ts.snap
@@ -1,18 +1,16 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`__SOURCE__ functions now uses Source toString instead of native when +ed with another string 1`] = `
+exports[`Allow display to return value it is displaying 1`] = `
 Object {
   "status": "finished",
-  "value": "function pair(x, xs) {
-	[implementation hidden]
-}123",
+  "value": 50,
 }
 `;
 
-exports[`Allow display to return value it is displaying 1`] = `
+exports[`Arrays toString matches up with JS 1`] = `
 Object {
   "status": "finished",
-  "value": 50,
+  "value": "1,2",
 }
 `;
 
@@ -30,6 +28,24 @@ exports[`Arrow function infinite recursion with list args represents CallExpress
   f([1, [2, null]])..  f([1, [2, null]])..  f([1, [2, null]]).."
 `;
 
+exports[`Builtins hide their implementation 1`] = `
+Object {
+  "status": "finished",
+  "value": "function pair(left, right) {
+	[implementation hidden]
+}",
+}
+`;
+
+exports[`Builtins hide their implementation 2`] = `
+Object {
+  "status": "finished",
+  "value": "function pair(left, right) {
+	[implementation hidden]
+}",
+}
+`;
+
 exports[`Cannot overwrite consts even when assignment is allowed 1`] = `"Line 4: Cannot assign new value to constant constant"`;
 
 exports[`Deep object assignment and retrieval 1`] = `
@@ -58,17 +74,10 @@ exports[`Function infinite recursion with list args represents CallExpression we
   f([1, [2, null]])..  f([1, [2, null]])..  f([1, [2, null]]).."
 `;
 
-exports[`Multi-dimensional arrays display properly 1`] = `
+exports[`Objects toString matches up with JS 1`] = `
 Object {
   "status": "finished",
-  "value": "[1, function a() {}, 3, [() => 1, 5]]",
-}
-`;
-
-exports[`Multi-dimensional arrays display properly 2`] = `
-Object {
-  "status": "finished",
-  "value": "[1, function a() {}, 3, [() => 1, 5]]",
+  "value": "[object Object]",
 }
 `;
 
@@ -130,15 +139,24 @@ Object {
 }
 `;
 
-exports[`list now uses Source toString instead of native when +ed with another string 1`] = `
+exports[`functions toString (mostly) matches up with JS 1`] = `
 Object {
   "status": "finished",
-  "value": "123[4, [5, [6, null]]]",
+  "value": "a => bfunction f(x) {
+  return 5;
+}",
 }
 `;
 
 exports[`parseError for missing semicolon 1`] = `"Line 1: Missing semicolon at the end of statement"`;
 
+exports[`primitives toString matches up with JS 1`] = `
+Object {
+  "status": "finished",
+  "value": "truefalse11.5nullundefinedNaN",
+}
+`;
+
 exports[`test && shortcircuiting 1`] = `
 Object {
   "status": "finished",
diff --git a/src/__tests__/__snapshots__/interpreter-errors.ts.snap b/src/__tests__/__snapshots__/interpreter-errors.ts.snap
index df1efa27..828d57ef 100644
--- a/src/__tests__/__snapshots__/interpreter-errors.ts.snap
+++ b/src/__tests__/__snapshots__/interpreter-errors.ts.snap
@@ -229,7 +229,7 @@ Object {
 }
 `;
 
-exports[`Error when calling non function value object 2`] = `"Line 2: Calling non-function value [object Object]"`;
+exports[`Error when calling non function value object 2`] = `"Line 2: Calling non-function value {\\"a\\": 1}"`;
 
 exports[`Error when calling non function value true 1`] = `
 Object {
diff --git a/src/__tests__/__snapshots__/stringify.ts.snap b/src/__tests__/__snapshots__/stringify.ts.snap
new file mode 100644
index 00000000..6dd9719d
--- /dev/null
+++ b/src/__tests__/__snapshots__/stringify.ts.snap
@@ -0,0 +1,343 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`String representation of arrays are nice 1`] = `"[1, \\"true\\", true, () => x]"`;
+
+exports[`String representation of arrow functions are nice 1`] = `"(x, y) => z"`;
+
+exports[`String representation of big objects are nice 1`] = `
+"{ \\"a\\": 1,
+  \\"b\\": true,
+  \\"c\\": () => x,
+  \\"d\\": {\\"e\\": 5, \\"f\\": 6},
+  \\"g\\": 0,
+  \\"h\\": 0,
+  \\"i\\": 0,
+  \\"j\\": 0,
+  \\"k\\": 0,
+  \\"l\\": 0,
+  \\"m\\": 0,
+  \\"n\\": 0 }"
+`;
+
+exports[`String representation of booleans are nice 1`] = `"\\"true\\""`;
+
+exports[`String representation of builtins are nice 1`] = `
+"function pair(left, right) {
+	[implementation hidden]
+}"
+`;
+
+exports[`String representation of empty arrays are nice 1`] = `"[]"`;
+
+exports[`String representation of functions are nice 1`] = `
+"function f(x, y) {
+  return z;
+}"
+`;
+
+exports[`String representation of huge arrays are nice 1`] = `
+"[ 0,
+  1,
+  2,
+  3,
+  4,
+  5,
+  6,
+  7,
+  8,
+  9,
+  10,
+  11,
+  12,
+  13,
+  14,
+  15,
+  16,
+  17,
+  18,
+  19,
+  20,
+  21,
+  22,
+  23,
+  24,
+  25,
+  26,
+  27,
+  28,
+  29,
+  30,
+  31,
+  32,
+  33,
+  34,
+  35,
+  36,
+  37,
+  38,
+  39,
+  40,
+  41,
+  42,
+  43,
+  44,
+  45,
+  46,
+  47,
+  48,
+  49,
+  50,
+  51,
+  52,
+  53,
+  54,
+  55,
+  56,
+  57,
+  58,
+  59,
+  60,
+  61,
+  62,
+  63,
+  64,
+  65,
+  66,
+  67,
+  68,
+  69,
+  70,
+  71,
+  72,
+  73,
+  74,
+  75,
+  76,
+  77,
+  78,
+  79,
+  80,
+  81,
+  82,
+  83,
+  84,
+  85,
+  86,
+  87,
+  88,
+  89,
+  90,
+  91,
+  92,
+  93,
+  94,
+  95,
+  96,
+  97,
+  98,
+  99 ]"
+`;
+
+exports[`String representation of huge lists are nice 1`] = `
+"[ 1,
+[ 2,
+[ 3,
+[ 4,
+[ 5,
+[ 6,
+[ 7,
+[ 8,
+[ 9,
+[ 10,
+[ 11,
+[ 12,
+[ 13,
+[ 14,
+[ 15,
+[ 16,
+[ 17,
+[ 18,
+[ 19,
+[ 20,
+[ 21,
+[ 22,
+[ 23,
+[ 24,
+[ 25,
+[ 26,
+[ 27,
+[ 28,
+[ 29,
+[ 30,
+[ 31,
+[ 32,
+[ 33,
+[ 34,
+[ 35,
+[ 36,
+[ 37,
+[ 38,
+[ 39,
+[ 40,
+[ 41,
+[ 42,
+[ 43,
+[ 44,
+[ 45,
+[ 46,
+[ 47,
+[ 48,
+[ 49,
+[ 50,
+[ 51,
+[ 52,
+[ 53,
+[ 54,
+[ 55,
+[ 56,
+[ 57,
+[ 58,
+[ 59,
+[ 60,
+[ 61,
+[ 62,
+[ 63,
+[ 64,
+[ 65,
+[ 66,
+[ 67,
+[ 68,
+[ 69,
+[ 70,
+[ 71,
+[ 72,
+[ 73,
+[ 74,
+[ 75,
+[ 76,
+[ 77,
+[ 78,
+[ 79,
+[ 80,
+[ 81,
+[ 82,
+[ 83,
+[ 84,
+[ 85,
+[ 86,
+[ 87,
+[ 88,
+[ 89,
+[ 90,
+[91, [92, [93, [94, [95, [96, [97, [98, [99, [100, [101, ...<truncated>]]]]]]]]]]] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ]"
+`;
+
+exports[`String representation of lists are nice 1`] = `"[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, null]]]]]]]]]]"`;
+
+exports[`String representation of multidimensional arrays are nice 1`] = `"[1, \\"true\\", [true, () => x, [[]]]]"`;
+
+exports[`String representation of nested objects are nice 1`] = `"{\\"a\\": 1, \\"b\\": true, \\"c\\": () => x, \\"d\\": {\\"e\\": 5, \\"f\\": 6}}"`;
+
+exports[`String representation of nested objects are nice 2`] = `"{\\"o\\": ...<circular>}"`;
+
+exports[`String representation of null is nice 1`] = `"null"`;
+
+exports[`String representation of numbers are nice 1`] = `"0"`;
+
+exports[`String representation of objects are nice 1`] = `"{\\"a\\": 1, \\"b\\": true, \\"c\\": () => x}"`;
+
+exports[`String representation of strings are nice 1`] = `"\\"a string\\""`;
+
+exports[`String representation of undefined is nice 1`] = `"undefined"`;
+
+exports[`String representation with 1 space indent 1`] = `
+"[{\\"tag\\": \\"function_definition\\",
+  \\"parameters\\":
+   [{\\"tag\\": \\"name\\",
+     \\"name\\": \\"x\\",
+     \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 1}}},
+   null],
+  \\"body\\":
+   {\\"tag\\": \\"return_statement\\",
+    \\"expression\\":
+     {\\"tag\\": \\"name\\",
+      \\"name\\": \\"x\\",
+      \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}}},
+    \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}}},
+  \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 5}}},
+null]"
+`;
+
+exports[`String representation with custom indent 1`] = `
+"[... {... \\"tag\\": \\"function_definition\\",
+ ...  ... \\"parameters\\":
+ ...  ...  ... [... {... \\"tag\\": \\"name\\",
+ ...  ...  ...  ...  ... \\"name\\": \\"x\\",
+ ...  ...  ...  ...  ... \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 1}} ...},
+ ...  ...  ... null ...],
+ ...  ... \\"body\\":
+ ...  ...  ... {... \\"tag\\": \\"return_statement\\",
+ ...  ...  ...  ... \\"expression\\":
+ ...  ...  ...  ...  ... {... \\"tag\\": \\"name\\",
+ ...  ...  ...  ...  ...  ... \\"name\\": \\"x\\",
+ ...  ...  ...  ...  ...  ... \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}} ...},
+ ...  ...  ...  ... \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}} ...},
+ ...  ... \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 5}} ...},
+null ...]"
+`;
+
+exports[`String representation with default (2 space) indent 1`] = `
+"[ { \\"tag\\": \\"function_definition\\",
+    \\"parameters\\":
+      [ { \\"tag\\": \\"name\\",
+          \\"name\\": \\"x\\",
+          \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 1}} },
+      null ],
+    \\"body\\":
+      { \\"tag\\": \\"return_statement\\",
+        \\"expression\\":
+          { \\"tag\\": \\"name\\",
+            \\"name\\": \\"x\\",
+            \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}} },
+        \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}} },
+    \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 5}} },
+null ]"
+`;
+
+exports[`String representation with long custom indent gets trimmed to 10 characters 1`] = `
+"[.........{.........\\"tag\\": \\"function_definition\\",
+....................\\"parameters\\":
+..............................[.........{.........\\"tag\\": \\"name\\",
+..................................................\\"name\\": \\"x\\",
+..................................................\\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 1}}.........},
+..............................null.........],
+....................\\"body\\":
+..............................{.........\\"tag\\": \\"return_statement\\",
+........................................\\"expression\\":
+..................................................{.........\\"tag\\": \\"name\\",
+............................................................\\"name\\": \\"x\\",
+............................................................\\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}}.........},
+........................................\\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}}.........},
+....................\\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 5}}.........},
+null.........]"
+`;
+
+exports[`String representation with more than 10 space indent should trim to 10 space indent 1`] = `
+"[         {         \\"tag\\": \\"function_definition\\",
+                    \\"parameters\\":
+                              [         {         \\"tag\\": \\"name\\",
+                                                  \\"name\\": \\"x\\",
+                                                  \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 1}}         },
+                              null         ],
+                    \\"body\\":
+                              {         \\"tag\\": \\"return_statement\\",
+                                        \\"expression\\":
+                                                  {         \\"tag\\": \\"name\\",
+                                                            \\"name\\": \\"x\\",
+                                                            \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}}         },
+                                        \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}}         },
+                    \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 5}}         },
+null         ]"
+`;
+
+exports[`String representation with no indent 1`] = `"[{\\"tag\\": \\"function_definition\\", \\"parameters\\": [{\\"tag\\": \\"name\\", \\"name\\": \\"x\\", \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 1}}}, null], \\"body\\": {\\"tag\\": \\"return_statement\\", \\"expression\\": {\\"tag\\": \\"name\\", \\"name\\": \\"x\\", \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}}}, \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 3}, \\"end\\": {\\"line\\": 1, \\"column\\": 4}}}, \\"loc\\": {\\"start\\": {\\"line\\": 1, \\"column\\": 0}, \\"end\\": {\\"line\\": 1, \\"column\\": 5}}}, null]"`;
diff --git a/src/__tests__/__snapshots__/toString.ts.snap b/src/__tests__/__snapshots__/toString.ts.snap
deleted file mode 100644
index ad6f90fc..00000000
--- a/src/__tests__/__snapshots__/toString.ts.snap
+++ /dev/null
@@ -1,41 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`String representation of arrays are nice 1`] = `"[1, \\"true\\", true, () => x]"`;
-
-exports[`String representation of arrow functions are nice 1`] = `"(x, y) => z"`;
-
-exports[`String representation of booleans are nice 1`] = `"\\"true\\""`;
-
-exports[`String representation of builtins are nice 1`] = `
-"function pair(x, xs) {
-	[implementation hidden]
-}"
-`;
-
-exports[`String representation of builtins without __SOURCE__ are nice 1`] = `
-"function prompt(v) {
-	[implementation hidden]
-}"
-`;
-
-exports[`String representation of empty arrays are nice 1`] = `"[]"`;
-
-exports[`String representation of functions are nice 1`] = `
-"function f(x, y) {
-  return z;
-}"
-`;
-
-exports[`String representation of huge lists are nice 1`] = `"[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, [46, [47, [48, [49, [50, [51, [52, [53, [54, [55, [56, [57, [58, [59, [60, [61, [62, [63, [64, [65, [66, [67, [68, [69, [70, [71, [72, [73, [74, [75, [76, [77, [78, [79, [80, [81, [82, [83, [84, [85, [86, [87, [88, [89, [90, [91, [92, [93, [94, [95, [96, [97, [98, [99, [100, [101, ...<truncated>]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"`;
-
-exports[`String representation of lists are nice 1`] = `"[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, null]]]]]]]]]]"`;
-
-exports[`String representation of null is nice 1`] = `"null"`;
-
-exports[`String representation of numbers are nice 1`] = `"0"`;
-
-exports[`String representation of objects are nice 1`] = `"[object Object]"`;
-
-exports[`String representation of strings are nice 1`] = `"\\"a string\\""`;
-
-exports[`String representation of undefined is nice 1`] = `"undefined"`;
diff --git a/src/__tests__/index.ts b/src/__tests__/index.ts
index c3ed2e48..9b6a65c0 100644
--- a/src/__tests__/index.ts
+++ b/src/__tests__/index.ts
@@ -1,5 +1,5 @@
 import { stripIndent } from 'common-tags'
-import { defineSymbol } from '../createContext'
+import { defineBuiltin } from '../createContext'
 import { parseError, runInContext } from '../index'
 import { mockContext } from '../mocks/context'
 import { Finished } from '../types'
@@ -26,20 +26,6 @@ test('Single string self-evaluates to itself', () => {
   })
 })
 
-test('Multi-dimensional arrays display properly', () => {
-  const code = `
-    function a() {}
-    ""+[1, a, 3, [() => 1, 5]];
-   `
-  const context = mockContext(4)
-  const promise = runInContext(code, context, { scheduler: 'preemptive' })
-  return promise.then(obj => {
-    expect(obj).toMatchSnapshot()
-    expect(obj.status).toBe('finished')
-    expect((obj as Finished).value).toBe('[1, function a() {}, 3, [() => 1, 5]]')
-  })
-})
-
 test('Allow display to return value it is displaying', () => {
   const code = '25*(display(1+1));'
   const context = mockContext()
@@ -84,19 +70,18 @@ test('Arrow function definition returns itself', () => {
   })
 })
 
-test('list now uses Source toString instead of native when +ed with another string', () => {
-  const code = '"123" + list(4, 5, 6);'
+test('Builtins hide their implementation', () => {
+  const code = 'stringify(pair);'
   const context = mockContext(2)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj).toMatchSnapshot()
     expect(obj.status).toBe('finished')
-    expect((obj as Finished).value).toBe('123[4, [5, [6, null]]]')
   })
 })
 
-test('__SOURCE__ functions now uses Source toString instead of native when +ed with another string', () => {
-  const code = ' pair + "123";'
+test('Builtins hide their implementation', () => {
+  const code = '""+pair;'
   const context = mockContext(2)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
@@ -105,6 +90,59 @@ test('__SOURCE__ functions now uses Source toString instead of native when +ed w
   })
 })
 
+test('Objects toString matches up with JS', () => {
+  const code = '"" + ({a: 1});'
+  const context = mockContext(100)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj).toMatchSnapshot()
+    expect(obj.status).toBe('finished')
+    // tslint:disable-next-line:no-eval
+    expect((obj as Finished).value).toEqual(eval(code))
+  })
+})
+
+test('Arrays toString matches up with JS', () => {
+  const code = '"" + [1, 2];'
+  const context = mockContext(3)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj).toMatchSnapshot()
+    expect(obj.status).toBe('finished')
+    // tslint:disable-next-line:no-eval
+    expect((obj as Finished).value).toEqual(eval(code))
+  })
+})
+
+test('functions toString (mostly) matches up with JS', () => {
+  const code = `
+    function f(x) {
+      return 5;
+    }
+    "" + (a=>b) + f;
+  `
+  const context = mockContext(3)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj).toMatchSnapshot()
+    expect(obj.status).toBe('finished')
+    // tslint:disable-next-line:no-eval
+    expect((obj as Finished).value.replace(/ /g, '')).toEqual(eval(code).replace(/ /g, ''))
+  })
+})
+
+test('primitives toString matches up with JS', () => {
+  const code = '"" + true + false + 1 + 1.5 + null + undefined + NaN;'
+  const context = mockContext(3)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj).toMatchSnapshot()
+    expect(obj.status).toBe('finished')
+    // tslint:disable-next-line:no-eval
+    expect((obj as Finished).value).toEqual(eval(code))
+  })
+})
+
 test('Factorial arrow function', () => {
   const code = stripIndent`
     const fac = (i) => i === 1 ? 1 : i * fac(i-1);
@@ -248,7 +286,7 @@ test('Functions passed into non-source functions remain equal', () => {
   identity(t) === t && t(1, 2, 3) === 6;
   `
   const context = mockContext(4)
-  defineSymbol(context, 'identity', (x: any) => x)
+  defineBuiltin(context, 'identity(x)', (x: any) => x)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -256,20 +294,6 @@ test('Functions passed into non-source functions remain equal', () => {
   })
 })
 
-test('Multi-dimensional arrays display properly', () => {
-  const code = `
-    function a() {}
-    ""+[1, a, 3, [() => 1, 5]];
-   `
-  const context = mockContext(4)
-  const promise = runInContext(code, context, { scheduler: 'preemptive' })
-  return promise.then(obj => {
-    expect(obj).toMatchSnapshot()
-    expect(obj.status).toBe('finished')
-    expect((obj as Finished).value).toBe('[1, function a() {}, 3, [() => 1, 5]]')
-  })
-})
-
 test('Simple object assignment and retrieval', () => {
   const code = `
     const o = {};
diff --git a/src/__tests__/toString.ts b/src/__tests__/stringify.ts
similarity index 52%
rename from src/__tests__/toString.ts
rename to src/__tests__/stringify.ts
index 5796563f..7edd44f7 100644
--- a/src/__tests__/toString.ts
+++ b/src/__tests__/stringify.ts
@@ -1,16 +1,13 @@
 import { stripIndent } from 'common-tags'
-import { defineSymbol } from '../createContext'
 import { runInContext } from '../index'
-import { toString } from '../interop'
 import { mockContext } from '../mocks/context'
 import { Finished } from '../types'
 
 test('String representation of numbers are nice', () => {
   const code = stripIndent`
-  toString(0);
+  stringify(0);
   `
   const context = mockContext()
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -20,10 +17,9 @@ test('String representation of numbers are nice', () => {
 
 test('String representation of strings are nice', () => {
   const code = stripIndent`
-  toString('a string');
+  stringify('a string');
   `
   const context = mockContext()
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -33,10 +29,9 @@ test('String representation of strings are nice', () => {
 
 test('String representation of booleans are nice', () => {
   const code = stripIndent`
-  toString('true');
+  stringify('true');
   `
   const context = mockContext()
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -49,10 +44,9 @@ test('String representation of functions are nice', () => {
   function f(x, y) {
     return z;
   }
-  toString(f);
+  stringify(f);
   `
   const context = mockContext()
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -63,10 +57,9 @@ test('String representation of functions are nice', () => {
 test('String representation of arrow functions are nice', () => {
   const code = stripIndent`
   const f = (x, y) => z;
-  toString(f);
+  stringify(f);
   `
   const context = mockContext()
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -77,10 +70,22 @@ test('String representation of arrow functions are nice', () => {
 test('String representation of arrays are nice', () => {
   const code = stripIndent`
   const xs = [1, 'true', true, () => x];
-  toString(xs);
+  stringify(xs);
+  `
+  const context = mockContext(3)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation of multidimensional arrays are nice', () => {
+  const code = stripIndent`
+  const xs = [1, 'true', [true, () => x, [[]]]];
+  stringify(xs);
   `
   const context = mockContext(3)
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -91,10 +96,9 @@ test('String representation of arrays are nice', () => {
 test('String representation of empty arrays are nice', () => {
   const code = stripIndent`
   const xs = [];
-  toString(xs);
+  stringify(xs);
   `
   const context = mockContext(3)
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -104,10 +108,9 @@ test('String representation of empty arrays are nice', () => {
 
 test('String representation of lists are nice', () => {
   const code = stripIndent`
-  toString(enum_list(1, 10));
+  stringify(enum_list(1, 10));
   `
   const context = mockContext(2)
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -117,10 +120,25 @@ test('String representation of lists are nice', () => {
 
 test('String representation of huge lists are nice', () => {
   const code = stripIndent`
-  toString(enum_list(1, 1000));
+  stringify(enum_list(1, 1000));
   `
   const context = mockContext(2)
-  defineSymbol(context, 'toString', toString)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation of huge arrays are nice', () => {
+  const code = stripIndent`
+  const arr = [];
+  for (let i = 0; i < 100; i = i + 1) {
+    arr[i] = i;
+  }
+  stringify(arr);
+  `
+  const context = mockContext(3)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -131,10 +149,9 @@ test('String representation of huge lists are nice', () => {
 test('String representation of objects are nice', () => {
   const code = stripIndent`
   const o = { a: 1, b: true, c: () => x };
-  toString(o);
+  stringify(o);
   `
   const context = mockContext(100)
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -142,12 +159,12 @@ test('String representation of objects are nice', () => {
   })
 })
 
-test('String representation of builtins are nice', () => {
+test('String representation of nested objects are nice', () => {
   const code = stripIndent`
-  toString(pair);
+  const o = { a: 1, b: true, c: () => x, d: { e: 5, f: 6 } };
+  stringify(o);
   `
-  const context = mockContext(2)
-  defineSymbol(context, 'toString', toString)
+  const context = mockContext(100)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -155,12 +172,38 @@ test('String representation of builtins are nice', () => {
   })
 })
 
-test('String representation of builtins without __SOURCE__ are nice', () => {
+test('String representation of big objects are nice', () => {
   const code = stripIndent`
-  toString(prompt);
+  const o = { a: 1, b: true, c: () => x, d: { e: 5, f: 6 }, g: 0, h: 0, i: 0, j: 0, k: 0, l: 0, m: 0, n: 0};
+  stringify(o);
   `
-  const context = mockContext()
-  defineSymbol(context, 'toString', toString)
+  const context = mockContext(100)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation of nested objects are nice', () => {
+  const code = stripIndent`
+  let o = {};
+  o.o = o;
+  stringify(o);
+  `
+  const context = mockContext(100)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation of builtins are nice', () => {
+  const code = stripIndent`
+  stringify(pair);
+  `
+  const context = mockContext(2)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -170,10 +213,9 @@ test('String representation of builtins without __SOURCE__ are nice', () => {
 
 test('String representation of null is nice', () => {
   const code = stripIndent`
-  toString(null);
+  stringify(null);
   `
   const context = mockContext(2)
-  defineSymbol(context, 'toString', toString)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
@@ -183,10 +225,81 @@ test('String representation of null is nice', () => {
 
 test('String representation of undefined is nice', () => {
   const code = stripIndent`
-  toString(undefined);
+  stringify(undefined);
   `
   const context = mockContext()
-  defineSymbol(context, 'toString', toString)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation with no indent', () => {
+  const code = stripIndent`
+  stringify(parse('x=>x;'), 0);
+  `
+  const context = mockContext(4)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation with 1 space indent', () => {
+  const code = stripIndent`
+  stringify(parse('x=>x;'), 1);
+  `
+  const context = mockContext(4)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation with default (2 space) indent', () => {
+  const code = stripIndent`
+  stringify(parse('x=>x;'));
+  `
+  const context = mockContext(4)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation with more than 10 space indent should trim to 10 space indent', () => {
+  const code = stripIndent`
+  stringify(parse('x=>x;'), 100);
+  `
+  const context = mockContext(4)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation with custom indent', () => {
+  const code = stripIndent`
+  stringify(parse('x=>x;'), ' ... ');
+  `
+  const context = mockContext(4)
+  const promise = runInContext(code, context, { scheduler: 'preemptive' })
+  return promise.then(obj => {
+    expect(obj.status).toBe('finished')
+    expect((obj as Finished).value).toMatchSnapshot()
+  })
+})
+
+test('String representation with long custom indent gets trimmed to 10 characters', () => {
+  const code = stripIndent`
+  stringify(parse('x=>x;'), '.................................');
+  `
+  const context = mockContext(4)
   const promise = runInContext(code, context, { scheduler: 'preemptive' })
   return promise.then(obj => {
     expect(obj.status).toBe('finished')
diff --git a/src/stdlib/__tests__/__snapshots__/parser.ts.snap b/src/stdlib/__tests__/__snapshots__/parser.ts.snap
index f57afcd2..73403239 100644
--- a/src/stdlib/__tests__/__snapshots__/parser.ts.snap
+++ b/src/stdlib/__tests__/__snapshots__/parser.ts.snap
@@ -3,459 +3,308 @@
 exports[`Parses arrow function assignments properly 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"constant_declaration\\",
-    \\"name\\": {
-      \\"tag\\": \\"name\\",
-      \\"name\\": \\"y\\",
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 6
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 7
-        }
-      }
-    },
-    \\"value\\": {
-      \\"tag\\": \\"function_definition\\",
-      \\"parameters\\": [
-        {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"x\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 10
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 11
-            }
-          }
-        },
-        null
-      ],
-      \\"body\\": {
-        \\"tag\\": \\"return_statement\\",
-        \\"expression\\": {
-          \\"tag\\": \\"application\\",
-          \\"operator\\": {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"+\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 18
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 19
-              }
-            }
-          },
-          \\"operands\\": [
-            {
-              \\"tag\\": \\"name\\",
+  "value": "[ { \\"tag\\": \\"constant_declaration\\",
+    \\"name\\":
+      { \\"tag\\": \\"name\\",
+        \\"name\\": \\"y\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 6 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 7 } } },
+    \\"value\\":
+      { \\"tag\\": \\"function_definition\\",
+        \\"parameters\\":
+          [ { \\"tag\\": \\"name\\",
               \\"name\\": \\"x\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 15
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 16
-                }
-              }
-            },
-            [
-              1,
-              null
-            ]
-          ],
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 15
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 20
-            }
-          }
-        },
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 15
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 20
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 10
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 20
-        }
-      }
-    },
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 21
-      }
-    }
-  },
-  null
-]",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 10 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 11 } } },
+          null ],
+        \\"body\\":
+          { \\"tag\\": \\"return_statement\\",
+            \\"expression\\":
+              { \\"tag\\": \\"application\\",
+                \\"operator\\":
+                  { \\"tag\\": \\"name\\",
+                    \\"name\\": \\"+\\",
+                    \\"loc\\":
+                      { \\"start\\":
+                          { \\"line\\": 1,
+                            \\"column\\": 18 },
+                        \\"end\\":
+                          { \\"line\\": 1,
+                            \\"column\\": 19 } } },
+                \\"operands\\":
+                  [ { \\"tag\\": \\"name\\",
+                      \\"name\\": \\"x\\",
+                      \\"loc\\":
+                        { \\"start\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 15 },
+                          \\"end\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 16 } } },
+                  [ 1,
+                  null ] ],
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 15 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 20 } } },
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 15 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 20 } } },
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 10 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 20 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 21 } } },
+null ]",
 }
 `;
 
 exports[`Parses arrow function expressions properly 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"function_definition\\",
-    \\"parameters\\": [
-      {
-        \\"tag\\": \\"name\\",
-        \\"name\\": \\"x\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 0
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 1
-          }
-        }
-      },
-      null
-    ],
-    \\"body\\": {
-      \\"tag\\": \\"return_statement\\",
-      \\"expression\\": {
-        \\"tag\\": \\"application\\",
-        \\"operator\\": {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"+\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 8
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 9
-            }
-          }
-        },
-        \\"operands\\": [
-          {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"x\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 5
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 6
-              }
-            }
-          },
-          [
-            1,
-            null
-          ]
-        ],
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 5
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 10
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 5
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 10
-        }
-      }
-    },
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 11
-      }
-    }
-  },
-  null
-]",
+  "value": "[ { \\"tag\\": \\"function_definition\\",
+    \\"parameters\\":
+      [ { \\"tag\\": \\"name\\",
+          \\"name\\": \\"x\\",
+          \\"loc\\":
+            { \\"start\\":
+                { \\"line\\": 1,
+                  \\"column\\": 0 },
+              \\"end\\":
+                { \\"line\\": 1,
+                  \\"column\\": 1 } } },
+      null ],
+    \\"body\\":
+      { \\"tag\\": \\"return_statement\\",
+        \\"expression\\":
+          { \\"tag\\": \\"application\\",
+            \\"operator\\":
+              { \\"tag\\": \\"name\\",
+                \\"name\\": \\"+\\",
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 8 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 9 } } },
+            \\"operands\\":
+              [ { \\"tag\\": \\"name\\",
+                  \\"name\\": \\"x\\",
+                  \\"loc\\":
+                    { \\"start\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 5 },
+                      \\"end\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 6 } } },
+              [ 1,
+              null ] ],
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 5 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 10 } } },
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 5 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 10 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 11 } } },
+null ]",
 }
 `;
 
 exports[`Parses assignment statements 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"assignment\\",
-    \\"name\\": {
-      \\"tag\\": \\"name\\",
-      \\"name\\": \\"x\\",
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 0
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 1
-        }
-      }
-    },
+  "value": "[ { \\"tag\\": \\"assignment\\",
+    \\"name\\":
+      { \\"tag\\": \\"name\\",
+        \\"name\\": \\"x\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 0 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 1 } } },
     \\"value\\": 5,
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 6
-      }
-    }
-  },
-  [
-    {
-      \\"tag\\": \\"assignment\\",
-      \\"name\\": {
-        \\"tag\\": \\"name\\",
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 6 } } },
+[ { \\"tag\\": \\"assignment\\",
+    \\"name\\":
+      { \\"tag\\": \\"name\\",
         \\"name\\": \\"x\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 7
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 8
-          }
-        }
-      },
-      \\"value\\": {
-        \\"tag\\": \\"name\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 7 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 8 } } },
+    \\"value\\":
+      { \\"tag\\": \\"name\\",
         \\"name\\": \\"x\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 11
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 12
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 7
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 13
-        }
-      }
-    },
-    [
-      {
-        \\"tag\\": \\"conditional_statement\\",
-        \\"predicate\\": true,
-        \\"consequent\\": {
-          \\"tag\\": \\"block\\",
-          \\"body\\": [
-            {
-              \\"tag\\": \\"assignment\\",
-              \\"name\\": {
-                \\"tag\\": \\"name\\",
-                \\"name\\": \\"x\\",
-                \\"loc\\": {
-                  \\"start\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 26
-                  },
-                  \\"end\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 27
-                  }
-                }
-              },
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 11 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 12 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 7 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 13 } } },
+[ { \\"tag\\": \\"conditional_statement\\",
+    \\"predicate\\": true,
+    \\"consequent\\":
+      { \\"tag\\": \\"block\\",
+        \\"body\\":
+          [ { \\"tag\\": \\"assignment\\",
+              \\"name\\":
+                { \\"tag\\": \\"name\\",
+                  \\"name\\": \\"x\\",
+                  \\"loc\\":
+                    { \\"start\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 26 },
+                      \\"end\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 27 } } },
               \\"value\\": 5,
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 26
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 32
-                }
-              }
-            },
-            null
-          ],
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 24
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 34
-            }
-          }
-        },
-        \\"alternative\\": {
-          \\"tag\\": \\"block\\",
-          \\"body\\": null,
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 40
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 42
-            }
-          }
-        },
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 14
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 42
-          }
-        }
-      },
-      null
-    ]
-  ]
-]",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 26 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 32 } } },
+          null ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 24 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 34 } } },
+    \\"alternative\\":
+      { \\"tag\\": \\"block\\",
+        \\"body\\": null,
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 40 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 42 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 14 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 42 } } },
+null ] ] ]",
 }
 `;
 
 exports[`Parses declaration statements 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"constant_declaration\\",
-    \\"name\\": {
-      \\"tag\\": \\"name\\",
-      \\"name\\": \\"x\\",
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 6
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 7
-        }
-      }
-    },
+  "value": "[ { \\"tag\\": \\"constant_declaration\\",
+    \\"name\\":
+      { \\"tag\\": \\"name\\",
+        \\"name\\": \\"x\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 6 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 7 } } },
     \\"value\\": 5,
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 12
-      }
-    }
-  },
-  [
-    {
-      \\"tag\\": \\"variable_declaration\\",
-      \\"name\\": {
-        \\"tag\\": \\"name\\",
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 12 } } },
+[ { \\"tag\\": \\"variable_declaration\\",
+    \\"name\\":
+      { \\"tag\\": \\"name\\",
         \\"name\\": \\"y\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 17
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 18
-          }
-        }
-      },
-      \\"value\\": {
-        \\"tag\\": \\"name\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 17 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 18 } } },
+    \\"value\\":
+      { \\"tag\\": \\"name\\",
         \\"name\\": \\"x\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 21
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 22
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 13
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 23
-        }
-      }
-    },
-    null
-  ]
-]",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 21 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 22 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 13 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 23 } } },
+null ] ]",
 }
 `;
 
@@ -469,1773 +318,1157 @@ Object {
 exports[`Parses fibonacci 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"constant_declaration\\",
-    \\"name\\": {
-      \\"tag\\": \\"name\\",
-      \\"name\\": \\"fib\\",
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 9
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 12
-        }
-      }
-    },
-    \\"value\\": {
-      \\"tag\\": \\"function_definition\\",
-      \\"parameters\\": [
-        {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"x\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 13
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 14
-            }
-          }
-        },
-        null
-      ],
-      \\"body\\": [
-        {
-          \\"tag\\": \\"return_statement\\",
-          \\"expression\\": {
-            \\"tag\\": \\"conditional_expression\\",
-            \\"predicate\\": {
-              \\"tag\\": \\"application\\",
-              \\"operator\\": {
-                \\"tag\\": \\"name\\",
-                \\"name\\": \\"<=\\",
-                \\"loc\\": {
-                  \\"start\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 29
-                  },
-                  \\"end\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 30
-                  }
-                }
-              },
-              \\"operands\\": [
-                {
-                  \\"tag\\": \\"name\\",
-                  \\"name\\": \\"x\\",
-                  \\"loc\\": {
-                    \\"start\\": {
-                      \\"line\\": 1,
-                      \\"column\\": 25
-                    },
-                    \\"end\\": {
-                      \\"line\\": 1,
-                      \\"column\\": 26
-                    }
-                  }
-                },
-                [
-                  1,
-                  null
-                ]
-              ],
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 25
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 31
-                }
-              }
-            },
-            \\"consequent\\": {
-              \\"tag\\": \\"name\\",
+  "value": "[ { \\"tag\\": \\"constant_declaration\\",
+    \\"name\\":
+      { \\"tag\\": \\"name\\",
+        \\"name\\": \\"fib\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 9 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 12 } } },
+    \\"value\\":
+      { \\"tag\\": \\"function_definition\\",
+        \\"parameters\\":
+          [ { \\"tag\\": \\"name\\",
               \\"name\\": \\"x\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 34
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 35
-                }
-              }
-            },
-            \\"alternative\\": {
-              \\"tag\\": \\"application\\",
-              \\"operator\\": {
-                \\"tag\\": \\"name\\",
-                \\"name\\": \\"+\\",
-                \\"loc\\": {
-                  \\"start\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 48
-                  },
-                  \\"end\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 49
-                  }
-                }
-              },
-              \\"operands\\": [
-                {
-                  \\"tag\\": \\"application\\",
-                  \\"operator\\": {
-                    \\"tag\\": \\"name\\",
-                    \\"name\\": \\"fib\\",
-                    \\"loc\\": {
-                      \\"start\\": {
-                        \\"line\\": 1,
-                        \\"column\\": 38
-                      },
-                      \\"end\\": {
-                        \\"line\\": 1,
-                        \\"column\\": 41
-                      }
-                    }
-                  },
-                  \\"operands\\": [
-                    {
-                      \\"tag\\": \\"application\\",
-                      \\"operator\\": {
-                        \\"tag\\": \\"name\\",
-                        \\"name\\": \\"-\\",
-                        \\"loc\\": {
-                          \\"start\\": {
-                            \\"line\\": 1,
-                            \\"column\\": 43
-                          },
-                          \\"end\\": {
-                            \\"line\\": 1,
-                            \\"column\\": 44
-                          }
-                        }
-                      },
-                      \\"operands\\": [
-                        {
-                          \\"tag\\": \\"name\\",
-                          \\"name\\": \\"x\\",
-                          \\"loc\\": {
-                            \\"start\\": {
-                              \\"line\\": 1,
-                              \\"column\\": 42
-                            },
-                            \\"end\\": {
-                              \\"line\\": 1,
-                              \\"column\\": 43
-                            }
-                          }
-                        },
-                        [
-                          1,
-                          null
-                        ]
-                      ],
-                      \\"loc\\": {
-                        \\"start\\": {
-                          \\"line\\": 1,
-                          \\"column\\": 42
-                        },
-                        \\"end\\": {
-                          \\"line\\": 1,
-                          \\"column\\": 45
-                        }
-                      }
-                    },
-                    null
-                  ],
-                  \\"loc\\": {
-                    \\"start\\": {
-                      \\"line\\": 1,
-                      \\"column\\": 38
-                    },
-                    \\"end\\": {
-                      \\"line\\": 1,
-                      \\"column\\": 46
-                    }
-                  }
-                },
-                [
-                  {
-                    \\"tag\\": \\"application\\",
-                    \\"operator\\": {
-                      \\"tag\\": \\"name\\",
-                      \\"name\\": \\"fib\\",
-                      \\"loc\\": {
-                        \\"start\\": {
-                          \\"line\\": 1,
-                          \\"column\\": 49
-                        },
-                        \\"end\\": {
-                          \\"line\\": 1,
-                          \\"column\\": 52
-                        }
-                      }
-                    },
-                    \\"operands\\": [
-                      {
-                        \\"tag\\": \\"application\\",
-                        \\"operator\\": {
-                          \\"tag\\": \\"name\\",
-                          \\"name\\": \\"-\\",
-                          \\"loc\\": {
-                            \\"start\\": {
-                              \\"line\\": 1,
-                              \\"column\\": 54
-                            },
-                            \\"end\\": {
-                              \\"line\\": 1,
-                              \\"column\\": 55
-                            }
-                          }
-                        },
-                        \\"operands\\": [
-                          {
-                            \\"tag\\": \\"name\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 13 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 14 } } },
+          null ],
+        \\"body\\":
+          [ { \\"tag\\": \\"return_statement\\",
+              \\"expression\\":
+                { \\"tag\\": \\"conditional_expression\\",
+                  \\"predicate\\":
+                    { \\"tag\\": \\"application\\",
+                      \\"operator\\":
+                        { \\"tag\\": \\"name\\",
+                          \\"name\\": \\"<=\\",
+                          \\"loc\\":
+                            { \\"start\\":
+                                { \\"line\\": 1,
+                                  \\"column\\": 29 },
+                              \\"end\\":
+                                { \\"line\\": 1,
+                                  \\"column\\": 30 } } },
+                      \\"operands\\":
+                        [ { \\"tag\\": \\"name\\",
                             \\"name\\": \\"x\\",
-                            \\"loc\\": {
-                              \\"start\\": {
-                                \\"line\\": 1,
-                                \\"column\\": 53
-                              },
-                              \\"end\\": {
-                                \\"line\\": 1,
-                                \\"column\\": 54
-                              }
-                            }
-                          },
-                          [
-                            2,
-                            null
-                          ]
-                        ],
-                        \\"loc\\": {
-                          \\"start\\": {
-                            \\"line\\": 1,
-                            \\"column\\": 53
-                          },
-                          \\"end\\": {
-                            \\"line\\": 1,
-                            \\"column\\": 56
-                          }
-                        }
-                      },
-                      null
-                    ],
-                    \\"loc\\": {
-                      \\"start\\": {
-                        \\"line\\": 1,
-                        \\"column\\": 49
-                      },
-                      \\"end\\": {
-                        \\"line\\": 1,
-                        \\"column\\": 57
-                      }
-                    }
-                  },
-                  null
-                ]
-              ],
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 38
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 57
-                }
-              }
-            },
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 25
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 57
-              }
-            }
-          },
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 18
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 58
-            }
-          }
-        },
-        null
-      ]
-    },
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 60
-      }
-    }
-  },
-  [
-    {
-      \\"tag\\": \\"application\\",
-      \\"operator\\": {
-        \\"tag\\": \\"name\\",
+                            \\"loc\\":
+                              { \\"start\\":
+                                  { \\"line\\": 1,
+                                    \\"column\\": 25 },
+                                \\"end\\":
+                                  { \\"line\\": 1,
+                                    \\"column\\": 26 } } },
+                        [ 1,
+                        null ] ],
+                      \\"loc\\":
+                        { \\"start\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 25 },
+                          \\"end\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 31 } } },
+                  \\"consequent\\":
+                    { \\"tag\\": \\"name\\",
+                      \\"name\\": \\"x\\",
+                      \\"loc\\":
+                        { \\"start\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 34 },
+                          \\"end\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 35 } } },
+                  \\"alternative\\":
+                    { \\"tag\\": \\"application\\",
+                      \\"operator\\":
+                        { \\"tag\\": \\"name\\",
+                          \\"name\\": \\"+\\",
+                          \\"loc\\":
+                            { \\"start\\":
+                                { \\"line\\": 1,
+                                  \\"column\\": 48 },
+                              \\"end\\":
+                                { \\"line\\": 1,
+                                  \\"column\\": 49 } } },
+                      \\"operands\\":
+                        [ { \\"tag\\": \\"application\\",
+                            \\"operator\\":
+                              { \\"tag\\": \\"name\\",
+                                \\"name\\": \\"fib\\",
+                                \\"loc\\":
+                                  { \\"start\\":
+                                      { \\"line\\": 1,
+                                        \\"column\\": 38 },
+                                    \\"end\\":
+                                      { \\"line\\": 1,
+                                        \\"column\\": 41 } } },
+                            \\"operands\\":
+                              [ { \\"tag\\": \\"application\\",
+                                  \\"operator\\":
+                                    { \\"tag\\": \\"name\\",
+                                      \\"name\\": \\"-\\",
+                                      \\"loc\\":
+                                        { \\"start\\":
+                                            { \\"line\\": 1,
+                                              \\"column\\": 43 },
+                                          \\"end\\":
+                                            { \\"line\\": 1,
+                                              \\"column\\": 44 } } },
+                                  \\"operands\\":
+                                    [ { \\"tag\\": \\"name\\",
+                                        \\"name\\": \\"x\\",
+                                        \\"loc\\":
+                                          { \\"start\\":
+                                              { \\"line\\": 1,
+                                                \\"column\\": 42 },
+                                            \\"end\\":
+                                              { \\"line\\": 1,
+                                                \\"column\\": 43 } } },
+                                    [ 1,
+                                    null ] ],
+                                  \\"loc\\":
+                                    { \\"start\\":
+                                        { \\"line\\": 1,
+                                          \\"column\\": 42 },
+                                      \\"end\\":
+                                        { \\"line\\": 1,
+                                          \\"column\\": 45 } } },
+                              null ],
+                            \\"loc\\":
+                              { \\"start\\":
+                                  { \\"line\\": 1,
+                                    \\"column\\": 38 },
+                                \\"end\\":
+                                  { \\"line\\": 1,
+                                    \\"column\\": 46 } } },
+                        [ { \\"tag\\": \\"application\\",
+                            \\"operator\\":
+                              { \\"tag\\": \\"name\\",
+                                \\"name\\": \\"fib\\",
+                                \\"loc\\":
+                                  { \\"start\\":
+                                      { \\"line\\": 1,
+                                        \\"column\\": 49 },
+                                    \\"end\\":
+                                      { \\"line\\": 1,
+                                        \\"column\\": 52 } } },
+                            \\"operands\\":
+                              [ { \\"tag\\": \\"application\\",
+                                  \\"operator\\":
+                                    { \\"tag\\": \\"name\\",
+                                      \\"name\\": \\"-\\",
+                                      \\"loc\\":
+                                        { \\"start\\":
+                                            { \\"line\\": 1,
+                                              \\"column\\": 54 },
+                                          \\"end\\":
+                                            { \\"line\\": 1,
+                                              \\"column\\": 55 } } },
+                                  \\"operands\\":
+                                    [ { \\"tag\\": \\"name\\",
+                                        \\"name\\": \\"x\\",
+                                        \\"loc\\":
+                                          { \\"start\\":
+                                              { \\"line\\": 1,
+                                                \\"column\\": 53 },
+                                            \\"end\\":
+                                              { \\"line\\": 1,
+                                                \\"column\\": 54 } } },
+                                    [ 2,
+                                    null ] ],
+                                  \\"loc\\":
+                                    { \\"start\\":
+                                        { \\"line\\": 1,
+                                          \\"column\\": 53 },
+                                      \\"end\\":
+                                        { \\"line\\": 1,
+                                          \\"column\\": 56 } } },
+                              null ],
+                            \\"loc\\":
+                              { \\"start\\":
+                                  { \\"line\\": 1,
+                                    \\"column\\": 49 },
+                                \\"end\\":
+                                  { \\"line\\": 1,
+                                    \\"column\\": 57 } } },
+                        null ] ],
+                      \\"loc\\":
+                        { \\"start\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 38 },
+                          \\"end\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 57 } } },
+                  \\"loc\\":
+                    { \\"start\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 25 },
+                      \\"end\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 57 } } },
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 18 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 58 } } },
+          null ] },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 60 } } },
+[ { \\"tag\\": \\"application\\",
+    \\"operator\\":
+      { \\"tag\\": \\"name\\",
         \\"name\\": \\"fib\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 61
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 64
-          }
-        }
-      },
-      \\"operands\\": [
-        4,
-        null
-      ],
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 61
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 68
-        }
-      }
-    },
-    null
-  ]
-]",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 61 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 64 } } },
+    \\"operands\\":
+      [ 4,
+      null ],
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 61 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 68 } } },
+null ] ]",
 }
 `;
 
 exports[`Parses function calls 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"application\\",
-    \\"operator\\": {
-      \\"tag\\": \\"name\\",
-      \\"name\\": \\"f\\",
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 0
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 1
-        }
-      }
-    },
-    \\"operands\\": [
-      {
-        \\"tag\\": \\"name\\",
-        \\"name\\": \\"x\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 2
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 3
-          }
-        }
-      },
-      null
-    ],
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 5
-      }
-    }
-  },
-  [
-    {
-      \\"tag\\": \\"application\\",
-      \\"operator\\": {
-        \\"tag\\": \\"application\\",
-        \\"operator\\": {
-          \\"tag\\": \\"application\\",
-          \\"operator\\": {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"thrice\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 6
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 12
-              }
-            }
-          },
-          \\"operands\\": [
-            {
-              \\"tag\\": \\"name\\",
-              \\"name\\": \\"thrice\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 13
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 19
-                }
-              }
-            },
-            null
-          ],
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 6
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 20
-            }
-          }
-        },
-        \\"operands\\": [
-          {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"plus_one\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 21
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 29
-              }
-            }
-          },
-          null
-        ],
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 6
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 30
-          }
-        }
-      },
-      \\"operands\\": [
-        0,
-        null
-      ],
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 6
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 34
-        }
-      }
-    },
-    null
-  ]
-]",
+  "value": "[ { \\"tag\\": \\"application\\",
+    \\"operator\\":
+      { \\"tag\\": \\"name\\",
+        \\"name\\": \\"f\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 0 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 1 } } },
+    \\"operands\\":
+      [ { \\"tag\\": \\"name\\",
+          \\"name\\": \\"x\\",
+          \\"loc\\":
+            { \\"start\\":
+                { \\"line\\": 1,
+                  \\"column\\": 2 },
+              \\"end\\":
+                { \\"line\\": 1,
+                  \\"column\\": 3 } } },
+      null ],
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 5 } } },
+[ { \\"tag\\": \\"application\\",
+    \\"operator\\":
+      { \\"tag\\": \\"application\\",
+        \\"operator\\":
+          { \\"tag\\": \\"application\\",
+            \\"operator\\":
+              { \\"tag\\": \\"name\\",
+                \\"name\\": \\"thrice\\",
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 6 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 12 } } },
+            \\"operands\\":
+              [ { \\"tag\\": \\"name\\",
+                  \\"name\\": \\"thrice\\",
+                  \\"loc\\":
+                    { \\"start\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 13 },
+                      \\"end\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 19 } } },
+              null ],
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 6 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 20 } } },
+        \\"operands\\":
+          [ { \\"tag\\": \\"name\\",
+              \\"name\\": \\"plus_one\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 21 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 29 } } },
+          null ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 6 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 30 } } },
+    \\"operands\\":
+      [ 0,
+      null ],
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 6 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 34 } } },
+null ] ]",
 }
 `;
 
 exports[`Parses if statements 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"conditional_statement\\",
+  "value": "[ { \\"tag\\": \\"conditional_statement\\",
     \\"predicate\\": true,
-    \\"consequent\\": {
-      \\"tag\\": \\"block\\",
-      \\"body\\": [
-        {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"hi\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 12
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 15
-            }
-          }
-        },
-        null
-      ],
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 10
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 17
-        }
-      }
-    },
-    \\"alternative\\": {
-      \\"tag\\": \\"block\\",
-      \\"body\\": [
-        {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"haha\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 25
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 30
-            }
-          }
-        },
-        null
-      ],
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 23
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 32
-        }
-      }
-    },
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 32
-      }
-    }
-  },
-  [
-    {
-      \\"tag\\": \\"conditional_statement\\",
-      \\"predicate\\": false,
-      \\"consequent\\": {
-        \\"tag\\": \\"block\\",
+    \\"consequent\\":
+      { \\"tag\\": \\"block\\",
+        \\"body\\":
+          [ { \\"tag\\": \\"name\\",
+              \\"name\\": \\"hi\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 12 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 15 } } },
+          null ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 10 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 17 } } },
+    \\"alternative\\":
+      { \\"tag\\": \\"block\\",
+        \\"body\\":
+          [ { \\"tag\\": \\"name\\",
+              \\"name\\": \\"haha\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 25 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 30 } } },
+          null ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 23 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 32 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 32 } } },
+[ { \\"tag\\": \\"conditional_statement\\",
+    \\"predicate\\": false,
+    \\"consequent\\":
+      { \\"tag\\": \\"block\\",
         \\"body\\": null,
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 44
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 46
-          }
-        }
-      },
-      \\"alternative\\": {
-        \\"tag\\": \\"block\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 44 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 46 } } },
+    \\"alternative\\":
+      { \\"tag\\": \\"block\\",
         \\"body\\": null,
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 52
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 54
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 33
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 54
-        }
-      }
-    },
-    null
-  ]
-]",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 52 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 54 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 33 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 54 } } },
+null ] ]",
 }
 `;
 
 exports[`Parses infix expressions 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"boolean_operation\\",
-    \\"operator\\": {
-      \\"tag\\": \\"name\\",
-      \\"name\\": \\"||\\",
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 14
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 15
-        }
-      }
-    },
-    \\"operands\\": [
-      {
-        \\"tag\\": \\"application\\",
-        \\"operator\\": {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"===\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 9
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 10
-            }
-          }
-        },
-        \\"operands\\": [
-          {
-            \\"tag\\": \\"application\\",
-            \\"operator\\": {
-              \\"tag\\": \\"name\\",
-              \\"name\\": \\"+\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 3
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 4
-                }
-              }
-            },
-            \\"operands\\": [
-              3,
-              [
-                5,
-                null
-              ]
-            ],
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 0
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 5
-              }
-            }
-          },
-          [
-            8,
-            null
-          ]
-        ],
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 0
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 11
-          }
-        }
-      },
-      [
-        {
-          \\"tag\\": \\"boolean_operation\\",
-          \\"operator\\": {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"&&\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 23
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 24
-              }
-            }
-          },
-          \\"operands\\": [
-            {
-              \\"tag\\": \\"application\\",
-              \\"operator\\": {
-                \\"tag\\": \\"name\\",
-                \\"name\\": \\"!\\",
-                \\"loc\\": {
-                  \\"start\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 15
-                  },
-                  \\"end\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 16
-                  }
-                }
-              },
-              \\"operands\\": [
-                true,
-                null
-              ],
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 15
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 20
-                }
-              }
-            },
-            [
-              false,
-              null
-            ]
-          ],
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 15
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 29
-            }
-          }
-        },
-        null
-      ]
-    ],
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 30
-      }
-    }
-  },
-  null
-]",
+  "value": "[ { \\"tag\\": \\"boolean_operation\\",
+    \\"operator\\":
+      { \\"tag\\": \\"name\\",
+        \\"name\\": \\"||\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 14 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 15 } } },
+    \\"operands\\":
+      [ { \\"tag\\": \\"application\\",
+          \\"operator\\":
+            { \\"tag\\": \\"name\\",
+              \\"name\\": \\"===\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 9 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 10 } } },
+          \\"operands\\":
+            [ { \\"tag\\": \\"application\\",
+                \\"operator\\":
+                  { \\"tag\\": \\"name\\",
+                    \\"name\\": \\"+\\",
+                    \\"loc\\":
+                      { \\"start\\":
+                          { \\"line\\": 1,
+                            \\"column\\": 3 },
+                        \\"end\\":
+                          { \\"line\\": 1,
+                            \\"column\\": 4 } } },
+                \\"operands\\":
+                  [ 3,
+                  [ 5,
+                  null ] ],
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 0 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 5 } } },
+            [ 8,
+            null ] ],
+          \\"loc\\":
+            { \\"start\\":
+                { \\"line\\": 1,
+                  \\"column\\": 0 },
+              \\"end\\":
+                { \\"line\\": 1,
+                  \\"column\\": 11 } } },
+      [ { \\"tag\\": \\"boolean_operation\\",
+          \\"operator\\":
+            { \\"tag\\": \\"name\\",
+              \\"name\\": \\"&&\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 23 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 24 } } },
+          \\"operands\\":
+            [ { \\"tag\\": \\"application\\",
+                \\"operator\\":
+                  { \\"tag\\": \\"name\\",
+                    \\"name\\": \\"!\\",
+                    \\"loc\\":
+                      { \\"start\\":
+                          { \\"line\\": 1,
+                            \\"column\\": 15 },
+                        \\"end\\":
+                          { \\"line\\": 1,
+                            \\"column\\": 16 } } },
+                \\"operands\\":
+                  [ true,
+                  null ],
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 15 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 20 } } },
+            [ false,
+            null ] ],
+          \\"loc\\":
+            { \\"start\\":
+                { \\"line\\": 1,
+                  \\"column\\": 15 },
+              \\"end\\":
+                { \\"line\\": 1,
+                  \\"column\\": 29 } } },
+      null ] ],
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 30 } } },
+null ]",
 }
 `;
 
 exports[`Parses literals 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  3,
-  [
-    true,
-    [
-      false,
-      [
-        \\"\\",
-        [
-          \\"\\",
-          [
-            \\"bob\\",
-            [
-              1,
-              [
-                20,
-                null
-              ]
-            ]
-          ]
-        ]
-      ]
-    ]
-  ]
-]",
+  "value": "[ 3,
+[ true,
+[ false,
+[ \\"\\",
+[ \\"\\",
+[ \\"bob\\",
+[ 1,
+[ 20,
+null ] ] ] ] ] ] ] ]",
 }
 `;
 
 exports[`Parses loops 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"while_loop\\",
+  "value": "[ { \\"tag\\": \\"while_loop\\",
     \\"predicate\\": true,
-    \\"statements\\": {
-      \\"tag\\": \\"block\\",
-      \\"body\\": [
-        {
-          \\"tag\\": \\"continue_statement\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 15
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 24
-            }
-          }
-        },
-        [
-          {
-            \\"tag\\": \\"break_statement\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 25
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 31
-              }
-            }
-          },
-          null
-        ]
-      ],
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 13
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 33
-        }
-      }
-    },
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 33
-      }
-    }
-  },
-  [
-    {
-      \\"tag\\": \\"for_loop\\",
-      \\"initialiser\\": {
-        \\"tag\\": \\"variable_declaration\\",
-        \\"name\\": {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"i\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 43
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 44
-            }
-          }
-        },
-        \\"value\\": 0,
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 39
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 48
-          }
-        }
-      },
-      \\"predicate\\": {
-        \\"tag\\": \\"application\\",
-        \\"operator\\": {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"<\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 53
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 54
-            }
-          }
-        },
-        \\"operands\\": [
-          {
-            \\"tag\\": \\"name\\",
+    \\"statements\\":
+      { \\"tag\\": \\"block\\",
+        \\"body\\":
+          [ { \\"tag\\": \\"continue_statement\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 15 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 24 } } },
+          [ { \\"tag\\": \\"break_statement\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 25 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 31 } } },
+          null ] ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 13 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 33 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 33 } } },
+[ { \\"tag\\": \\"for_loop\\",
+    \\"initialiser\\":
+      { \\"tag\\": \\"variable_declaration\\",
+        \\"name\\":
+          { \\"tag\\": \\"name\\",
             \\"name\\": \\"i\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 50
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 51
-              }
-            }
-          },
-          [
-            1,
-            null
-          ]
-        ],
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 50
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 55
-          }
-        }
-      },
-      \\"finaliser\\": {
-        \\"tag\\": \\"assignment\\",
-        \\"name\\": {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"i\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 57
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 58
-            }
-          }
-        },
-        \\"value\\": {
-          \\"tag\\": \\"application\\",
-          \\"operator\\": {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"+\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 64
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 65
-              }
-            }
-          },
-          \\"operands\\": [
-            {
-              \\"tag\\": \\"name\\",
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 43 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 44 } } },
+        \\"value\\": 0,
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 39 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 48 } } },
+    \\"predicate\\":
+      { \\"tag\\": \\"application\\",
+        \\"operator\\":
+          { \\"tag\\": \\"name\\",
+            \\"name\\": \\"<\\",
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 53 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 54 } } },
+        \\"operands\\":
+          [ { \\"tag\\": \\"name\\",
               \\"name\\": \\"i\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 61
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 62
-                }
-              }
-            },
-            [
-              1,
-              null
-            ]
-          ],
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 61
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 66
-            }
-          }
-        },
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 57
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 66
-          }
-        }
-      },
-      \\"statements\\": {
-        \\"tag\\": \\"block\\",
-        \\"body\\": [
-          {
-            \\"tag\\": \\"continue_statement\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 70
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 79
-              }
-            }
-          },
-          [
-            {
-              \\"tag\\": \\"break_statement\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 80
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 86
-                }
-              }
-            },
-            null
-          ]
-        ],
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 68
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 88
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 34
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 88
-        }
-      }
-    },
-    [
-      {
-        \\"tag\\": \\"for_loop\\",
-        \\"initialiser\\": {
-          \\"tag\\": \\"assignment\\",
-          \\"name\\": {
-            \\"tag\\": \\"name\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 50 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 51 } } },
+          [ 1,
+          null ] ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 50 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 55 } } },
+    \\"finaliser\\":
+      { \\"tag\\": \\"assignment\\",
+        \\"name\\":
+          { \\"tag\\": \\"name\\",
+            \\"name\\": \\"i\\",
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 57 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 58 } } },
+        \\"value\\":
+          { \\"tag\\": \\"application\\",
+            \\"operator\\":
+              { \\"tag\\": \\"name\\",
+                \\"name\\": \\"+\\",
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 64 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 65 } } },
+            \\"operands\\":
+              [ { \\"tag\\": \\"name\\",
+                  \\"name\\": \\"i\\",
+                  \\"loc\\":
+                    { \\"start\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 61 },
+                      \\"end\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 62 } } },
+              [ 1,
+              null ] ],
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 61 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 66 } } },
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 57 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 66 } } },
+    \\"statements\\":
+      { \\"tag\\": \\"block\\",
+        \\"body\\":
+          [ { \\"tag\\": \\"continue_statement\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 70 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 79 } } },
+          [ { \\"tag\\": \\"break_statement\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 80 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 86 } } },
+          null ] ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 68 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 88 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 34 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 88 } } },
+[ { \\"tag\\": \\"for_loop\\",
+    \\"initialiser\\":
+      { \\"tag\\": \\"assignment\\",
+        \\"name\\":
+          { \\"tag\\": \\"name\\",
             \\"name\\": \\"i\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 94
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 95
-              }
-            }
-          },
-          \\"value\\": 0,
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 94
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 99
-            }
-          }
-        },
-        \\"predicate\\": {
-          \\"tag\\": \\"application\\",
-          \\"operator\\": {
-            \\"tag\\": \\"name\\",
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 94 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 95 } } },
+        \\"value\\": 0,
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 94 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 99 } } },
+    \\"predicate\\":
+      { \\"tag\\": \\"application\\",
+        \\"operator\\":
+          { \\"tag\\": \\"name\\",
             \\"name\\": \\"<\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 104
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 105
-              }
-            }
-          },
-          \\"operands\\": [
-            {
-              \\"tag\\": \\"name\\",
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 104 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 105 } } },
+        \\"operands\\":
+          [ { \\"tag\\": \\"name\\",
               \\"name\\": \\"i\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 101
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 102
-                }
-              }
-            },
-            [
-              1,
-              null
-            ]
-          ],
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 101
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 106
-            }
-          }
-        },
-        \\"finaliser\\": {
-          \\"tag\\": \\"assignment\\",
-          \\"name\\": {
-            \\"tag\\": \\"name\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 101 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 102 } } },
+          [ 1,
+          null ] ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 101 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 106 } } },
+    \\"finaliser\\":
+      { \\"tag\\": \\"assignment\\",
+        \\"name\\":
+          { \\"tag\\": \\"name\\",
             \\"name\\": \\"i\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 108
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 109
-              }
-            }
-          },
-          \\"value\\": {
-            \\"tag\\": \\"application\\",
-            \\"operator\\": {
-              \\"tag\\": \\"name\\",
-              \\"name\\": \\"+\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 115
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 116
-                }
-              }
-            },
-            \\"operands\\": [
-              {
-                \\"tag\\": \\"name\\",
-                \\"name\\": \\"i\\",
-                \\"loc\\": {
-                  \\"start\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 112
-                  },
-                  \\"end\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 113
-                  }
-                }
-              },
-              [
-                1,
-                null
-              ]
-            ],
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 112
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 117
-              }
-            }
-          },
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 108
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 117
-            }
-          }
-        },
-        \\"statements\\": {
-          \\"tag\\": \\"block\\",
-          \\"body\\": [
-            {
-              \\"tag\\": \\"continue_statement\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 121
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 130
-                }
-              }
-            },
-            [
-              {
-                \\"tag\\": \\"break_statement\\",
-                \\"loc\\": {
-                  \\"start\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 131
-                  },
-                  \\"end\\": {
-                    \\"line\\": 1,
-                    \\"column\\": 137
-                  }
-                }
-              },
-              null
-            ]
-          ],
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 119
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 139
-            }
-          }
-        },
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 89
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 139
-          }
-        }
-      },
-      null
-    ]
-  ]
-]",
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 108 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 109 } } },
+        \\"value\\":
+          { \\"tag\\": \\"application\\",
+            \\"operator\\":
+              { \\"tag\\": \\"name\\",
+                \\"name\\": \\"+\\",
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 115 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 116 } } },
+            \\"operands\\":
+              [ { \\"tag\\": \\"name\\",
+                  \\"name\\": \\"i\\",
+                  \\"loc\\":
+                    { \\"start\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 112 },
+                      \\"end\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 113 } } },
+              [ 1,
+              null ] ],
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 112 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 117 } } },
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 108 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 117 } } },
+    \\"statements\\":
+      { \\"tag\\": \\"block\\",
+        \\"body\\":
+          [ { \\"tag\\": \\"continue_statement\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 121 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 130 } } },
+          [ { \\"tag\\": \\"break_statement\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 131 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 137 } } },
+          null ] ],
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 119 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 139 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 89 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 139 } } },
+null ] ] ]",
 }
 `;
 
 exports[`Parses multi-argument arrow function assignments properly 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"constant_declaration\\",
-    \\"name\\": {
-      \\"tag\\": \\"name\\",
-      \\"name\\": \\"y\\",
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 6
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 7
-        }
-      }
-    },
-    \\"value\\": {
-      \\"tag\\": \\"function_definition\\",
-      \\"parameters\\": [
-        {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"x\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 11
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 12
-            }
-          }
-        },
-        [
-          {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"y\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 14
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 15
-              }
-            }
-          },
-          null
-        ]
-      ],
-      \\"body\\": {
-        \\"tag\\": \\"return_statement\\",
-        \\"expression\\": {
-          \\"tag\\": \\"application\\",
-          \\"operator\\": {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"+\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 23
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 24
-              }
-            }
-          },
-          \\"operands\\": [
-            {
-              \\"tag\\": \\"name\\",
+  "value": "[ { \\"tag\\": \\"constant_declaration\\",
+    \\"name\\":
+      { \\"tag\\": \\"name\\",
+        \\"name\\": \\"y\\",
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 6 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 7 } } },
+    \\"value\\":
+      { \\"tag\\": \\"function_definition\\",
+        \\"parameters\\":
+          [ { \\"tag\\": \\"name\\",
               \\"name\\": \\"x\\",
-              \\"loc\\": {
-                \\"start\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 20
-                },
-                \\"end\\": {
-                  \\"line\\": 1,
-                  \\"column\\": 21
-                }
-              }
-            },
-            [
-              1,
-              null
-            ]
-          ],
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 20
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 25
-            }
-          }
-        },
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 20
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 25
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 10
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 25
-        }
-      }
-    },
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 26
-      }
-    }
-  },
-  null
-]",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 11 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 12 } } },
+          [ { \\"tag\\": \\"name\\",
+              \\"name\\": \\"y\\",
+              \\"loc\\":
+                { \\"start\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 14 },
+                  \\"end\\":
+                    { \\"line\\": 1,
+                      \\"column\\": 15 } } },
+          null ] ],
+        \\"body\\":
+          { \\"tag\\": \\"return_statement\\",
+            \\"expression\\":
+              { \\"tag\\": \\"application\\",
+                \\"operator\\":
+                  { \\"tag\\": \\"name\\",
+                    \\"name\\": \\"+\\",
+                    \\"loc\\":
+                      { \\"start\\":
+                          { \\"line\\": 1,
+                            \\"column\\": 23 },
+                        \\"end\\":
+                          { \\"line\\": 1,
+                            \\"column\\": 24 } } },
+                \\"operands\\":
+                  [ { \\"tag\\": \\"name\\",
+                      \\"name\\": \\"x\\",
+                      \\"loc\\":
+                        { \\"start\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 20 },
+                          \\"end\\":
+                            { \\"line\\": 1,
+                              \\"column\\": 21 } } },
+                  [ 1,
+                  null ] ],
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 20 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 25 } } },
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 20 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 25 } } },
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 10 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 25 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 26 } } },
+null ]",
 }
 `;
 
 exports[`Parses multi-argument arrow function expressions properly 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"function_definition\\",
-    \\"parameters\\": [
-      {
-        \\"tag\\": \\"name\\",
-        \\"name\\": \\"x\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 1
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 2
-          }
-        }
-      },
-      [
-        {
-          \\"tag\\": \\"name\\",
+  "value": "[ { \\"tag\\": \\"function_definition\\",
+    \\"parameters\\":
+      [ { \\"tag\\": \\"name\\",
+          \\"name\\": \\"x\\",
+          \\"loc\\":
+            { \\"start\\":
+                { \\"line\\": 1,
+                  \\"column\\": 1 },
+              \\"end\\":
+                { \\"line\\": 1,
+                  \\"column\\": 2 } } },
+      [ { \\"tag\\": \\"name\\",
           \\"name\\": \\"y\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 4
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 5
-            }
-          }
-        },
-        null
-      ]
-    ],
-    \\"body\\": {
-      \\"tag\\": \\"return_statement\\",
-      \\"expression\\": {
-        \\"tag\\": \\"application\\",
-        \\"operator\\": {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"+\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 13
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 14
-            }
-          }
-        },
-        \\"operands\\": [
-          {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"x\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 10
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 11
-              }
-            }
-          },
-          [
-            1,
-            null
-          ]
-        ],
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 10
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 15
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 10
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 15
-        }
-      }
-    },
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 16
-      }
-    }
-  },
-  null
-]",
+          \\"loc\\":
+            { \\"start\\":
+                { \\"line\\": 1,
+                  \\"column\\": 4 },
+              \\"end\\":
+                { \\"line\\": 1,
+                  \\"column\\": 5 } } },
+      null ] ],
+    \\"body\\":
+      { \\"tag\\": \\"return_statement\\",
+        \\"expression\\":
+          { \\"tag\\": \\"application\\",
+            \\"operator\\":
+              { \\"tag\\": \\"name\\",
+                \\"name\\": \\"+\\",
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 13 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 14 } } },
+            \\"operands\\":
+              [ { \\"tag\\": \\"name\\",
+                  \\"name\\": \\"x\\",
+                  \\"loc\\":
+                    { \\"start\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 10 },
+                      \\"end\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 11 } } },
+              [ 1,
+              null ] ],
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 10 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 15 } } },
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 10 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 15 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 16 } } },
+null ]",
 }
 `;
 
 exports[`Parses multi-argument arrow function expressions properly 2`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"function_definition\\",
-    \\"parameters\\": [
-      {
-        \\"tag\\": \\"name\\",
-        \\"name\\": \\"x\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 1
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 2
-          }
-        }
-      },
-      [
-        {
-          \\"tag\\": \\"name\\",
+  "value": "[ { \\"tag\\": \\"function_definition\\",
+    \\"parameters\\":
+      [ { \\"tag\\": \\"name\\",
+          \\"name\\": \\"x\\",
+          \\"loc\\":
+            { \\"start\\":
+                { \\"line\\": 1,
+                  \\"column\\": 1 },
+              \\"end\\":
+                { \\"line\\": 1,
+                  \\"column\\": 2 } } },
+      [ { \\"tag\\": \\"name\\",
           \\"name\\": \\"y\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 4
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 5
-            }
-          }
-        },
-        null
-      ]
-    ],
-    \\"body\\": {
-      \\"tag\\": \\"return_statement\\",
-      \\"expression\\": {
-        \\"tag\\": \\"application\\",
-        \\"operator\\": {
-          \\"tag\\": \\"name\\",
-          \\"name\\": \\"+\\",
-          \\"loc\\": {
-            \\"start\\": {
-              \\"line\\": 1,
-              \\"column\\": 13
-            },
-            \\"end\\": {
-              \\"line\\": 1,
-              \\"column\\": 14
-            }
-          }
-        },
-        \\"operands\\": [
-          {
-            \\"tag\\": \\"name\\",
-            \\"name\\": \\"x\\",
-            \\"loc\\": {
-              \\"start\\": {
-                \\"line\\": 1,
-                \\"column\\": 10
-              },
-              \\"end\\": {
-                \\"line\\": 1,
-                \\"column\\": 11
-              }
-            }
-          },
-          [
-            1,
-            null
-          ]
-        ],
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 10
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 15
-          }
-        }
-      },
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 10
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 15
-        }
-      }
-    },
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 16
-      }
-    }
-  },
-  null
-]",
+          \\"loc\\":
+            { \\"start\\":
+                { \\"line\\": 1,
+                  \\"column\\": 4 },
+              \\"end\\":
+                { \\"line\\": 1,
+                  \\"column\\": 5 } } },
+      null ] ],
+    \\"body\\":
+      { \\"tag\\": \\"return_statement\\",
+        \\"expression\\":
+          { \\"tag\\": \\"application\\",
+            \\"operator\\":
+              { \\"tag\\": \\"name\\",
+                \\"name\\": \\"+\\",
+                \\"loc\\":
+                  { \\"start\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 13 },
+                    \\"end\\":
+                      { \\"line\\": 1,
+                        \\"column\\": 14 } } },
+            \\"operands\\":
+              [ { \\"tag\\": \\"name\\",
+                  \\"name\\": \\"x\\",
+                  \\"loc\\":
+                    { \\"start\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 10 },
+                      \\"end\\":
+                        { \\"line\\": 1,
+                          \\"column\\": 11 } } },
+              [ 1,
+              null ] ],
+            \\"loc\\":
+              { \\"start\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 10 },
+                \\"end\\":
+                  { \\"line\\": 1,
+                    \\"column\\": 15 } } },
+        \\"loc\\":
+          { \\"start\\":
+              { \\"line\\": 1,
+                \\"column\\": 10 },
+            \\"end\\":
+              { \\"line\\": 1,
+                \\"column\\": 15 } } },
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 16 } } },
+null ]",
 }
 `;
 
 exports[`Parses name expression 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"name\\",
+  "value": "[ { \\"tag\\": \\"name\\",
     \\"name\\": \\"x\\",
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 2
-      }
-    }
-  },
-  null
-]",
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 2 } } },
+null ]",
 }
 `;
 
 exports[`Parses name expressions 1`] = `
 Object {
   "status": "finished",
-  "value": "[
-  {
-    \\"tag\\": \\"name\\",
+  "value": "[ { \\"tag\\": \\"name\\",
     \\"name\\": \\"x\\",
-    \\"loc\\": {
-      \\"start\\": {
-        \\"line\\": 1,
-        \\"column\\": 0
-      },
-      \\"end\\": {
-        \\"line\\": 1,
-        \\"column\\": 2
-      }
-    }
-  },
-  [
-    {
-      \\"tag\\": \\"name\\",
-      \\"name\\": \\"moreNames\\",
-      \\"loc\\": {
-        \\"start\\": {
-          \\"line\\": 1,
-          \\"column\\": 3
-        },
-        \\"end\\": {
-          \\"line\\": 1,
-          \\"column\\": 13
-        }
-      }
-    },
-    [
-      {
-        \\"tag\\": \\"name\\",
-        \\"name\\": \\"undefined\\",
-        \\"loc\\": {
-          \\"start\\": {
-            \\"line\\": 1,
-            \\"column\\": 14
-          },
-          \\"end\\": {
-            \\"line\\": 1,
-            \\"column\\": 24
-          }
-        }
-      },
-      null
-    ]
-  ]
-]",
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 0 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 2 } } },
+[ { \\"tag\\": \\"name\\",
+    \\"name\\": \\"moreNames\\",
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 3 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 13 } } },
+[ { \\"tag\\": \\"name\\",
+    \\"name\\": \\"undefined\\",
+    \\"loc\\":
+      { \\"start\\":
+          { \\"line\\": 1,
+            \\"column\\": 14 },
+        \\"end\\":
+          { \\"line\\": 1,
+            \\"column\\": 24 } } },
+null ] ] ]",
 }
 `;