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();