function generate(tree) {
		var type = tree.type;

		if (typeof tree === "string") {
			return tree;
		} else if (Array.isArray(tree)) {
			var output = "";

			for (var i = 0; i < tree.length; i++) {
				output += generate(tree[i]);
			}

			return output;
		} else if (type === "comment") {
			return "/*" + generate(tree.value[1]) + "*/";
		} else if (type === "attributes") {
			var value = tree.value;
			var _output = "";
			var separator = "";

			for (var _i = 0; _i < value.length; _i++) {
				var pair = value[_i];
				_output += separator + "\"" + generate(pair[0]) + "\":" + generate(pair[2]) + generate(pair[3]);
				separator = ",";
			}

			return {
				output: _output,
				separator: separator
			};
		} else if (type === "text") {
			var textGenerated = generate(tree.value);
			var textGeneratedIsWhitespace = whitespaceRE.test(textGenerated) && textGenerated.indexOf("\n") !== -1; // Text that is only whitespace with at least one newline is ignored and
			// added only to preserve newlines in the generated code.

			return {
				output: textGeneratedIsWhitespace ? textGenerated : "Moon.view.components.text({data:\"" + textGenerated.replace(textSpecialRE, function (match, character, characterSpecial) {
					return character + (characterSpecial === "\"" ? "\\\"" : "\\n\\\n");
				}) + "\"})",
				isWhitespace: textGeneratedIsWhitespace
			};
		} else if (type === "interpolation") {
			return "Moon.view.components.text({data:" + generate(tree.value[1]) + "})";
		} else if (type === "node") {
			// Nodes represent a variable reference.
			var _value = tree.value;
			return generate(_value[1]) + generateName(_value[2]) + generate(_value[3]);
		} else if (type === "nodeData") {
			// Data nodes represent calling a function with either a custom data
			// expression or an object using attribute syntax.
			var _value2 = tree.value;
			var data = _value2[4];
			var dataGenerated = generate(data);
			return "" + generate(_value2[1]) + generateName(_value2[2]) + generate(_value2[3]) + "(" + (data.type === "attributes" ? "{" + dataGenerated.output + "}" : dataGenerated) + ")";
		} else if (type === "nodeDataChildren") {
			// Data and children nodes represent calling a function with a data
			// object using attribute syntax and children.
			var _value3 = tree.value;

			var _data = generate(_value3[4]);

			var children = _value3[6];
			var childrenLength = children.length;
			var childrenGenerated;

			if (childrenLength === 0) {
				childrenGenerated = "";
			} else {
				var _separator = "";
				childrenGenerated = _data.separator + "children:[";

				for (var _i2 = 0; _i2 < childrenLength; _i2++) {
					var child = children[_i2];
					var childGenerated = generate(child);

					if (child.type === "text") {
						if (childGenerated.isWhitespace) {
							childrenGenerated += childGenerated.output;
						} else {
							childrenGenerated += _separator + childGenerated.output;
							_separator = ",";
						}
					} else {
						childrenGenerated += _separator + childGenerated;
						_separator = ",";
					}
				}

				childrenGenerated += "]";
			}

			return "" + generate(_value3[1]) + generateName(_value3[2]) + generate(_value3[3]) + "({" + _data.output + childrenGenerated + "})";
		}
	}
Generator

The generator takes parse nodes and converts them to strings representing
JavaScript code. All code is generated the same, but Moon view expressions
are converted to function calls or variable references.

@param {object} tree
@returns {string} generator result