comparison cbackend.js @ 45:2a9c6eed0c70

Move closure/lambda object def into compiler rather than runtime code. Add while:do method to lambda
author Mike Pavone <pavone@retrodev.com>
date Fri, 13 Jul 2012 00:23:38 -0700
parents 27a2167663dd
children 18ab96287c3a
comparison
equal deleted inserted replaced
44:9dd370530f69 45:2a9c6eed0c70
363 'return mcall(METHOD_ID_FALSE, 1, main_module);' 363 'return mcall(METHOD_ID_FALSE, 1, main_module);'
364 ] 364 ]
365 }); 365 });
366 } 366 }
367 367
368 function makeCProg(obj) 368 function makeInt32()
369 { 369 {
370 var int32 = new cObject('obj_int32'); 370 var int32 = new cObject('obj_int32');
371 int32.addProperty('num', null, 'int32_t'); 371 int32.addProperty('num', null, 'int32_t');
372 addBinaryOp(int32, 'ADD_', '+', 'obj_int32'); 372 addBinaryOp(int32, 'ADD_', '+', 'obj_int32');
373 addBinaryOp(int32, 'SUB_', '-', 'obj_int32'); 373 addBinaryOp(int32, 'SUB_', '-', 'obj_int32');
387 'sprintf(str->data, "%d", self->num);', 387 'sprintf(str->data, "%d", self->num);',
388 'str->length = str->bytes = strlen(str->data);', 388 'str->length = str->bytes = strlen(str->data);',
389 'return (object *)str;' 389 'return (object *)str;'
390 ] 390 ]
391 }); 391 });
392 return int32;
393 }
394
395 function makeArray()
396 {
392 var array = new cObject('array'); 397 var array = new cObject('array');
393 array.addProperty('size', null, 'uint32_t'); 398 array.addProperty('size', null, 'uint32_t');
394 array.addProperty('storage', null, 'uint32_t'); 399 array.addProperty('storage', null, 'uint32_t');
395 array.addProperty('data', null, 'object **'); 400 array.addProperty('data', null, 'object **');
396 array.addMessage('get', { 401 array.addMessage('get', {
412 '}', 417 '}',
413 'return (object *)self;' 418 'return (object *)self;'
414 ] 419 ]
415 }); 420 });
416 array.addMessage('foreach', { 421 array.addMessage('foreach', {
417 vars: {index: 'obj_int32 *', i: 'int32_t', clos: 'closure *'}, 422 vars: {index: 'obj_int32 *', i: 'int32_t', clos: 'lambda *'},
418 lines: [ 423 lines: [
419 'clos = va_arg(args, closure *);', 424 'clos = va_arg(args, lambda *);',
420 'for (i = 0; i < self->size; i++) {', 425 'for (i = 0; i < self->size; i++) {',
421 ' index = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 426 ' index = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
422 ' index->num = i;', 427 ' index->num = i;',
423 ' ccall(clos, 2, index, self->data[i]);', 428 ' ccall(clos, 2, index, self->data[i]);',
424 '}', 429 '}',
439 '}', 444 '}',
440 'self->data[self->size++] = va_arg(args, object *);', 445 'self->data[self->size++] = va_arg(args, object *);',
441 'return self;' 446 'return self;'
442 ] 447 ]
443 }); 448 });
449 return array;
450 }
451
452 function makeString()
453 {
444 var string = new cObject('string'); 454 var string = new cObject('string');
445 string.addProperty('length', null, 'uint32_t'); 455 string.addProperty('length', null, 'uint32_t');
446 string.addProperty('bytes', null, 'uint32_t'); 456 string.addProperty('bytes', null, 'uint32_t');
447 string.addProperty('data', null, 'char *'); 457 string.addProperty('data', null, 'char *');
448 string.addMessage('length', { 458 string.addMessage('length', {
494 'memcpy(out->data, self->data, self->bytes);', 504 'memcpy(out->data, self->data, self->bytes);',
495 'memcpy(out->data + self->bytes, argb->data, argb->bytes + 1);', 505 'memcpy(out->data + self->bytes, argb->data, argb->bytes + 1);',
496 'return out;' 506 'return out;'
497 ] 507 ]
498 }); 508 });
509 string.addMessage('byte', {
510 vars: {index: 'obj_int32 *', intret: 'obj_int32 *'},
511 lines: [
512 'index = va_arg(args, obj_int32 *);',
513 'intret = make_object(&obj_int32_meta, NULL, 0);',
514 'intret->num = index->num < self->bytes ? self->data[index->num] : 0;',
515 'return intret;'
516 ]
517 });
518 return string;
519 }
520
521 function makelambda()
522 {
523 var clos = new cObject('lambda');
524 clos.addProperty('env', null, 'void *');
525 clos.addProperty('func', null, 'closure_func');
526 clos.addMessage('while:do', {
527 vars: {action: 'lambda *', valtrue: 'object *', ret: 'object *'},
528 lines: [
529 'action = va_arg(args, lambda *);',
530 'valtrue = mcall(METHOD_ID_TRUE, 1, main_module);',
531 'ret = valtrue;',
532 'while(valtrue == ccall(self, 0)) {',
533 ' ccall(action, 0);',
534 '}',
535 'return ret;'
536 ]
537 });
538 return clos;
539 }
540
541 function builtinTypes()
542 {
543 return [makeInt32(), makeArray(), makeString(), makelambda()];
544 }
545
546 function makeCProg(obj)
547 {
548 var builtins = builtinTypes();
499 forwarddec = toplevelcode = ''; 549 forwarddec = toplevelcode = '';
500 forwarddec += int32.toEarlyCDef() + array.toEarlyCDef() + string.toEarlyCDef(); 550 for (var i in builtins) {
501 toplevelcode += int32.toCDef() + array.toCDef() + string.toCDef(); 551 forwarddec += builtins[i].toEarlyCDef();
552 toplevelcode += builtins[i].toCDef();
553 }
502 obj.populateSymbols(toplevel); 554 obj.populateSymbols(toplevel);
503 var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n'; 555 var rest = 'object * mainModule() {\n\tmain_module = ' + obj.toC() + ';\n\treturn main_module;\n}\n';
504 return '#include "runtime/proghead.inc"\n' + 556 return '#include "runtime/proghead.inc"\n' +
505 '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' + 557 '#define METHOD_ID_MAIN ' + getMethodId('main') + '\n' +
506 '#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' + 558 '#define METHOD_ID_TRUE ' + getMethodId('true') + '\n' +
579 if (this.symbols.passthruenv) { 631 if (this.symbols.passthruenv) {
580 var envvar = 'env'; 632 var envvar = 'env';
581 } else { 633 } else {
582 var envvar = 'myenv'; 634 var envvar = 'myenv';
583 } 635 }
584 return 'make_closure(' + envvar + ', lambda_' + mynum + ')'; 636 return 'make_lambda(' + envvar + ', lambda_' + mynum + ')';
585 } else { 637 } else {
586 toplevelcode += 'closure lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n'; 638 toplevelcode += 'lambda lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n';
587 return '((object *)&lambda_obj_' + mynum + ')'; 639 return '((object *)&lambda_obj_' + mynum + ')';
588 } 640 }
589 } 641 }
590 }; 642 };
591 lambda.prototype.toCObject = function(typename) { 643 lambda.prototype.toCObject = function(typename) {