UNPKG

wisp

Version:

Homoiconic JS with clojure syntax, s-expressions & macros

1,189 lines 188 kB
{ var _ns_ = { id: 'wisp.backend.escodegen.writer', doc: void 0 }; var wisp_reader = require('./../../reader'); var readFromString = wisp_reader.readFromString; var wisp_ast = require('./../../ast'); var meta = wisp_ast.meta; var withMeta = wisp_ast.withMeta; var isSymbol = wisp_ast.isSymbol; var symbol = wisp_ast.symbol; var isKeyword = wisp_ast.isKeyword; var keyword = wisp_ast.keyword; var namespace = wisp_ast.namespace; var isUnquote = wisp_ast.isUnquote; var isUnquoteSplicing = wisp_ast.isUnquoteSplicing; var isQuote = wisp_ast.isQuote; var isSyntaxQuote = wisp_ast.isSyntaxQuote; var name = wisp_ast.name; var gensym = wisp_ast.gensym; var prStr = wisp_ast.prStr; var wisp_sequence = require('./../../sequence'); var isEmpty = wisp_sequence.isEmpty; var count = wisp_sequence.count; var isList = wisp_sequence.isList; var list = wisp_sequence.list; var first = wisp_sequence.first; var second = wisp_sequence.second; var third = wisp_sequence.third; var rest = wisp_sequence.rest; var cons = wisp_sequence.cons; var conj = wisp_sequence.conj; var butlast = wisp_sequence.butlast; var reverse = wisp_sequence.reverse; var reduce = wisp_sequence.reduce; var vec = wisp_sequence.vec; var last = wisp_sequence.last; var map = wisp_sequence.map; var mapv = wisp_sequence.mapv; var filter = wisp_sequence.filter; var take = wisp_sequence.take; var concat = wisp_sequence.concat; var partition = wisp_sequence.partition; var repeat = wisp_sequence.repeat; var interleave = wisp_sequence.interleave; var assoc = wisp_sequence.assoc; var wisp_runtime = require('./../../runtime'); var isOdd = wisp_runtime.isOdd; var isDictionary = wisp_runtime.isDictionary; var dictionary = wisp_runtime.dictionary; var merge = wisp_runtime.merge; var keys = wisp_runtime.keys; var vals = wisp_runtime.vals; var isContainsVector = wisp_runtime.isContainsVector; var mapDictionary = wisp_runtime.mapDictionary; var isString = wisp_runtime.isString; var isNumber = wisp_runtime.isNumber; var isVector = wisp_runtime.isVector; var isBoolean = wisp_runtime.isBoolean; var subs = wisp_runtime.subs; var reFind = wisp_runtime.reFind; var isTrue = wisp_runtime.isTrue; var isFalse = wisp_runtime.isFalse; var isNil = wisp_runtime.isNil; var isRePattern = wisp_runtime.isRePattern; var inc = wisp_runtime.inc; var dec = wisp_runtime.dec; var str = wisp_runtime.str; var char = wisp_runtime.char; var int = wisp_runtime.int; var isEqual = wisp_runtime.isEqual; var isStrictEqual = wisp_runtime.isStrictEqual; var get = wisp_runtime.get; var wisp_string = require('./../../string'); var split = wisp_string.split; var join = wisp_string.join; var upperCase = wisp_string.upperCase; var replace = wisp_string.replace; var triml = wisp_string.triml; var wisp_expander = require('./../../expander'); var installMacro = wisp_expander.installMacro; var escodegen = require('escodegen'); var generate = escodegen.generate; } var __uniqueChar__ = exports.__uniqueChar__ = '\xF8'; var toCamelJoin = exports.toCamelJoin = function toCamelJoin(prefix, key) { return '' + prefix + (!isEmpty(prefix) && !isEmpty(key) ? '' + upperCase((key || 0)[0]) + subs(key, 1) : key); }; var toPrivatePrefix = exports.toPrivatePrefix = function toPrivatePrefix(id) { return function () { var spaceDelimitedø1 = join(' ', split(id, /-/)); var leftTrimmedø1 = triml(spaceDelimitedø1); var nø1 = count(id) - count(leftTrimmedø1); return nø1 > 0 ? '' + join('_', repeat(inc(nø1), '')) + subs(id, nø1) : id; }.call(this); }; var translateIdentifierWord = exports.translateIdentifierWord = function translateIdentifierWord(form) { 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' : id === '->' ? 'thread-first' : 'else' ? id : void 0; id = join('_', split(id, '*')); id = join('_', split(id, '.')); id = subs(id, 0, 2) === '->' ? subs(join('-to-', split(id, '->')), 1) : join('-to-', split(id, '->')); id = join(split(id, '!')); id = join('$', split(id, '%')); id = join('-equal-', split(id, '=')); id = join('-plus-', split(id, '+')); id = join('-and-', split(id, '&')); id = last(id) === '?' ? '' + 'is-' + subs(id, 0, dec(count(id))) : id; id = toPrivatePrefix(id); id = reduce(toCamelJoin, '', split(id, '-')); return id; }; var translateIdentifier = exports.translateIdentifier = function translateIdentifier(form) { return function () { var nsø1 = namespace(form); return '' + (nsø1 && !isEqual(nsø1, 'js') ? '' + translateIdentifierWord(namespace(form)) + '.' : '') + join('.', map(translateIdentifierWord, split(name(form), '.'))); }.call(this); }; var errorArgCount = exports.errorArgCount = function errorArgCount(callee, n) { return (function () { throw SyntaxError('' + 'Wrong number of arguments (' + n + ') passed to: ' + callee); })(); }; var inheritLocation = exports.inheritLocation = function inheritLocation(body) { return function () { var startø1 = ((first(body) || 0)['loc'] || 0)['start']; var endø1 = ((last(body) || 0)['loc'] || 0)['end']; return !(isNil(startø1) || isNil(endø1)) ? { 'start': startø1, 'end': endø1 } : void 0; }.call(this); }; var writeLocation = exports.writeLocation = function writeLocation(form, original) { return function () { var dataø1 = meta(form); var inheritedø1 = meta(original); var startø1 = (form || 0)['start'] || (dataø1 || 0)['start'] || (inheritedø1 || 0)['start']; var endø1 = (form || 0)['end'] || (dataø1 || 0)['end'] || (inheritedø1 || 0)['end']; return !isNil(startø1) ? { 'loc': { 'start': { 'line': inc(get.apply(void 0, [ startø1, 'line', -1 ])), 'column': get.apply(void 0, [ startø1, 'column', -1 ]) }, 'end': { 'line': inc(get.apply(void 0, [ endø1, 'line', -1 ])), 'column': get.apply(void 0, [ endø1, 'column', -1 ]) } } } : {}; }.call(this); }; var __writers__ = exports.__writers__ = {}; var installWriter = exports.installWriter = function installWriter(op, writer) { return (__writers__ || 0)[op] = writer; }; var writeOp = exports.writeOp = function writeOp(op, form) { return function () { var writerø1 = (__writers__ || 0)[op]; !writerø1 ? (function () { throw Error('' + 'Assert failed: ' + ('' + 'Unsupported operation: ' + op) + 'writer'); })() : void 0; return conj(writeLocation((form || 0)['form'], (form || 0)['original-form']), writerø1(form)); }.call(this); }; var __specials__ = exports.__specials__ = {}; var installSpecial = exports.installSpecial = function installSpecial(op, writer) { return (__specials__ || 0)[name(op)] = writer; }; var writeSpecial = exports.writeSpecial = function writeSpecial(writer, form) { return conj(writeLocation((form || 0)['form'], (form || 0)['original-form']), writer.apply(void 0, (form || 0)['params'])); }; var writeNil = exports.writeNil = function writeNil(form) { return { 'type': 'UnaryExpression', 'operator': 'void', 'argument': { 'type': 'Literal', 'value': 0 }, 'prefix': true }; }; installWriter('nil', writeNil); var writeLiteral = exports.writeLiteral = function writeLiteral(form) { return { 'type': 'Literal', 'value': form }; }; var writeList = exports.writeList = function writeList(form) { return { 'type': 'CallExpression', 'callee': write({ 'op': 'var', 'form': symbol(void 0, 'list') }), 'arguments': map(write, (form || 0)['items']) }; }; installWriter('list', writeList); var writeSymbol = exports.writeSymbol = function writeSymbol(form) { return { 'type': 'CallExpression', 'callee': write({ 'op': 'var', 'form': symbol(void 0, 'symbol') }), 'arguments': [ writeConstant((form || 0)['namespace']), writeConstant((form || 0)['name']) ] }; }; installWriter('symbol', writeSymbol); var writeConstant = exports.writeConstant = function writeConstant(form) { return isNil(form) ? writeNil(form) : isKeyword(form) ? writeLiteral(namespace(form) ? '' + namespace(form) + '/' + name(form) : name(form)) : isNumber(form) ? writeNumber(form.valueOf()) : isString(form) ? writeString(form) : 'else' ? writeLiteral(form) : void 0; }; installWriter('constant', function ($1) { return writeConstant(($1 || 0)['form']); }); var writeString = exports.writeString = function writeString(form) { return { 'type': 'Literal', 'value': '' + form }; }; var writeNumber = exports.writeNumber = function writeNumber(form) { return form < 0 ? { 'type': 'UnaryExpression', 'operator': '-', 'prefix': true, 'argument': writeNumber(form * -1) } : writeLiteral(form); }; var writeKeyword = exports.writeKeyword = function writeKeyword(form) { return { 'type': 'Literal', 'value': (form || 0)['form'] }; }; installWriter('keyword', writeKeyword); var toIdentifier = exports.toIdentifier = function toIdentifier(form) { return { 'type': 'Identifier', 'name': translateIdentifier(form) }; }; var writeBindingVar = exports.writeBindingVar = function writeBindingVar(form) { return function () { var baseIdø1 = (form || 0)['id']; var resolvedIdø1 = (form || 0)['shadow'] ? symbol(void 0, '' + translateIdentifier(baseIdø1) + __uniqueChar__ + (form || 0)['depth']) : baseIdø1; return conj(toIdentifier(resolvedIdø1), writeLocation(baseIdø1)); }.call(this); }; var writeVar = exports.writeVar = function writeVar(node) { return isEqual('binding', ((node || 0)['binding'] || 0)['type']) ? conj(writeBindingVar((node || 0)['binding']), writeLocation((node || 0)['form'])) : conj(writeLocation((node || 0)['form']), toIdentifier((node || 0)['form'])); }; installWriter('var', writeVar); installWriter('param', writeVar); var writeInvoke = exports.writeInvoke = function writeInvoke(form) { return { 'type': 'CallExpression', 'callee': write((form || 0)['callee']), 'arguments': map(write, (form || 0)['params']) }; }; installWriter('invoke', writeInvoke); var writeVector = exports.writeVector = function writeVector(form) { return { 'type': 'ArrayExpression', 'elements': map(write, (form || 0)['items']) }; }; installWriter('vector', writeVector); var writeDictionary = exports.writeDictionary = function writeDictionary(form) { return function () { var propertiesø1 = partition(2, interleave((form || 0)['keys'], (form || 0)['values'])); return { 'type': 'ObjectExpression', 'properties': map(function (pair) { return function () { var keyø1 = first(pair); var valueø1 = second(pair); return { 'kind': 'init', 'type': 'Property', 'key': isEqual('symbol', (keyø1 || 0)['op']) ? writeConstant('' + (keyø1 || 0)['form']) : write(keyø1), 'value': write(valueø1) }; }.call(this); }, propertiesø1) }; }.call(this); }; installWriter('dictionary', writeDictionary); var writeExport = exports.writeExport = function writeExport(form) { return write({ 'op': 'set!', 'target': { 'op': 'member-expression', 'computed': false, 'target': { 'op': 'var', 'form': withMeta(symbol(void 0, 'exports'), meta(((form || 0)['id'] || 0)['form'])) }, 'property': (form || 0)['id'], 'form': ((form || 0)['id'] || 0)['form'] }, 'value': (form || 0)['init'], 'form': ((form || 0)['id'] || 0)['form'] }); }; var writeDef = exports.writeDef = function writeDef(form) { return conj({ 'type': 'VariableDeclaration', 'kind': 'var', 'declarations': [conj({ 'type': 'VariableDeclarator', 'id': write((form || 0)['id']), 'init': conj((form || 0)['export'] ? writeExport(form) : write((form || 0)['init'])) }, writeLocation(((form || 0)['id'] || 0)['form']))] }, writeLocation((form || 0)['form'], (form || 0)['original-form'])); }; installWriter('def', writeDef); var writeBinding = exports.writeBinding = function writeBinding(form) { return function () { var idø1 = writeBindingVar(form); var initø1 = write((form || 0)['init']); return { 'type': 'VariableDeclaration', 'kind': 'var', 'loc': inheritLocation([ idø1, initø1 ]), 'declarations': [{ 'type': 'VariableDeclarator', 'id': idø1, 'init': initø1 }] }; }.call(this); }; installWriter('binding', writeBinding); var writeThrow = exports.writeThrow = function writeThrow(form) { return toExpression(conj({ 'type': 'ThrowStatement', 'argument': write((form || 0)['throw']) }, writeLocation((form || 0)['form'], (form || 0)['original-form']))); }; installWriter('throw', writeThrow); var writeNew = exports.writeNew = function writeNew(form) { return { 'type': 'NewExpression', 'callee': write((form || 0)['constructor']), 'arguments': map(write, (form || 0)['params']) }; }; installWriter('new', writeNew); var writeSet = exports.writeSet = function writeSet(form) { return { 'type': 'AssignmentExpression', 'operator': '=', 'left': write((form || 0)['target']), 'right': write((form || 0)['value']) }; }; installWriter('set!', writeSet); var writeAget = exports.writeAget = function writeAget(form) { return { 'type': 'MemberExpression', 'computed': (form || 0)['computed'], 'object': write((form || 0)['target']), 'property': write((form || 0)['property']) }; }; installWriter('member-expression', writeAget); var __statements__ = exports.__statements__ = { 'EmptyStatement': true, 'BlockStatement': true, 'ExpressionStatement': true, 'IfStatement': true, 'LabeledStatement': true, 'BreakStatement': true, 'ContinueStatement': true, 'SwitchStatement': true, 'ReturnStatement': true, 'ThrowStatement': true, 'TryStatement': true, 'WhileStatement': true, 'DoWhileStatement': true, 'ForStatement': true, 'ForInStatement': true, 'ForOfStatement': true, 'LetStatement': true, 'VariableDeclaration': true, 'FunctionDeclaration': true }; var writeStatement = exports.writeStatement = function writeStatement(form) { return toStatement(write(form)); }; var toStatement = exports.toStatement = function toStatement(node) { return (__statements__ || 0)[(node || 0)['type']] ? node : { 'type': 'ExpressionStatement', 'expression': node, 'loc': (node || 0)['loc'] }; }; var toReturn = exports.toReturn = function toReturn(form) { return conj({ 'type': 'ReturnStatement', 'argument': write(form) }, writeLocation((form || 0)['form'], (form || 0)['original-form'])); }; var writeBody = exports.writeBody = function writeBody(form) { return function () { var statementsø1 = map(writeStatement, (form || 0)['statements'] || []); var resultø1 = (form || 0)['result'] ? toReturn((form || 0)['result']) : void 0; return resultø1 ? conj(statementsø1, resultø1) : statementsø1; }.call(this); }; var toBlock = exports.toBlock = function toBlock(body) { return isVector(body) ? { 'type': 'BlockStatement', 'body': body, 'loc': inheritLocation(body) } : { 'type': 'BlockStatement', 'body': [body], 'loc': (body || 0)['loc'] }; }; var toExpression = exports.toExpression = function toExpression() { var body = Array.prototype.slice.call(arguments, 0); return { 'type': 'CallExpression', 'arguments': [], 'loc': inheritLocation(body), 'callee': toSequence([{ 'type': 'FunctionExpression', 'id': void 0, 'params': [], 'defaults': [], 'expression': false, 'generator': false, 'rest': void 0, 'body': toBlock(body) }]) }; }; var writeDo = exports.writeDo = function writeDo(form) { return (meta(first((form || 0)['form'])) || 0)['block'] ? toBlock(writeBody(conj(form, { 'result': void 0, 'statements': conj((form || 0)['statements'], (form || 0)['result']) }))) : toExpression.apply(void 0, writeBody(form)); }; installWriter('do', writeDo); var writeIf = exports.writeIf = function writeIf(form) { return { 'type': 'ConditionalExpression', 'test': write((form || 0)['test']), 'consequent': write((form || 0)['consequent']), 'alternate': write((form || 0)['alternate']) }; }; installWriter('if', writeIf); var writeTry = exports.writeTry = function writeTry(form) { return function () { var handlerø1 = (form || 0)['handler']; var finalizerø1 = (form || 0)['finalizer']; return toExpression(conj({ 'type': 'TryStatement', 'guardedHandlers': [], 'block': toBlock(writeBody((form || 0)['body'])), 'handlers': handlerø1 ? [{ 'type': 'CatchClause', 'param': write((handlerø1 || 0)['name']), 'body': toBlock(writeBody(handlerø1)) }] : [], 'finalizer': finalizerø1 ? toBlock(writeBody(finalizerø1)) : !handlerø1 ? toBlock([]) : 'else' ? void 0 : void 0 }, writeLocation((form || 0)['form'], (form || 0)['original-form']))); }.call(this); }; installWriter('try', writeTry); var writeBindingValue = function writeBindingValue(form) { return write((form || 0)['init']); }; var writeBindingParam = function writeBindingParam(form) { return writeVar({ 'form': (form || 0)['name'] }); }; var writeBinding = exports.writeBinding = function writeBinding(form) { return write({ 'op': 'def', 'var': form, 'init': (form || 0)['init'], 'form': form }); }; var writeLet = exports.writeLet = function writeLet(form) { return function () { var bodyø1 = conj(form, { 'statements': vec(concat((form || 0)['bindings'], (form || 0)['statements'])) }); return toIife(toBlock(writeBody(bodyø1))); }.call(this); }; installWriter('let', writeLet); var toRebind = exports.toRebind = function toRebind(form) { return function loop() { var recur = loop; var resultø1 = []; var bindingsø1 = (form || 0)['bindings']; do { recur = isEmpty(bindingsø1) ? resultø1 : (loop[0] = conj(resultø1, { 'type': 'AssignmentExpression', 'operator': '=', 'left': writeBindingVar(first(bindingsø1)), 'right': { 'type': 'MemberExpression', 'computed': true, 'object': { 'type': 'Identifier', 'name': 'loop' }, 'property': { 'type': 'Literal', 'value': count(resultø1) } } }), loop[1] = rest(bindingsø1), loop); } while (resultø1 = loop[0], bindingsø1 = loop[1], recur === loop); return recur; }.call(this); }; var toSequence = exports.toSequence = function toSequence(expressions) { return { 'type': 'SequenceExpression', 'expressions': expressions }; }; var toIife = exports.toIife = function toIife(body, id) { return { 'type': 'CallExpression', 'arguments': [{ 'type': 'ThisExpression' }], 'callee': { 'type': 'MemberExpression', 'computed': false, 'object': { 'type': 'FunctionExpression', 'id': id, 'params': [], 'defaults': [], 'expression': false, 'generator': false, 'rest': void 0, 'body': body }, 'property': { 'type': 'Identifier', 'name': 'call' } } }; }; var toLoopInit = exports.toLoopInit = function toLoopInit() { return { 'type': 'VariableDeclaration', 'kind': 'var', 'declarations': [{ 'type': 'VariableDeclarator', 'id': { 'type': 'Identifier', 'name': 'recur' }, 'init': { 'type': 'Identifier', 'name': 'loop' } }] }; }; var toDoWhile = exports.toDoWhile = function toDoWhile(body, test) { return { 'type': 'DoWhileStatement', 'body': body, 'test': test }; }; var toSetRecur = exports.toSetRecur = function toSetRecur(form) { return { 'type': 'AssignmentExpression', 'operator': '=', 'left': { 'type': 'Identifier', 'name': 'recur' }, 'right': write(form) }; }; var toLoop = exports.toLoop = function toLoop(form) { return toSequence(conj(toRebind(form), { 'type': 'BinaryExpression', 'operator': '===', 'left': { 'type': 'Identifier', 'name': 'recur' }, 'right': { 'type': 'Identifier', 'name': 'loop' } })); }; var writeLoop = exports.writeLoop = function writeLoop(form) { return function () { var statementsø1 = (form || 0)['statements']; var resultø1 = (form || 0)['result']; var bindingsø1 = (form || 0)['bindings']; var loopBodyø1 = conj(map(writeStatement, statementsø1), toStatement(toSetRecur(resultø1))); var bodyø1 = concat([toLoopInit()], map(write, bindingsø1), [toDoWhile(toBlock(vec(loopBodyø1)), toLoop(form))], [{ 'type': 'ReturnStatement', 'argument': { 'type': 'Identifier', 'name': 'recur' } }]); return toIife(toBlock(vec(bodyø1)), symbol(void 0, 'loop')); }.call(this); }; installWriter('loop', writeLoop); var toRecur = exports.toRecur = function toRecur(form) { return function loop() { var recur = loop; var resultø1 = []; var paramsø1 = (form || 0)['params']; do { recur = isEmpty(paramsø1) ? resultø1 : (loop[0] = conj(resultø1, { 'type': 'AssignmentExpression', 'operator': '=', 'right': write(first(paramsø1)), 'left': { 'type': 'MemberExpression', 'computed': true, 'object': { 'type': 'Identifier', 'name': 'loop' }, 'property': { 'type': 'Literal', 'value': count(resultø1) } } }), loop[1] = rest(paramsø1), loop); } while (resultø1 = loop[0], paramsø1 = loop[1], recur === loop); return recur; }.call(this); }; var writeRecur = exports.writeRecur = function writeRecur(form) { return toSequence(conj(toRecur(form), { 'type': 'Identifier', 'name': 'loop' })); }; installWriter('recur', writeRecur); var fallbackOverload = exports.fallbackOverload = function fallbackOverload() { return { 'type': 'SwitchCase', 'test': void 0, 'consequent': [{ 'type': 'ThrowStatement', 'argument': { 'type': 'CallExpression', 'callee': { 'type': 'Identifier', 'name': 'RangeError' }, 'arguments': [{ 'type': 'Literal', 'value': 'Wrong number of arguments passed' }] } }] }; }; var spliceBinding = exports.spliceBinding = function spliceBinding(form) { return { 'op': 'def', 'id': last((form || 0)['params']), 'init': { 'op': 'invoke', 'callee': { 'op': 'var', 'form': symbol(void 0, 'Array.prototype.slice.call') }, 'params': [ { 'op': 'var', 'form': symbol(void 0, 'arguments') }, { 'op': 'constant', 'form': (form || 0)['arity'], 'type': 'number' } ] } }; }; var writeOverloadingParams = exports.writeOverloadingParams = function writeOverloadingParams(params) { return reduce(function (forms, param) { return conj(forms, { 'op': 'def', 'id': param, 'init': { 'op': 'member-expression', 'computed': true, 'target': { 'op': 'var', 'form': symbol(void 0, 'arguments') }, 'property': { 'op': 'constant', 'type': 'number', 'form': count(forms) } } }); }, [], params); }; var writeOverloadingFn = exports.writeOverloadingFn = function writeOverloadingFn(form) { return function () { var overloadsø1 = map(writeFnOverload, (form || 0)['methods']); return { 'params': [], 'body': toBlock({ 'type': 'SwitchStatement', 'discriminant': { 'type': 'MemberExpression', 'computed': false, 'object': { 'type': 'Identifier', 'name': 'arguments' }, 'property': { 'type': 'Identifier', 'name': 'length' } }, 'cases': (form || 0)['variadic'] ? overloadsø1 : conj(overloadsø1, fallbackOverload()) }) }; }.call(this); }; var writeFnOverload = exports.writeFnOverload = function writeFnOverload(form) { return function () { var paramsø1 = (form || 0)['params']; var bindingsø1 = (form || 0)['variadic'] ? conj(writeOverloadingParams(butlast(paramsø1)), spliceBinding(form)) : writeOverloadingParams(paramsø1); var statementsø1 = vec(concat(bindingsø1, (form || 0)['statements'])); return { 'type': 'SwitchCase', 'test': !(form || 0)['variadic'] ? { 'type': 'Literal', 'value': (form || 0)['arity'] } : void 0, 'consequent': writeBody(conj(form, { 'statements': statementsø1 })) }; }.call(this); }; var writeSimpleFn = exports.writeSimpleFn = function writeSimpleFn(form) { return function () { var methodø1 = first((form || 0)['methods']); var paramsø1 = (methodø1 || 0)['variadic'] ? butlast((methodø1 || 0)['params']) : (methodø1 || 0)['params']; var bodyø1 = (methodø1 || 0)['variadic'] ? conj(methodø1, { 'statements': vec(cons(spliceBinding(methodø1), (methodø1 || 0)['statements'])) }) : methodø1; return { 'params': map(writeVar, paramsø1), 'body': toBlock(writeBody(bodyø1)) }; }.call(this); }; var resolve = exports.resolve = function resolve(from, to) { return function () { var requirerø1 = split(name(from), '.'); var requirementø1 = split(name(to), '.'); var isRelativeø1 = !(name(from) === name(to)) && first(requirerø1) === first(requirementø1); return isRelativeø1 ? function loop() { var recur = loop; var fromø2 = requirerø1; var toø2 = requirementø1; do { recur = first(fromø2) === first(toø2) ? (loop[0] = rest(fromø2), loop[1] = rest(toø2), loop) : join('/', concat(['.'], repeat(dec(count(fromø2)), '..'), toø2)); } while (fromø2 = loop[0], toø2 = loop[1], recur === loop); return recur; }.call(this) : join('/', requirementø1); }.call(this); }; var idToNs = exports.idToNs = function idToNs(id) { return symbol(void 0, join('*', split(name(id), '.'))); }; var writeRequire = exports.writeRequire = function writeRequire(form, requirer) { return function () { var nsBindingø1 = { 'op': 'def', 'id': { 'op': 'var', 'type': 'identifier', 'form': idToNs((form || 0)['ns']) }, 'init': { 'op': 'invoke', 'callee': { 'op': 'var', 'type': 'identifier', 'form': symbol(void 0, 'require') }, 'params': [{ 'op': 'constant', 'form': resolve(requirer, (form || 0)['ns']) }] } }; var nsAliasø1 = (form || 0)['alias'] ? { 'op': 'def', 'id': { 'op': 'var', 'type': 'identifier', 'form': idToNs((form || 0)['alias']) }, 'init': (nsBindingø1 || 0)['id'] } : void 0; var referencesø1 = reduce(function (references, form) { return conj(references, { 'op': 'def', 'id': { 'op': 'var', 'type': 'identifier', 'form': (form || 0)['rename'] || (form || 0)['name'] }, 'init': { 'op': 'member-expression', 'computed': false, 'target': (nsBindingø1 || 0)['id'], 'property': { 'op': 'var', 'type': 'identifier', 'form': (form || 0)['name'] } } }); }, [], (form || 0)['refer']); return vec(cons(nsBindingø1, nsAliasø1 ? cons(nsAliasø1, referencesø1) : referencesø1)); }.call(this); }; var writeNs = exports.writeNs = function writeNs(form) { return function () { var nodeø1 = (form || 0)['form']; var requirerø1 = (form || 0)['name']; var nsBindingø1 = { 'op': 'def', 'original-form': nodeø1, 'id': { 'op': 'var', 'type': 'identifier', 'original-form': first(nodeø1), 'form': symbol(void 0, '*ns*') }, 'init': { 'op': 'dictionary', 'form': nodeø1, 'keys': [ { 'op': 'var', 'type': 'identifier', 'original-form': nodeø1, 'form': symbol(void 0, 'id') }, { 'op': 'var', 'type': 'identifier', 'original-form': nodeø1, 'form': symbol(void 0, 'doc') } ], 'values': [ { 'op': 'constant', 'type': 'identifier', 'original-form': (form || 0)['name'], 'form': name((form || 0)['name']) }, { 'op': 'constant', 'original-form': nodeø1, 'form': (form || 0)['doc'] } ] } }; var requirementsø1 = vec(concat.apply(void 0, map(function ($1) { return writeRequire($1, requirerø1); }, (form || 0)['require']))); return toBlock(map(write, vec(cons(nsBindingø1, requirementsø1)))); }.call(this); }; installWriter('ns', writeNs); var writeFn = exports.writeFn = function writeFn(form) { return function () { var baseø1 = count((form || 0)['methods']) > 1 ? writeOverloadingFn(form) : writeSimpleFn(form); return conj(baseø1, { 'type': 'FunctionExpression', 'id': (form || 0)['id'] ? writeVar((form || 0)['id']) : void 0, 'defaults': void 0, 'rest': void 0, 'generator': false, 'expression': false }); }.call(this); }; installWriter('fn', writeFn); var write = exports.write = function write(form) { return function () { var opø1 = (form || 0)['op']; var writerø1 = isEqual('invoke', (form || 0)['op']) && isEqual('var', ((form || 0)['callee'] || 0)['op']) && (__specials__ || 0)[name(((form || 0)['callee'] || 0)['form'])]; return writerø1 ? writeSpecial(writerø1, form) : writeOp((form || 0)['op'], form); }.call(this); }; var write_ = exports.write_ = function write_() { var forms = Array.prototype.slice.call(arguments, 0); return function () { var bodyø1 = map(writeStatement, forms); return { 'type': 'Program', 'body': bodyø1, 'loc': inheritLocation(bodyø1) }; }.call(this); }; var compile = exports.compile = function compile() { switch (arguments.length) { case 1: var form = arguments[0]; return compile({}, form); default: var options = arguments[0]; var forms = Array.prototype.slice.call(arguments, 1); return generate(write_.apply(void 0, forms), options); } }; var getMacro = exports.getMacro = function getMacro() { switch (arguments.length) { case 2: var target = arguments[0]; var property = arguments[1]; return list.apply(void 0, [symbol(void 0, 'aget')].concat([list.apply(void 0, [symbol(void 0, 'or')].concat([target], [0]))], [property])); case 3: var target = arguments[0]; var property = arguments[1]; var default_ = arguments[2]; return default_ === void 0 ? list.apply(void 0, [symbol(void 0, 'get')].concat([target], [property])) : list.apply(void 0, [symbol(void 0, 'apply')].concat([symbol(void 0, 'get')], [[ target, property, default_ ]])); default: throw RangeError('Wrong number of arguments passed'); } }; installMacro('get', getMacro); var installLogicalOperator = exports.installLogicalOperator = function installLogicalOperator(callee, operator, fallback) { var writeLogicalOperator = function writeLogicalOperator() { var operands = Array.prototype.slice.call(arguments, 0); return function () { var nø1 = count(operands); return isEqual(nø1, 0) ? writeConstant(fallback) : isEqual(nø1, 1) ? write(first(operands)) : 'else' ? reduce(function (left, right) { return { 'type': 'LogicalExpression', 'operator': operator, 'left': left, 'right': write(right) }; }, write(first(operands)), rest(operands)) : void 0; }.call(this); }; return installSpecial(callee, writeLogicalOperator); }; installLogicalOperator('or', '||', void 0); installLogicalOperator('and', '&&', true); var installUnaryOperator = exports.installUnaryOperator = function installUnaryOperator(callee, operator, isPrefix) { var writeUnaryOperator = function writeUnaryOperator() { var params = Array.prototype.slice.call(arguments, 0); return count(params) === 1 ? { 'type': 'UnaryExpression', 'operator': operator, 'argument': write(first(params)), 'prefix': isPrefix } : errorArgCount(callee, count(params)); }; return installSpecial(callee, writeUnaryOperator); }; installUnaryOperator('not', '!'); installUnaryOperator('bit-not', '~'); var installBinaryOperator = exports.installBinaryOperator = function installBinaryOperator(callee, operator) { var writeBinaryOperator = function writeBinaryOperator() { var params = Array.prototype.slice.call(arguments, 0); return count(params) < 2 ? errorArgCount(callee, count(params)) : reduce(function (left, right) { return { 'type': 'BinaryExpression', 'operator': operator, 'left': left, 'right': write(right) }; }, write(first(params)), rest(params)); }; return installSpecial(callee, writeBinaryOperator); }; installBinaryOperator('bit-and', '&'); installBinaryOperator('bit-or', '|'); installBinaryOperator('bit-xor', '^'); installBinaryOperator('bit-shift-left', '<<'); installBinaryOperator('bit-shift-right', '>>'); installBinaryOperator('bit-shift-right-zero-fil', '>>>'); var installArithmeticOperator = exports.installArithmeticOperator = function installArithmeticOperator(callee, operator, isValid, fallback) { var writeBinaryOperator = function writeBinaryOperator(left, right) { return { 'type': 'BinaryExpression', 'operator': name(operator), 'left': left, 'right': write(right) }; }; var writeArithmeticOperator = function writeArithmeticOperator() { var params = Array.prototype.slice.call(arguments, 0); return function () { var nø1 = count(params); return isValid && !isValid(nø1) ? errorArgCount(name(callee), nø1) : nø1 == 0 ? writeLiteral(fallback) : nø1 == 1 ? reduce(writeBinaryOperator, writeLiteral(fallback), params) : 'else' ? reduce(writeBinaryOperator, write(first(params)), rest(params)) : void 0; }.call(this); }; return installSpecial(callee, writeArithmeticOperator); }; installArithmeticOperator('+', '+', void 0, 0); installArithmeticOperator('-', '-', function ($1) { return $1 >= 1; }, 0); installArithmeticOperator('*', '*', void 0, 1); installArithmeticOperator(keyword('/'), keyword('/'), function ($1) { return $1 >= 1; }, 1); installArithmeticOperator('rem', keyword('%'), function ($1) { return $1 == 2; }, 1); var installComparisonOperator = exports.installComparisonOperator = function installComparisonOperator(callee, operator, fallback) { var writeComparisonOperator = function writeComparisonOperator() { switch (arguments.length) { case 0: return errorArgCount(callee, 0); case 1: var form = arguments[0]; return toSequence([ write(form), writeLiteral(fallback) ]); case 2: var left = arguments[0]; var right = arguments[1]; return { 'type': 'BinaryExpression', 'operator': operator, 'left': write(left), 'right': write(right) }; default: var left = arguments[0]; var right = arguments[1]; var more = Array.prototype.slice.call(arguments, 2); return reduce(function (left, right) { return { 'type': 'LogicalExpression', 'operator': '&&', 'left': left, 'right': { 'type': 'BinaryExpression', 'operator': operator, 'left': isEqual('LogicalExpression', (left || 0)['type']) ? ((left || 0)['right'] || 0)['right'] : (left || 0)['right'], 'right': write(right) } }; }, writeComparisonOperator(left, right), more); } }; return installSpecial(callee, writeComparisonOperator); }; installComparisonOperator('==', '==', true); installComparisonOperator('>', '>', true); installComparisonOperator('>=', '>=', true); installComparisonOperator('<', '<', true); installComparisonOperator('<=', '<=', true); var isWriteIdentical = exports.isWriteIdentical = function isWriteIdentical() { var params = Array.prototype.slice.call(arguments, 0); return count(params) === 2 ? { 'type': 'BinaryExpression', 'operator': '===', 'left': write(first(params)), 'right': write(second(params)) } : errorArgCount('identical?', count(params)); }; installSpecial('identical?', isWriteIdentical); var isWriteInstance = exports.isWriteInstance = function isWriteInstance() { var params = Array.prototype.slice.call(arguments, 0); return function () { var constructorø1 = first(params); var instanceø1 = second(params); return count(params) < 1 ? errorArgCount('instance?', count(params)) : { 'type': 'BinaryExpression', 'operator': 'instanceof', 'left': instanceø1 ? write(instanceø1) : writeConstant(instanceø1), 'right': write(constructorø1) }; }.call(this); }; installSpecial('instance?', isWriteInstance); var expandApply = exports.expandApply = function expandApply(f) { var params = Array.prototype.slice.call(arguments, 1); return function () { var prefixø1 = vec(butlast(params)); return isEmpty(prefixø1) ? list.apply(void 0, [symbol(void 0, '.apply')].concat([f], [void 0], vec(params))) : list.apply(void 0, [symbol(void 0, '.apply')].concat([f], [void 0], [list.apply(void 0, [symbol(void 0, '.concat')].concat([prefixø1], [last(params)]))])); }.call(this); }; installMacro('apply', expandApply); var expandPrint = exports.expandPrint = function expandPrint(_andForm) { var more = Array.prototype.slice.call(arguments, 1); 'Prints the object(s) to the output for human consumption.'; return function () { var opø1 = withMeta(symbol(void 0, 'console.log'), meta(_andForm)); return list.apply(void 0, [opø1].concat(vec(more))); }.call(this); }; installMacro('print', withMeta(expandPrint, { 'implicit': ['&form'] })); var expandStr = exports.expandStr = function expandStr() { var forms = Array.prototype.slice.call(arguments, 0); return list.apply(void 0, [symbol(void 0, '+')].concat([''], vec(forms))); }; installMacro('str', expandStr); var expandDebug = exports.expandDebug = function expandDebug() { return symbol(void 0, 'debugger'); }; installMacro('debugger!', expandDebug); var expandAssert = exports.expandAssert = function expandAssert() { switch (arguments.length) { case 1: var x = arguments[0]; return expandAssert(x, ''); case 2: var x = arguments[0]; var message = arguments[1]; return function () { var formø1 = prStr(x); return list.apply(void 0, [symbol(void 0, 'if')].concat([list.apply(void 0, [symbol(void 0, 'not')].concat([x]))], [list.apply(void 0, [symbol(void 0, 'throw')].concat([list.apply(void 0, [symbol(void 0, 'Error')].concat([list.apply(void 0, [symbol(void 0, 'str')].concat(['Assert failed: '], [message], [formø1]))]))]))])); }.call(this); default: throw RangeError('Wrong number of arguments passed'); } }; installMacro('assert', expandAssert); var expandTypestr = exports.expandTypestr = function expandTypestr(it) { return function () { var prefixø1 = '[object '; var suffixø1 = ']'; return list.apply(void 0, [symbol(void 0, '->')].concat([list.apply(void 0, [symbol(void 0, '.call')].concat([symbol(void 0, 'Object.prototype.to-string')], [it]))], [list.apply(void 0, [symbol(void 0, '.slice')].concat([count(prefixø1)], [0 - count(suffixø1)]))])); }.call(this); }; var expandDefprotocol = exports.expandDefprotocol = function expandDefprotocol(_andEnv, id) { var forms = Array.prototype.slice.call(arguments, 2); return function