# HG changeset patch # User Mike Pavone # Date 1376456460 25200 # Node ID 869399ff7faa1358f111b69c3d91f5c5a5aee0d3 # Parent 18598163e3ef89e18bca35acb0d80efa1f7dae8e# Parent 9d8ae39e8e67c041e700b1761f5e7b7e661577a1 Merge diff -r 9d8ae39e8e67 -r 869399ff7faa cbackend.js --- a/cbackend.js Sun Aug 11 04:03:08 2013 -0700 +++ b/cbackend.js Tue Aug 13 22:01:00 2013 -0700 @@ -15,7 +15,9 @@ function getOpMethodName(opname) { - var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '%': 'MOD_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', '.': 'CAT_', '&&':'if', '||':'ifnot'}; + var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '%': 'MOD_', + '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', + '.': 'CAT_', '&&':'if', '||':'ifnot', '|': 'CONS_'}; if (opname in optoMeth) { return optoMeth[opname]; } else { @@ -25,7 +27,11 @@ op.prototype.toC = function(isReceiver) { var method = getOpMethodName(this.op); - return 'mcall(' + getMethodId(method) + '/* operator ' + method + ' */, 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n'; + if (this.op == '|') { + return 'mcall(' + getMethodId(method) + '/* operator ' + method + ' */, 2, (object *)' + this.right.toC() + ', ' + this.left.toC() + ')\n'; + } else { + return 'mcall(' + getMethodId(method) + '/* operator ' + method + ' */, 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n'; + } }; op.prototype.toCLLExpr = function(vars) { var opmap = {'=': '==', 'xor': '^'}; @@ -182,7 +188,7 @@ listlit.prototype.toC = function() { var ret = 'make_list(' + this.val.length; - for (var i = 0; i < this.val.length; i++) { + for (var i = this.val.length-1; i >= 0; i--) { ret += ', ' + this.val[i].toC(); } return ret + ')'; @@ -925,7 +931,7 @@ function processUsedToplevel(toplevel) { - var alwaysused = ['true', 'false']; + var alwaysused = ['true', 'false', 'list']; var ret = ''; var modulenum = 0; var visited = {}; @@ -978,6 +984,8 @@ var rest = 'object * mainModule() {\n' + moduleinit + '\tmain_module = ' + obj.toCModuleInstance() + ';\n\treturn main_module;\n}\n'; return '#include "runtime/proghead.inc"\n' + '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' + + '#define METHOD_ID_EMPTY ' + getMethodId('empty') + '\n' + + '#define METHOD_ID_CONS ' + getMethodId(getOpMethodName('|')) + '\n' + forwarddec + toplevelcode + rest + '#include "runtime/progfoot.inc"\n'; } diff -r 9d8ae39e8e67 -r 869399ff7faa compiler.js --- a/compiler.js Sun Aug 11 04:03:08 2013 -0700 +++ b/compiler.js Tue Aug 13 22:01:00 2013 -0700 @@ -99,7 +99,7 @@ if (!(name in this.names)) { throw new Error('symbol ' + name + ' not found at toplevel'); } - if (name == 'true' || name == 'false') { + if (name == 'true' || name == 'false' || name == 'list') { return 'module_' + name; } if (!this.names[name].modulevar) { @@ -230,11 +230,8 @@ }; } else { if (nestedcall) { - if (!(name in this.closedover)) { - debugprint('//' + name + ' is now closed over'); - this.closedover[name] = true; - this.passthruenv = false; - } + this.closedover[name] = true; + this.passthruenv = false; } if (name in this.closedover) { var ret = { @@ -417,19 +414,13 @@ } } -funcall.prototype.predefSymbolsObject = function(symbols) { -}; - funcall.prototype.populateSymbolsObject = function(symbols) { this.populateSymbols(symbols); -}; +} object.prototype.populateSymbols = function(symbols) { var symbols = new osymbols(symbols); for (var i in this.messages) { - this.messages[i].predefSymbolsObject(symbols); - } - for (var i in this.messages) { this.messages[i].populateSymbolsObject(symbols); } this.symbols = symbols; @@ -465,17 +456,14 @@ this.expression.populateSymbols(symbols); this.symbols = symbols; }; -assignment.prototype.predefSymbolsObject = function(symbols) { - debugprint('//messagedef', this.symbol.name, 'predefSymbolsObject'); +assignment.prototype.populateSymbolsObject = function(symbols) { + debugprint('//messagedef', this.symbol.name, 'populateSymbols'); if (this.expression instanceof lambda || (this.expression instanceof funcall & this.expression.name == 'foreign:')) { symbols.defineMsg(this.symbol.name, this.expression); } else { symbols.defineMsg(this.symbol.name, new getter(null)); symbols.defineMsg(this.symbol.name + '!', new setter(null)); } -}; -assignment.prototype.populateSymbolsObject = function(symbols) { - debugprint('//messagedef', this.symbol.name, 'populateSymbols'); this.symbol.populateSymbols(symbols); this.expression.populateSymbols(symbols, true); this.symbols = symbols; diff -r 9d8ae39e8e67 -r 869399ff7faa modules/list.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/list.tp Tue Aug 13 22:01:00 2013 -0700 @@ -0,0 +1,48 @@ +{ + _empty <- #{ + length <- { 0 } + empty? <- { true } + fold:with <- :acc :fun { acc } + foldr:with <- :acc :fun { acc } + map <- :fun { self } + | <- :val { + list node: val withTail: self + } + . <- :right { right } + } + #{ + empty <- { _empty } + node:withTail <- :_val :_tail { + #{ + value <- { _val } + tail <- { _tail } + empty? <- { false } + length <- { + fold: 0 with: :acc val { acc + 1 } + } + fold:with <- :acc :fun { + cur <- self + while: { not: (cur empty?)} do: { + acc <- fun: acc (cur value) + cur <- cur tail + } + acc + } + foldr:with <- :acc fun { + fun: (_tail foldr: acc with: fun) _val + } + map <- :fun { + node: (fun: _val) withTail: (_tail map: fun) + } + | <- :val { + node: val withTail: self + } + . <- :right { + foldr: right with: :tail val { + node: val withTail: tail + } + } + } + } + } +} diff -r 9d8ae39e8e67 -r 869399ff7faa parser.js --- a/parser.js Sun Aug 11 04:03:08 2013 -0700 +++ b/parser.js Tue Aug 13 22:01:00 2013 -0700 @@ -84,7 +84,9 @@ 'hws = ([ \\t] / "/*" ([^*] / "*" ! "/")* "*/" )*;' + 'expr = e:(funcall / methcall / opexpr) ws { return e; };' + 'opexpr = left:compareop pieces:(hws ("&&" / "||") hws compareop)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ -'compareop = left:addsub pieces:(hws ("<=" / ">=" / "<" / ">" / "=" / "!=") hws addsub)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ +'compareop = left:maybecons pieces:(hws ("<=" / ">=" / "<" / ">" / "=" / "!=") hws maybecons)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ +'maybecons = consop / addsub;' + +'consop = left:addsub hws "|" hws right:maybecons { return new op(left, "|", right); };'+ 'addsub = left:muldiv pieces:(hws ("+"/"-"/"xor"/"and"/"or"/".") hws muldiv)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 'muldiv = left:primlitsym pieces:(hws ("*"/"/"/"%") hws primlitsym)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 'primlitsym = hws val:(float / hex / binary / int / string / symbol / object / array / list / lambda / "(" ws expr:expr hws ")" { return expr; }) { return val; };' + @@ -99,7 +101,7 @@ 'object = "#{" ws messages:(assignment / funexpr)* "}" { return new object(messages); };' + 'array = "#[" ws els:opexpr* "]" { return new arraylit(els); };' + 'list = "[" ws els:opexpr* "]" { return new listlit(els); };' + -'opsym = name:("&&" / "||" / "<=" / ">=" / "<" / ">" / "=" / "!=" / "+" / "-" / "." / "*" / "/" / "%") { return new symbol(name); };' + +'opsym = name:("&&" / "||" / "<=" / ">=" / "<" / ">" / "=" / "!=" / "+" / "-" / "." / "*" / "/" / "%" / "|") { return new symbol(name); };' + 'assignment = ws sym:(symbol / opsym) hws "<-" expr:expr ws { return new assignment(sym, expr); }' + 'lambda = args:((& ":") argname+ )? "{" ws exprs:(assignment / expr)* "}" { return new lambda(args[1], exprs); };' + 'argname = init:":"? chars:[a-zA-Z_!?@]+ trailing:[a-zA-Z_!?@0-9]* hws { return new symbol(init + chars.join("") + trailing.join("")); };' + diff -r 9d8ae39e8e67 -r 869399ff7faa runtime/object.h --- a/runtime/object.h Sun Aug 11 04:03:08 2013 -0700 +++ b/runtime/object.h Tue Aug 13 22:01:00 2013 -0700 @@ -37,5 +37,6 @@ object * make_object(obj_meta * meta, void * parent, int num_props, ...); object * make_lambda(void * env, closure_func func); object * make_array(uint32_t num_els, ...); +object * make_list(uint32_t num_els, ...); #endif //OBJECT_H_ diff -r 9d8ae39e8e67 -r 869399ff7faa runtime/progfoot.inc --- a/runtime/progfoot.inc Sun Aug 11 04:03:08 2013 -0700 +++ b/runtime/progfoot.inc Tue Aug 13 22:01:00 2013 -0700 @@ -16,7 +16,7 @@ { va_list els; int i; - array * arr = alloc_array(num_els); + array * arr = alloc_array(num_els); va_start(els, num_els); for (i = 0; i < num_els; i++) arr->data[i] = va_arg(els, object *); @@ -24,6 +24,18 @@ return &(arr->header); } +object * make_list(uint32_t num_els, ...) +{ + va_list els; + int i; + object * cur = mcall(METHOD_ID_EMPTY, 1, module_list); + va_start(els, num_els); + for (i = 0; i < num_els; i++) + cur = mcall(METHOD_ID_CONS, 2, cur, va_arg(els, object *)); + va_end(els); + return cur; +} + object * make_lambda(void * env, closure_func func) { lambda * ret = GC_MALLOC(sizeof(lambda)); diff -r 9d8ae39e8e67 -r 869399ff7faa samples/slist.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/slist.tp Tue Aug 13 22:01:00 2013 -0700 @@ -0,0 +1,13 @@ +#{ + sum <- :l { + l fold: 0 with: :acc el { + acc + el + } + } + main <- { + print: (string: (sum: [])) . "\n" + print: (string: (sum: [1 2 3 4])) . "\n" + print: (string: (sum: 1 | 2 | 3 | 4 | [])) . "\n" + print: (string: (sum: [1 2] . [3 4])) . "\n" + } +}