# HG changeset patch # User Mike Pavone # Date 1342991914 25200 # Node ID 25bc8a5ab41ef563e6928f33feb1ea5a9f5e37eb # Parent ce6a81b3be7038e987db6818fa4c2f22a1c58122 Improve llMessage a bit and move implementation of string into string.tp module using llMessage. Update TASKS list diff -r ce6a81b3be70 -r 25bc8a5ab41e TASKS --- a/TASKS Sun Jul 22 14:17:33 2012 -0700 +++ b/TASKS Sun Jul 22 14:18:34 2012 -0700 @@ -1,6 +1,3 @@ -Convert string object to new style using llMessage:withVars:andCode - AssignedTo: Mike - Status: in-progress Improve string library Add basic UTF-8 support Implement import: in C backend @@ -12,3 +9,8 @@ Add support for actors Check for breakage in Javascript backend and fix it Port all library stuff from C backend to Javascript backend +Fix block comments in grammar +Add dict literals to grammar and compiler +Re-write compiler in TP +Finish type system design +Implement type system \ No newline at end of file diff -r ce6a81b3be70 -r 25bc8a5ab41e cbackend.js --- a/cbackend.js Sun Jul 22 14:17:33 2012 -0700 +++ b/cbackend.js Sun Jul 22 14:18:34 2012 -0700 @@ -45,7 +45,8 @@ return 'mcall(' + getMethodId(method) + '/* ' + method + ' */, 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n'; }; op.prototype.toCLLExpr = function(vars) { - return this.left.toCLLExpr(vars) + (this.op == '=' ? '==' : this.op) + this.right.toCLLExpr(vars); + var opmap = {'=': '==', 'xor': '^'}; + return this.left.toCLLExpr(vars) + (this.op in opmap ? opmap[this.op] : this.op) + this.right.toCLLExpr(vars); }; op.prototype.toCLines = function(vars, needsreturn) { return [ (needsreturn ? 'return (object *)' : '' ) + this.toCLLExpr(vars) + ';']; @@ -141,7 +142,7 @@ if (info.isll || !(info.def instanceof lambda)) { return 'self->' + name; } else { - return 'mcall(' + getMethodId(name) + '/* ' + name + ' */, 1, ' + (new symbol('self', this.symbols)).toC() + ')'; + return 'mcall(' + getMethodId(name) + '/* ' + name + ' */, 1, self)'; } } throw new Error('Unsupported reference type ' + info.type + ' for variable ' + name); @@ -231,7 +232,7 @@ var method = false; var funinfo = this.symbols.find(name); var start = 0; - if (!funinfo || funinfo.def instanceof setter) { + if (!funinfo || funinfo.def instanceof setter || funinfo.type == 'toplevel') { method = true; } else { switch(funinfo.type) @@ -349,9 +350,11 @@ switch(name) { case 'if': + return '((' + args[0].toCLLExpr(vars) + ') ? (' + args[1].toCLLExpr(vars) + ') : 0)'; case 'if:else': + return '((' + args[0].toCLLExpr(vars) + ') ? (' + args[1].toCLLExpr(vars) + ') : (' + args[2].toCLLExpr(vars) + '))'; case 'while:do': - throw new Error('if, if:else and while:do not allow in expression context in llMessage block'); + throw new Error('while:do not allowed in expression context in llMessage block'); case 'addr_of': return '&(' + args[0].toCLLExpr(vars) + ')'; case 'sizeof': @@ -362,6 +365,10 @@ return args[0].toCLLExpr(vars) + '[' + args[1].toCLLExpr(vars) + '] = ' + args[2].toCLLExpr(vars); case 'not': return '!(' + args[0].toCLLExpr(vars) + ')'; + case 'mcall': + if (args[0] instanceof symbol) { + args[0] = new intlit(getMethodId(args[0].name)); + } default: for (var i in args) { args[i] = args[i].toCLLExpr(vars); @@ -627,7 +634,7 @@ 'str = (string *)make_object(&string_meta, NULL, 0);', 'str->data = GC_MALLOC(12);', 'sprintf(str->data, "%d", self->num);', - 'str->length = str->bytes = strlen(str->data);', + 'str->len = str->bytes = strlen(str->data);', 'return &(str->header);' ] }); @@ -651,104 +658,11 @@ function makeString() { - var string = new cObject('string'); - string.addProperty('length', null, 'uint32_t'); - string.addProperty('bytes', null, 'uint32_t'); - string.addProperty('data', null, 'char *'); - string.addMessage('length', { - vars: {intret: 'obj_int32 *'}, - lines: [ - 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', - 'intret->num = self->length;', - 'return &(intret->header);' - ] - }); - string.addMessage('byte_length', { - vars: {intret: 'obj_int32 *'}, - lines: [ - 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', - 'intret->num = self->bytes;', - 'return &(intret->header);' - ] - }); - string.addMessage('EQ_', { - vars: {argb: 'string *'}, - lines: [ - 'argb = va_arg(args, string *);', - 'if (self->length == argb->length && self->bytes == argb->bytes && !memcmp(self->data, argb->data, self->bytes)) {', - ' return ' + toplevel.moduleVar('true') + ';', - '}', - 'return ' + toplevel.moduleVar('false') + ';', - ] - }); - string.addMessage('NEQ_', { - vars: {argb: 'string *'}, - lines: [ - 'argb = va_arg(args, string *);', - 'if (self->length != argb->length || self->bytes != argb->bytes || memcmp(self->data, argb->data, self->bytes)) {', - ' return ' + toplevel.moduleVar('true') + ';', - '}', - 'return ' + toplevel.moduleVar('false') + ';', - ] - }); - string.addMessage('print', { - vars: {}, - lines: [ - 'fwrite(self->data, 1, self->bytes, stdout);', - 'return &(self->header);' - ] - }); - string.addMessage('string', { - vars: {}, - lines: [ 'return &(self->header);' ] - }); - string.addMessage('CAT_', { - vars: {argbo: 'object *', argb: 'string *', out: 'string *'}, - lines: [ - 'argbo = va_arg(args, object *);', - 'argb = (string *)mcall(' + getMethodId('string') + ', 1, argbo);', - 'out = (string *)make_object(&string_meta, NULL, 0);', - 'out->bytes = self->bytes + argb->bytes;', - 'out->length = self->length + argb->length;', - 'out->data = GC_MALLOC_ATOMIC(out->bytes+1);', - 'memcpy(out->data, self->data, self->bytes);', - 'memcpy(out->data + self->bytes, argb->data, argb->bytes + 1);', - 'return &(out->header);' - ] - }); - string.addMessage('byte', { - vars: {index: 'obj_int32 *', intret: 'obj_int32 *'}, - lines: [ - 'index = va_arg(args, obj_int32 *);', - 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', - 'intret->num = index->num < self->bytes ? self->data[index->num] : 0;', - 'return &(intret->header);' - ] - }); - string.addMessage('int32', { - vars: {intret: 'obj_int32 *'}, - lines: [ - 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', - 'intret->num = atoi(self->data);', - 'return &(intret->header);' - ] - }); - string.addMessage('hash', { - vars: {intret: 'obj_int32 *', i: 'uint32_t'}, - lines: [ - 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', - 'intret->num = 0;', - 'if (self->bytes) {', - ' intret->num = self->data[0] << 7;', - ' for (i = 0; i < self->bytes; i++) {', - ' intret->num = (1000003 * intret->num) ^ self->data[i];', - ' }', - ' intret->num = intret->num ^ self->bytes;', - '}', - 'return &(intret->header);' - ] - }); - return string; + var arrayfile = toplevel.names['string']; + var ast = parseFile(arrayfile.path + '/' + arrayfile.file); + ast.name = 'string'; + ast.populateSymbols(toplevel); + return ast.toCObject(); } function makelambda() diff -r ce6a81b3be70 -r 25bc8a5ab41e runtime/progfoot.inc --- a/runtime/progfoot.inc Sun Jul 22 14:17:33 2012 -0700 +++ b/runtime/progfoot.inc Sun Jul 22 14:18:34 2012 -0700 @@ -43,7 +43,7 @@ for (i = 0; i < argc; ++i) { arg = (string *)make_object(&string_meta, NULL, 0); arg->data = argv[i]; - arg->bytes = arg->length = strlen(argv[i]); + arg->bytes = arg->len = strlen(argv[i]); arr->data[i] = &(arg->header); } object * ret = mcall(METHOD_ID_MAIN, 2, mainModule(), &(arr->header));