# HG changeset patch # User Mike Pavone # Date 1342164218 25200 # Node ID 2a9c6eed0c705942f390021c57e520476924560f # Parent 9dd370530f69d5b06a399f892c09160b08714d7d Move closure/lambda object def into compiler rather than runtime code. Add while:do method to lambda diff -r 9dd370530f69 -r 2a9c6eed0c70 cbackend.js --- a/cbackend.js Thu Jul 12 22:49:08 2012 -0700 +++ b/cbackend.js Fri Jul 13 00:23:38 2012 -0700 @@ -365,7 +365,7 @@ }); } -function makeCProg(obj) +function makeInt32() { var int32 = new cObject('obj_int32'); int32.addProperty('num', null, 'int32_t'); @@ -389,6 +389,11 @@ 'return (object *)str;' ] }); + return int32; +} + +function makeArray() +{ var array = new cObject('array'); array.addProperty('size', null, 'uint32_t'); array.addProperty('storage', null, 'uint32_t'); @@ -414,9 +419,9 @@ ] }); array.addMessage('foreach', { - vars: {index: 'obj_int32 *', i: 'int32_t', clos: 'closure *'}, + vars: {index: 'obj_int32 *', i: 'int32_t', clos: 'lambda *'}, lines: [ - 'clos = va_arg(args, closure *);', + 'clos = va_arg(args, lambda *);', 'for (i = 0; i < self->size; i++) {', ' index = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', ' index->num = i;', @@ -441,6 +446,11 @@ 'return self;' ] }); + return array; +} + +function makeString() +{ var string = new cObject('string'); string.addProperty('length', null, 'uint32_t'); string.addProperty('bytes', null, 'uint32_t'); @@ -496,9 +506,51 @@ 'return out;' ] }); + string.addMessage('byte', { + vars: {index: 'obj_int32 *', intret: 'obj_int32 *'}, + lines: [ + 'index = va_arg(args, obj_int32 *);', + 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret->num = index->num < self->bytes ? self->data[index->num] : 0;', + 'return intret;' + ] + }); + return string; +} + +function makelambda() +{ + var clos = new cObject('lambda'); + clos.addProperty('env', null, 'void *'); + clos.addProperty('func', null, 'closure_func'); + clos.addMessage('while:do', { + vars: {action: 'lambda *', valtrue: 'object *', ret: 'object *'}, + lines: [ + 'action = va_arg(args, lambda *);', + 'valtrue = mcall(METHOD_ID_TRUE, 1, main_module);', + 'ret = valtrue;', + 'while(valtrue == ccall(self, 0)) {', + ' ccall(action, 0);', + '}', + 'return ret;' + ] + }); + return clos; +} + +function builtinTypes() +{ + return [makeInt32(), makeArray(), makeString(), makelambda()]; +} + +function makeCProg(obj) +{ + var builtins = builtinTypes(); forwarddec = toplevelcode = ''; - forwarddec += int32.toEarlyCDef() + array.toEarlyCDef() + string.toEarlyCDef(); - toplevelcode += int32.toCDef() + array.toCDef() + string.toCDef(); + for (var i in builtins) { + forwarddec += builtins[i].toEarlyCDef(); + toplevelcode += builtins[i].toCDef(); + } obj.populateSymbols(toplevel); var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n'; return '#include "runtime/proghead.inc"\n' + @@ -581,9 +633,9 @@ } else { var envvar = 'myenv'; } - return 'make_closure(' + envvar + ', lambda_' + mynum + ')'; + return 'make_lambda(' + envvar + ', lambda_' + mynum + ')'; } else { - toplevelcode += 'closure lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n'; + toplevelcode += 'lambda lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n'; return '((object *)&lambda_obj_' + mynum + ')'; } } diff -r 9dd370530f69 -r 2a9c6eed0c70 runtime/object.c --- a/runtime/object.c Thu Jul 12 22:49:08 2012 -0700 +++ b/runtime/object.c Fri Jul 13 00:23:38 2012 -0700 @@ -21,16 +21,6 @@ return newobj; } -object * make_closure(void * env, closure_func func) -{ - closure * ret = malloc(sizeof(closure)); - ret->header.meta = &lambda_meta; - ret->header.parent = NULL; - ret->env = env; - ret->func = func; - return (object *) ret; -} - object * mcall(uint32_t method_id, uint32_t num_args, object * self, ...) { va_list args; diff -r 9dd370530f69 -r 2a9c6eed0c70 runtime/object.h --- a/runtime/object.h Thu Jul 12 22:49:08 2012 -0700 +++ b/runtime/object.h Fri Jul 13 00:23:38 2012 -0700 @@ -15,14 +15,14 @@ typedef object * (*method)(uint32_t method_id, uint32_t num_args, object * self, va_list args); typedef object * (*closure_func)(void *, uint32_t, ...); - +/* typedef struct closure { object header; void * env; closure_func func; } closure; - +*/ struct obj_meta { uint32_t size; @@ -32,10 +32,10 @@ extern obj_meta lambda_meta; object * mcall(uint32_t method_id, uint32_t num_args, object * self, ...); -#define ccall(clos, num_args, ...) (((closure *)clos)->func(((closure *)clos)->env, num_args,##__VA_ARGS__)) +#define ccall(clos, num_args, ...) (((lambda *)clos)->func(((lambda *)clos)->env, num_args,##__VA_ARGS__)) object * make_object(obj_meta * meta, void * parent, int num_props, ...); -object * make_closure(void * env, closure_func func); +object * make_lambda(void * env, closure_func func); object * make_array(uint32_t num_els, ...); #endif //OBJECT_H_ diff -r 9dd370530f69 -r 2a9c6eed0c70 runtime/progfoot.inc --- a/runtime/progfoot.inc Thu Jul 12 22:49:08 2012 -0700 +++ b/runtime/progfoot.inc Fri Jul 13 00:23:38 2012 -0700 @@ -18,6 +18,16 @@ return &(arr->header); } +object * make_lambda(void * env, closure_func func) +{ + lambda * ret = malloc(sizeof(lambda)); + ret->header.meta = &lambda_meta; + ret->header.parent = NULL; + ret->env = env; + ret->func = func; + return (object *) ret; +} + int main(int argc, char ** argv) { object * ret = mcall(METHOD_ID_MAIN, 1, mainModule()); diff -r 9dd370530f69 -r 2a9c6eed0c70 runtime/proghead.inc --- a/runtime/proghead.inc Thu Jul 12 22:49:08 2012 -0700 +++ b/runtime/proghead.inc Fri Jul 13 00:23:38 2012 -0700 @@ -12,9 +12,9 @@ exit(0); return NULL; } - +/* obj_meta lambda_meta = { sizeof(closure), {no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl, no_impl} -}; +};*/ diff -r 9dd370530f69 -r 2a9c6eed0c70 tpc.js --- a/tpc.js Thu Jul 12 22:49:08 2012 -0700 +++ b/tpc.js Fri Jul 13 00:23:38 2012 -0700 @@ -17,10 +17,8 @@ load('compiler.js'); load('cbackend.js'); try { - var parsed = parser.parse(text); - var c = parsed.toCModule(); - print(c); - } catch(error if error.name == 'SyntaxError') { + var parsed = parser.parse(text); + } catch (e) { print('SyntaxError on at', error.line, ',', error.column, ':', error.message); var lines = text.split('\n'); print(lines[error.line-1]); @@ -33,6 +31,8 @@ } } print(spacer + '^'); - + exit(1); } + var c = parsed.toCModule(); + print(c); }