Mercurial > repos > tabletprog
comparison cbackend.js @ 43:27a2167663dd
Improve compiler error reporting. Fix operator associativity. Add some more string operations and a string ops sample
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 12 Jul 2012 22:10:58 -0700 |
parents | 4e983fe32047 |
children | 2a9c6eed0c70 |
comparison
equal
deleted
inserted
replaced
42:4e983fe32047 | 43:27a2167663dd |
---|---|
38 } | 38 } |
39 return obj; | 39 return obj; |
40 } | 40 } |
41 | 41 |
42 op.prototype.toC = function(isReceiver) { | 42 op.prototype.toC = function(isReceiver) { |
43 var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_'}; | 43 var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', '.': 'CAT_'}; |
44 var method = optoMeth[this.op]; | 44 var method = optoMeth[this.op]; |
45 return 'mcall(' + getMethodId(method) + ', 2, ' + this.left.toC() + ', ' + this.right.toC() + ')\n'; | 45 return 'mcall(' + getMethodId(method) + ', 2, ' + this.left.toC() + ', ' + this.right.toC() + ')\n'; |
46 }; | 46 }; |
47 | 47 |
48 function escapeCName(name) | 48 function escapeCName(name) |
120 var nextStringId = 0; | 120 var nextStringId = 0; |
121 | 121 |
122 strlit.prototype.toC = function() { | 122 strlit.prototype.toC = function() { |
123 if (!(this.val in declaredStrings)) { | 123 if (!(this.val in declaredStrings)) { |
124 //TODO: get the proper byte length | 124 //TODO: get the proper byte length |
125 toplevelcode += 'string str_' + nextStringId + ' = {{&string_meta, NULL}, ' + this.val.length + ', ' + this.val.length + ', ' + this.val.length + ', "' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '"};\n'; | 125 toplevelcode += 'string str_' + nextStringId + ' = {{&string_meta, NULL}, ' + this.val.length + ', ' + this.val.length + ', "' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '"};\n'; |
126 declaredStrings[this.val] = nextStringId++; | 126 declaredStrings[this.val] = nextStringId++; |
127 } | 127 } |
128 return '((object *)&str_' + declaredStrings[this.val] + ')'; | 128 return '((object *)&str_' + declaredStrings[this.val] + ')'; |
129 } | 129 } |
130 | 130 |
377 addCompOp(int32, 'GT_', '>', 'obj_int32'); | 377 addCompOp(int32, 'GT_', '>', 'obj_int32'); |
378 addCompOp(int32, 'EQ_', '==', 'obj_int32'); | 378 addCompOp(int32, 'EQ_', '==', 'obj_int32'); |
379 addCompOp(int32, 'NEQ_', '!=', 'obj_int32'); | 379 addCompOp(int32, 'NEQ_', '!=', 'obj_int32'); |
380 addCompOp(int32, 'GEQ_', '>=', 'obj_int32'); | 380 addCompOp(int32, 'GEQ_', '>=', 'obj_int32'); |
381 addCompOp(int32, 'LEQ_', '<=', 'obj_int32'); | 381 addCompOp(int32, 'LEQ_', '<=', 'obj_int32'); |
382 int32.addMessage('string', { | |
383 vars: {str: 'string *'}, | |
384 lines: [ | |
385 'str = (string *)make_object(&string_meta, NULL, 0);', | |
386 'str->data = malloc(12);', | |
387 'sprintf(str->data, "%d", self->num);', | |
388 'str->length = str->bytes = strlen(str->data);', | |
389 'return (object *)str;' | |
390 ] | |
391 }); | |
382 var array = new cObject('array'); | 392 var array = new cObject('array'); |
383 array.addProperty('size', null, 'uint32_t'); | 393 array.addProperty('size', null, 'uint32_t'); |
384 array.addProperty('storage', null, 'uint32_t'); | 394 array.addProperty('storage', null, 'uint32_t'); |
385 array.addProperty('data', null, 'object **'); | 395 array.addProperty('data', null, 'object **'); |
386 array.addMessage('get', { | 396 array.addMessage('get', { |
432 ] | 442 ] |
433 }); | 443 }); |
434 var string = new cObject('string'); | 444 var string = new cObject('string'); |
435 string.addProperty('length', null, 'uint32_t'); | 445 string.addProperty('length', null, 'uint32_t'); |
436 string.addProperty('bytes', null, 'uint32_t'); | 446 string.addProperty('bytes', null, 'uint32_t'); |
437 string.addProperty('storage', null, 'uint32_t'); | |
438 string.addProperty('data', null, 'char *'); | 447 string.addProperty('data', null, 'char *'); |
439 string.addMessage('length', { | 448 string.addMessage('length', { |
440 vars: {intret: 'obj_int32 *'}, | 449 vars: {intret: 'obj_int32 *'}, |
441 lines: [ | 450 lines: [ |
442 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', | 451 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', |
443 'intret->num = self->length;', | 452 'intret->num = self->length;', |
453 'return &(intret->header);' | |
454 ] | |
455 }); | |
456 string.addMessage('byte_length', { | |
457 vars: {intret: 'obj_int32 *'}, | |
458 lines: [ | |
459 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', | |
460 'intret->num = self->bytes;', | |
444 'return &(intret->header);' | 461 'return &(intret->header);' |
445 ] | 462 ] |
446 }); | 463 }); |
447 string.addMessage('EQ_', { | 464 string.addMessage('EQ_', { |
448 vars: {argb: 'string *'}, | 465 vars: {argb: 'string *'}, |
457 string.addMessage('print', { | 474 string.addMessage('print', { |
458 vars: {}, | 475 vars: {}, |
459 lines: [ | 476 lines: [ |
460 'fwrite(self->data, 1, self->bytes, stdout);', | 477 'fwrite(self->data, 1, self->bytes, stdout);', |
461 'return self;' | 478 'return self;' |
479 ] | |
480 }); | |
481 string.addMessage('string', { | |
482 vars: {}, | |
483 lines: [ 'return self;' ] | |
484 }); | |
485 string.addMessage('CAT_', { | |
486 vars: {argbo: 'object *', argb: 'string *', out: 'string *'}, | |
487 lines: [ | |
488 'argbo = va_arg(args, object *);', | |
489 'argb = mcall(' + getMethodId('string') + ', 1, argbo);', | |
490 'out = (string *)make_object(&string_meta, NULL, 0);', | |
491 'out->bytes = self->bytes + argb->bytes;', | |
492 'out->length = self->length + argb->length;', | |
493 'out->data = malloc(out->bytes+1);', | |
494 'memcpy(out->data, self->data, self->bytes);', | |
495 'memcpy(out->data + self->bytes, argb->data, argb->bytes + 1);', | |
496 'return out;' | |
462 ] | 497 ] |
463 }); | 498 }); |
464 forwarddec = toplevelcode = ''; | 499 forwarddec = toplevelcode = ''; |
465 forwarddec += int32.toEarlyCDef() + array.toEarlyCDef() + string.toEarlyCDef(); | 500 forwarddec += int32.toEarlyCDef() + array.toEarlyCDef() + string.toEarlyCDef(); |
466 toplevelcode += int32.toCDef() + array.toCDef() + string.toCDef(); | 501 toplevelcode += int32.toCDef() + array.toCDef() + string.toCDef(); |