Mercurial > repos > tabletprog
diff cbackend.js @ 171:869399ff7faa
Merge
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 13 Aug 2013 22:01:00 -0700 |
parents | 18598163e3ef 224071eed9dd |
children | 8d466c5a7dff |
line wrap: on
line diff
--- a/cbackend.js Tue Aug 13 21:58:03 2013 -0700 +++ b/cbackend.js Tue Aug 13 22:01:00 2013 -0700 @@ -3,6 +3,7 @@ var nextmethodId = 0; var methodIds = {}; +var assignNames; function getMethodId(methodName) { if (!(methodName in methodIds)) { @@ -142,7 +143,7 @@ var declaredInts = {}; intlit.prototype.toC = function() { - var intType = 'int' + this.bits; + var intType = (this.unsigned ? 'u' : '') + 'int' + this.bits; var str = intType + '_' + (this.val < 0 ? 'neg_' + (0-this.val).toString() : this.val.toString()); if (!(str in declaredInts)) { toplevelcode += 'obj_' + intType + ' ' + str + ' = {{&obj_' + intType + '_meta, NULL}, ' + this.val.toString() + '};\n'; @@ -637,11 +638,11 @@ }); } -function makeInt(bits) +function makeInt(bits, unsigned) { - var typename = 'obj_int' + bits; + var typename = 'obj_' + (unsigned ? 'u' : '') + 'int' + bits; var intObj = new cObject(typename); - intObj.addProperty('num', null, 'int' + bits +'_t'); + intObj.addProperty('num', null, (unsigned ? 'u' : '') + 'int' + bits +'_t'); addBinaryOp(intObj, 'ADD_', '+', typename); addBinaryOp(intObj, 'SUB_', '-', typename); addBinaryOp(intObj, 'MUL_', '*', typename); @@ -666,7 +667,7 @@ lines: [ 'str = (string *)make_object(&string_meta, NULL, 0);', 'str->data = GC_MALLOC(' + (bits == 64 ? 21 : 12) + ');', - 'sprintf(str->data, "%' + (bits == 64 ? 'l' : '') +'d", self->num);', + 'sprintf(str->data, "%' + (bits == 64 ? 'l' : '') + (unsigned ? 'u' : 'd') + '", self->num);', 'str->len = str->bytes = strlen(str->data);', 'return &(str->header);' ] @@ -695,6 +696,37 @@ 'return &(self->header);' ] }); + var sizes = [8, 16, 32, 64]; + var destunsigned = [false, true]; + for (var i = 0; i < sizes.length; i++) { + size = sizes[i]; + for (var j = 0; j < destunsigned.length; j++) { + uns = destunsigned[j]; + if (uns == unsigned && size == bits) { + intObj.addMessage((uns ? 'u' : '') + 'int' + size, { + vars: {}, + lines: [ + 'return &(self->header);' + ] + }); + } else { + var retType = 'obj_' + (uns ? 'u' : '') + 'int' + size; + var retName = 'ret' + (uns ? 'u' : '') + size; + var vars = {}; + vars[retName] = retType + ' *'; + intObj.addMessage((uns ? 'u' : '') + 'int' + size, { + + vars: vars, + lines: [ + retName + ' = ('+retType+' *)make_object(&' + retType +'_meta, NULL, 0);', + retName + '->num = self->num;', + 'return &(' + retName + '->header);' + ] + }); + } + } + } + return intObj; } @@ -737,7 +769,9 @@ function builtinTypes() { - return [makeInt(64), makeInt(32), makeInt(16), makeInt(8), makeArray(), makeString(), makelambda()]; + return [makeInt(64, false), makeInt(32, false), makeInt(16, false), makeInt(8, false), + makeInt(64, true) , makeInt(32, true), makeInt(16, true), makeInt(8, true), + makeArray(), makeString(), makelambda()]; } function addBuiltinModules(toplevel) @@ -745,6 +779,9 @@ var os = new cObject('mod_obj_os'); os.addInclude('<sys/stat.h>'); os.addInclude('<fcntl.h>'); + os.addInclude('<stdlib.h>'); + os.addInclude('<time.h>'); + os.addInclude('<unistd.h>'); os.addMessage('write', { vars: {str: 'string *', intret: 'obj_int32 *', filedes: 'obj_int32 *'}, lines: [ @@ -762,8 +799,8 @@ 'size = va_arg(args, obj_int32 *);', 'str = (string *)make_object(&string_meta, NULL, 0);', 'str->data = GC_MALLOC_ATOMIC(size->num + 1);', - 'str->length = str->bytes = read(filedes->num, str->data, size->num);', - 'if (str->bytes < 0) { str->bytes = str->length = 0; }', + 'str->len = str->bytes = read(filedes->num, str->data, size->num);', + 'if (str->bytes < 0) { str->bytes = str->len = 0; }', 'str->data[str->bytes] = 0;', 'return &(str->header);' ] @@ -842,6 +879,49 @@ 'return &(intret->header);' ] }); + os.addMessage('rand', { + vars: {intret: 'obj_int32 *'}, + lines: [ + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', + 'intret->num = rand();', + 'return &(intret->header);' + ] + }); + os.addMessage('rand64', { + vars: {intret64: 'obj_int64 *'}, + lines: [ + 'intret64 = (obj_int64 *)make_object(&obj_int64_meta, NULL, 0);', + 'intret64->num = (((int64_t)rand()) << 32 ) | rand();', + 'return &(intret64->header);' + ] + }); + os.addMessage('srand', { + vars: {oseed: 'object *', seed: 'obj_int32 *'}, + lines: [ + 'oseed = va_arg(args, object *);', + 'seed = mcall(' + getMethodId("int32") + ', 1, oseed);', + 'srand(seed->num);', + 'return &(seed->header);' + ] + }); + os.addMessage('time', { + vars: {intret64: 'obj_int64 *'}, + lines: [ + 'intret64 = (obj_int64 *)make_object(&obj_int64_meta, NULL, 0);', + 'intret64->num = time(NULL);', + 'return &(intret64->header);' + ] + }); + os.addMessage('sleep', { + vars: {osecs: 'object *', secs: 'obj_int32 *', intret: 'obj_int32 *'}, + lines: [ + 'osecs = va_arg(args, object *);', + 'secs = mcall(' + getMethodId("int32") + ', 1, osecs);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', + 'intret->num = sleep(secs->num);', + 'return &(intret->header);' + ] + }); toplevel.names['os'] = os; } @@ -880,7 +960,9 @@ for (var i = allused.length-1; i >= 0; i--) { var symbol = allused[i]; debugprint('//---module', symbol, '(' + i +')--- compile'); + assignNames.push(symbol); ret += '\t' + toplevel.moduleVar(symbol) + ' = ' + toplevel.names[symbol].toC() + ';\n'; + assignNames.pop(); } return ret; } @@ -888,6 +970,7 @@ function makeCProg(obj) { forwarddec = toplevelcode = ''; + assignNames = []; var builtins = builtinTypes(); for (var i in builtins) { forwarddec += builtins[i].toEarlyCDef(); @@ -917,10 +1000,13 @@ lambda.prototype.toC = function() { var args = this.args ? this.args.slice(0, this.args.length) : []; var exprs = this.expressions; - debugprint('//', this.name); + var assignPath = assignNames.join('<-'); + debugprint('//', this.name, assignPath); + var addedTypeDef = false; if (Object.keys(this.symbols.closedover).length) { this.symbols.envtype = this.name + '_env'; forwarddec += 'typedef struct ' + this.symbols.envtype + ' ' + this.symbols.envtype + ';\n' + var addedTypeDef = true; } if (this.selftype) { this.symbols.defineVar('self', this.selftype); @@ -949,6 +1035,12 @@ } if (Object.keys(this.symbols.closedover).length) { + if (!addedTypeDef) { + for (var key in this.symbols.closedover) { + print(key, ": ", this.symbols.closedover[key]); + } + throw new Error('this.symbols.closedover is not empty, but it was when compilation of ' + this.name + ' "' + assignPath + '" started'); + } forwarddec += 'struct ' + this.name + '_env {\n'; if (this.symbols.needsParentEnv) { forwarddec += '\tstruct ' + this.symbols.parentEnvType() + ' * parent;\n'; @@ -972,6 +1064,7 @@ } forwarddec += 'object *' + this.name + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...);\n'; + toplevelcode += '//' + assignPath + "\n"; toplevelcode += 'object * ' + this.name + ' ( ' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...) {\n\tva_list args;\n' + myenvinit + '\tva_start(args, num_args);\n'; if (this.selftype) { var selfvar = (new symbol('self', this.symbols)).toC(); @@ -1042,7 +1135,9 @@ debugprint('//assignment', this.symbol.name); var existing = this.symbols.find(this.symbol.name); var prefix = ''; + assignNames.push(this.symbol.name); var val = this.expression.toC(); + assignNames.pop(this.symbol.name); if (val === null) { return null; } @@ -1055,11 +1150,13 @@ }; assignment.prototype.toCObject = function(cobj) { debugprint('//message definition', this.symbol.name); + assignNames.push('#' + this.symbol.name); if (this.expression.toCObject) { var val = this.expression.toCObject(cobj.name); } else { var val = this.expression.toC(); } + assignNames.pop(); if (val === null) { return; }