Mercurial > repos > tabletprog
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) { |