code: func evaluate(node ast.Node, ext vmExtMap, tla vmExtMap, nativeFuncs map[string]*NativeFunction,
  	maxStack int, importer Importer, stringOutputMode bool) (string, error) {
  
  	i, err := buildInterpreter(ext, nativeFuncs, maxStack, importer)
  	if err != nil {
  		return "", err
  	}
  
  	result, manifestationTrace, err := evaluateAux(i, node, tla)
  	if err != nil {
  		return "", err
  	}
  
  	var buf bytes.Buffer
  	if stringOutputMode {
  		err = i.manifestString(&buf, manifestationTrace, result)
  	} else {
  		err = i.manifestAndSerializeJSON(&buf, manifestationTrace, result, true, "")
  	}
  	if err != nil {
  		return "", err
  	}
  	buf.WriteString("\n")
  	return buf.String(), nil
  }
docs: // TODO(sbarzowski) this function takes far too many arguments - build interpreter in vm instead