comparison compiler.js @ 96:84b65ee8b78b

Optimize self method calls into static function calls
author Mike Pavone <pavone@retrodev.com>
date Thu, 26 Jul 2012 18:54:42 -0700
parents 926b65fe92b4
children 59a94f3ad56f
comparison
equal deleted inserted replaced
95:926b65fe92b4 96:84b65ee8b78b
327 this.val[i].populateSymbols(symbols); 327 this.val[i].populateSymbols(symbols);
328 } 328 }
329 } 329 }
330 330
331 funcall.prototype.populateSymbols = function(symbols) { 331 funcall.prototype.populateSymbols = function(symbols) {
332 var isll = false;
332 if (this.name == 'foreign:') { 333 if (this.name == 'foreign:') {
333 if ((this.args[0] instanceof lambda) || (this.args[0] instanceof object) || (this.args[0] instanceof symbol)) { 334 if ((this.args[0] instanceof lambda) || (this.args[0] instanceof object) || (this.args[0] instanceof symbol)) {
334 return; 335 return;
335 } else { 336 } else {
336 throw new Error("Unexpected AST type for foreign:"); 337 throw new Error("Unexpected AST type for foreign:");
349 } else if (this.name == 'llMessage:withVars:andCode:') { 350 } else if (this.name == 'llMessage:withVars:andCode:') {
350 if (this.args[0] instanceof symbol) { 351 if (this.args[0] instanceof symbol) {
351 if (this.args[1] instanceof lambda) { 352 if (this.args[1] instanceof lambda) {
352 if (this.args[2] instanceof lambda) { 353 if (this.args[2] instanceof lambda) {
353 symbols.defineMsg(this.args[0].name, this.args[2]); 354 symbols.defineMsg(this.args[0].name, this.args[2]);
355 isll = true;
354 } else { 356 } else {
355 throw new Error("Third argument to llMessage:withVars:andCode: must be a lambda"); 357 throw new Error("Third argument to llMessage:withVars:andCode: must be a lambda");
356 } 358 }
357 } else { 359 } else {
358 throw new Error("Second argument to llMessage:withVars:andCode: must be a lambda"); 360 throw new Error("Second argument to llMessage:withVars:andCode: must be a lambda");
366 var funinfo = symbols.find(name); 368 var funinfo = symbols.find(name);
367 if (funinfo && (funinfo.type == 'self' || funinfo.type == 'parent')) { 369 if (funinfo && (funinfo.type == 'self' || funinfo.type == 'parent')) {
368 symbols.find('self'); 370 symbols.find('self');
369 } 371 }
370 for (var i in this.args) { 372 for (var i in this.args) {
371 this.args[i].populateSymbols(symbols); 373 this.args[i].populateSymbols(symbols, undefined, isll);
372 } 374 }
373 if (this.receiver) { 375 if (this.receiver) {
374 this.receiver.populateSymbols(symbols); 376 this.receiver.populateSymbols(symbols, undefined, isll);
375 } 377 }
376 } 378 }
377 379
378 funcall.prototype.populateSymbolsObject = function(symbols) { 380 funcall.prototype.populateSymbolsObject = function(symbols) {
379 this.populateSymbols(symbols); 381 this.populateSymbols(symbols);
384 for (var i in this.messages) { 386 for (var i in this.messages) {
385 this.messages[i].populateSymbolsObject(symbols); 387 this.messages[i].populateSymbolsObject(symbols);
386 } 388 }
387 this.symbols = symbols; 389 this.symbols = symbols;
388 } 390 }
389 391 var lambdanum = 0;
390 lambda.prototype.populateSymbols = function(symbols, isobject) { 392 lambda.prototype.populateSymbols = function(symbols, isobject, isll) {
393 if (!isll) {
394 this.name = 'lambda_' + lambdanum++;
395 }
391 var args = this.args ? this.args.slice(0, this.args.length) : []; 396 var args = this.args ? this.args.slice(0, this.args.length) : [];
392 var exprs = this.expressions; 397 var exprs = this.expressions;
393 var symbols = new lsymbols(symbols); 398 var symbols = new lsymbols(symbols);
394 for (var i in args) { 399 for (var i in args) {
395 symbols.defineVar(args[i].cleanName(), null); 400 symbols.defineVar(args[i].cleanName(), null);