var _ns_ = "wisp.backend.javascript.writer"; module.namespace = _ns_; module.description = "Compiler backend for for writing JS output"; var name = (require("./../../ast")).name; var namespace = (require("./../../ast")).namespace; var symbol = (require("./../../ast")).symbol; var isSymbol = (require("./../../ast")).isSymbol; var isKeyword = (require("./../../ast")).isKeyword; var list = (require("./../../sequence")).list; var first = (require("./../../sequence")).first; var rest = (require("./../../sequence")).rest; var isList = (require("./../../sequence")).isList; var vec = (require("./../../sequence")).vec; var map = (require("./../../sequence")).map; var count = (require("./../../sequence")).count; var last = (require("./../../sequence")).last; var reduce = (require("./../../sequence")).reduce; var isEmpty = (require("./../../sequence")).isEmpty; var isTrue = (require("./../../runtime")).isTrue; var isNil = (require("./../../runtime")).isNil; var isString = (require("./../../runtime")).isString; var isNumber = (require("./../../runtime")).isNumber; var isVector = (require("./../../runtime")).isVector; var isDictionary = (require("./../../runtime")).isDictionary; var isBoolean = (require("./../../runtime")).isBoolean; var isRePattern = (require("./../../runtime")).isRePattern; var reFind = (require("./../../runtime")).reFind; var dec = (require("./../../runtime")).dec; var subs = (require("./../../runtime")).subs; var replace = (require("./../../string")).replace; var join = (require("./../../string")).join; var split = (require("./../../string")).split; var upperCase = (require("./../../string")).upperCase;; var writeReference = function writeReference(form) { "Translates references from clojure convention to JS:\n\n **macros** __macros__\n list->vector listToVector\n set! set\n foo_bar foo_bar\n number? isNumber\n create-server createServer"; return (function() { var id = name(form); id = id === "*" ? "multiply" : id === "/" ? "divide" : id === "+" ? "sum" : id === "-" ? "subtract" : id === "=" ? "equal?" : id === "==" ? "strict-equal?" : id === "<=" ? "not-greater-than" : id === ">=" ? "not-less-than" : id === ">" ? "greater-than" : id === "<" ? "less-than" : "else" ? id : void(0); id = join("_", split(id, "*")); id = join("-to-", split(id, "->")); id = join(split(id, "!")); id = join("$", split(id, "%")); id = join("-plus-", split(id, "+")); id = join("-and-", split(id, "&")); id = last(id) === "?" ? "" + "is-" + (subs(id, 0, dec(count(id)))) : id; id = reduce(function(result, key) { return "" + result + ((!(isEmpty(result))) && (!(isEmpty(key))) ? "" + (upperCase((key || 0)[0])) + (subs(key, 1)) : key); }, "", split(id, "-")); return id; })(); }; exports.writeReference = writeReference; var writeKeywordReference = function writeKeywordReference(form) { return "" + "\"" + (name(form)) + "\""; }; exports.writeKeywordReference = writeKeywordReference; var writeKeyword = function writeKeyword(form) { return "" + "\"" + "꞉" + (name(form)) + "\""; }; exports.writeKeyword = writeKeyword; var writeSymbol = function writeSymbol(form) { return write(list(symbol(void(0), "symbol"), namespace(form), name(form))); }; exports.writeSymbol = writeSymbol; var writeNil = function writeNil(form) { return "void(0)"; }; exports.writeNil = writeNil; var writeNumber = function writeNumber(form) { return form; }; exports.writeNumber = writeNumber; var writeBoolean = function writeBoolean(form) { return isTrue(form) ? "true" : "false"; }; exports.writeBoolean = writeBoolean; var writeString = function writeString(form) { form = replace(form, RegExp("\\\\", "g"), "\\\\"); form = replace(form, RegExp("\n", "g"), "\\n"); form = replace(form, RegExp("\r", "g"), "\\r"); form = replace(form, RegExp("\t", "g"), "\\t"); form = replace(form, RegExp("\"", "g"), "\\\""); return "" + "\"" + form + "\""; }; exports.writeString = writeString; var writeTemplate = function writeTemplate() { var form = Array.prototype.slice.call(arguments, 0); return (function() { var indentPattern = /\n *$/; var lineBreakPatter = RegExp("\n", "g"); var getIndentation = function(code) { return (reFind(indentPattern, code)) || "\n"; }; return (function loop(code, parts, values) { var recur = loop; while (recur === loop) { recur = count(parts) > 1 ? (code = "" + code + (first(parts)) + (replace("" + "" + (first(values)), lineBreakPatter, getIndentation(first(parts)))), parts = rest(parts), values = rest(values), loop) : "" + code + (first(parts)); }; return recur; })("", split(first(form), "~{}"), rest(form)); })(); }; exports.writeTemplate = writeTemplate; var writeGroup = function writeGroup() { var forms = Array.prototype.slice.call(arguments, 0); return join(", ", forms); }; exports.writeGroup = writeGroup; var writeInvoke = function writeInvoke(callee) { var params = Array.prototype.slice.call(arguments, 1); return writeTemplate("~{}(~{})", callee, writeGroup.apply(writeGroup, params)); }; exports.writeInvoke = writeInvoke; var writeError = function writeError(message) { return function() { return (function() { throw Error(message); })(); }; }; exports.writeError = writeError; var writeVector = writeError("Vectors are not supported"); exports.writeVector = writeVector; var writeDictionary = writeError("Dictionaries are not supported"); exports.writeDictionary = writeDictionary; var writePattern = writeError("Regular expressions are not supported"); exports.writePattern = writePattern; var compileComment = function compileComment(form) { return compileTemplate(list("//~{}\n", first(form))); }; exports.compileComment = compileComment; var writeDef = function writeDef(form) { var id = first(form); var isExport = ((((meta(form)) || {}) || 0)["top"]) && (!((((meta(id)) || {}) || 0)["private"])); var attribute = symbol(namespace(id), "" + "-" + (name(id))); return isExport ? compileTemplate(list("var ~{};\n~{}", compile(cons(symbol(void(0), "set!"), form)), compile(list(symbol(void(0), "set!"), list(symbol(void(0), "."), symbol(void(0), "exports"), attribute), id)))) : compileTemplate(list("var ~{}", compile(cons(symbol(void(0), "set!"), form)))); }; exports.writeDef = writeDef; var write = function write(form) { return isNil(form) ? writeNil(form) : isSymbol(form) ? writeReference(form) : isKeyword(form) ? writeKeywordReference(form) : isString(form) ? writeString(form) : isNumber(form) ? writeNumber(form) : isBoolean(form) ? writeBoolean(form) : isRePattern(form) ? writePattern(form) : isVector(form) ? writeVector(form) : isDictionary(form) ? writeDictionary() : isList(form) ? writeInvoke.apply(writeInvoke, map(write, vec(form))) : "else" ? writeError("Unsupported form") : void(0); }; exports.write = write