comparison interp.js @ 209:4b3b57f39f10

Implement zeroPlus macro
author Michael Pavone <pavone@retrodev.com>
date Wed, 27 Nov 2013 23:36:24 -0800
parents a1b4a2bc8d72
children d0848563f25d
comparison
equal deleted inserted replaced
208:a1b4a2bc8d72 209:4b3b57f39f10
26 return this <= other ? tptrue : tpfalse; 26 return this <= other ? tptrue : tpfalse;
27 }; 27 };
28 Number.prototype.tpmeth_asStringChar = function() { 28 Number.prototype.tpmeth_asStringChar = function() {
29 return String.fromCharCode(this); 29 return String.fromCharCode(this);
30 }; 30 };
31 Number.prototype['tpmeth_isString?'] = function() {
32 return false;
33 };
31 Number.prototype.tpmeth_string = function() { 34 Number.prototype.tpmeth_string = function() {
32 return '' + this; 35 return '' + this;
33 }; 36 };
34 Number.prototype.tpmeth_print = function() { 37 Number.prototype.tpmeth_print = function() {
35 print(this); 38 print(this);
50 String.prototype.tpmeth_byte = function(index) { 53 String.prototype.tpmeth_byte = function(index) {
51 return this.charCodeAt(index); 54 return this.charCodeAt(index);
52 }; 55 };
53 String.prototype['tpmeth_from:withLength'] = function(pos, length) { 56 String.prototype['tpmeth_from:withLength'] = function(pos, length) {
54 return this.substr(pos, length); 57 return this.substr(pos, length);
58 };
59 String.prototype['tpmeth_isString?'] = function() {
60 return true;
55 }; 61 };
56 String.prototype.tpmeth_print = function() { 62 String.prototype.tpmeth_print = function() {
57 print(this); 63 print(this);
58 }; 64 };
59 65
216 return val; 222 return val;
217 } 223 }
218 224
219 op.prototype.eval = function(env) { 225 op.prototype.eval = function(env) {
220 var l = this.left.eval(env); 226 var l = this.left.eval(env);
221 var r = this.right.eval(env);
222 var name = this.op; 227 var name = this.op;
228 if (name == '&&' || name == '||') {
229 var r = (new lambda([], [this.right])).eval(env);
230 } else {
231 var r = this.right.eval(env);
232 }
223 var fun = env.findNoTop(name); 233 var fun = env.findNoTop(name);
224 var ret; 234 var ret;
225 if (fun) { 235 if (fun) {
226 ret = fun(l,r) 236 ret = fun(l,r)
227 } else { 237 } else {
238 if (name == '&&') {
239 name = 'if'
240 } else if (name == '||') {
241 name = 'ifnot'
242 }
228 ret = l['tpmeth_'+name](r); 243 ret = l['tpmeth_'+name](r);
229 } 244 }
230 return ret; 245 return ret;
231 }; 246 };
232 247
240 var left = this.left.quote(env); 255 var left = this.left.quote(env);
241 var right = this.right.quote(env); 256 var right = this.right.quote(env);
242 return new op(left, this.op, right); 257 return new op(left, this.op, right);
243 }; 258 };
244 259
260 op.prototype.tpmeth_nodeType = function() {
261 return "op";
262 };
263
264 op.prototype.tpmeth_left = function() {
265 return this.left;
266 };
267
268 op.prototype.tpmeth_right = function() {
269 return this.right;
270 };
271
272 op.prototype.tpmeth_opName = function() {
273 return this.op;
274 };
275
245 var quote_prefix = 0; 276 var quote_prefix = 0;
246 277
247 symbol.prototype.eval = function(env) { 278 symbol.prototype.eval = function(env) {
248 var res = env.find(this.name); 279 var res = env.find(this.name);
249 if (res === null) { 280 if (res === null) {
253 }; 284 };
254 285
255 symbol.prototype.quote = function(env) { 286 symbol.prototype.quote = function(env) {
256 var val = env.find(this.name); 287 var val = env.find(this.name);
257 if (val) { 288 if (val) {
258 return makeASTNode(val); 289 var newnode = makeASTNode(val);
290 if (!(newnode instanceof symbol)) {
291 newnode = newnode.quote(env);
292 }
293 return newnode;
259 } else { 294 } else {
260 var hygenic = env.findQuoteTrans(this.name); 295 var hygenic = env.findQuoteTrans(this.name);
261 return hygenic ? new symbol(hygenic, this.symbols) : this; 296 return hygenic ? new symbol(hygenic, this.symbols) : this;
262 } 297 }
298 };
299
300 symbol.prototype.tpmeth_nodeType = function() {
301 return "symbol";
302 };
303
304 symbol.prototype.tpmeth_name = function() {
305 return this.cleanName();
263 }; 306 };
264 307
265 intlit.prototype.eval = 308 intlit.prototype.eval =
266 floatlit.prototype.eval = 309 floatlit.prototype.eval =
267 strlit.prototype.eval = 310 strlit.prototype.eval =
284 arraylit.prototype.quote = 327 arraylit.prototype.quote =
285 listlit.prototype.quote = function(env) { 328 listlit.prototype.quote = function(env) {
286 return this; 329 return this;
287 }; 330 };
288 331
332 intlit.prototype.tpmeth_nodeType = function() {
333 return "intlit";
334 };
335
336 floatlit.prototype.tpmeth_nodeType = function() {
337 return "floatlit";
338 };
339
340 strlit.prototype.tpmeth_nodeType = function() {
341 return "strlit";
342 };
343
344 arraylit.prototype.tpmeth_nodeType = function() {
345 return "arraylit";
346 };
347
348 listlit.prototype.tpmeth_nodeType = function() {
349 return "strlit";
350 };
351
352 intlit.prototype.tpmeth_value =
353 floatlit.prototype.tpmeth_value =
354 strlit.prototype.tpmeth_value =
355 arraylit.prototype.tpmeth_value =
356 listlit.prototype.tpmeth_value = function() {
357 return this.val;
358 }
359
289 funcall.prototype.eval = function(env) { 360 funcall.prototype.eval = function(env) {
290 var args = []; 361 var args = [];
291 var name = this.name; 362 var name = this.name;
292 if (name[name.length-1] == ":") { 363 if (name[name.length-1] == ":") {
293 name = name.substr(0, name.length-1); 364 name = name.substr(0, name.length-1);
295 if (name == 'quote') { 366 if (name == 'quote') {
296 if (this.receiver) { 367 if (this.receiver) {
297 return this.receiver.quote(env); 368 return this.receiver.quote(env);
298 } 369 }
299 if (this.args.length) { 370 if (this.args.length) {
371 var cur = env;
300 return this.args[0].quote(env); 372 return this.args[0].quote(env);
301 } 373 }
302 throw new Error('quote takes an argument'); 374 throw new Error('quote takes an argument');
303 } 375 }
304 if (name == 'macro') { 376 if (name == 'macro') {
363 var receiver = this.receiver ? this.receiver.quote(env) : null; 435 var receiver = this.receiver ? this.receiver.quote(env) : null;
364 var args = []; 436 var args = [];
365 for (var i = 0; i < this.args.length; i++) { 437 for (var i = 0; i < this.args.length; i++) {
366 args.push(this.args[i].quote(env)); 438 args.push(this.args[i].quote(env));
367 } 439 }
368 var name = env.findQuoteTrans(this.name); 440 var name = this.name;
369 if (!name) { 441 if (name[name.length-1] == ":") {
370 name = this.name; 442 name = name.substr(0, name.length-1);
443 }
444 var fun = env.find(name);
445 if (fun) {
446 fun = makeASTNode(fun);
447 if (fun instanceof symbol) {
448 name = fun.cleanName();
449 } else if (fun instanceof lambda) {
450 throw new Error('FIXME');
451 }
452 } else {
453 var hygenic = env.findQuoteTrans(this.name);
454 if (hygenic) {
455 name = hygenic;
456 }
371 } 457 }
372 var ret = new funcall(name, args); 458 var ret = new funcall(name, args);
373 ret.receiver = receiver; 459 ret.receiver = receiver;
374 return ret; 460 return ret;
461 };
462
463 funcall.prototype.tpmeth_nodeType = function() {
464 return "funcall";
375 }; 465 };
376 466
377 object.prototype.eval = function(parentenv) { 467 object.prototype.eval = function(parentenv) {
378 var env = new environment(parentenv); 468 var env = new environment(parentenv);
379 var obj = {env: env}; 469 var obj = {env: env};
478 } 568 }
479 } 569 }
480 return new object(outmessages); 570 return new object(outmessages);
481 }; 571 };
482 572
573 object.prototype.tpmeth_nodeType = function() {
574 return "object";
575 };
576
483 lambda.prototype.eval = function(parentenv) { 577 lambda.prototype.eval = function(parentenv) {
484 var args = this.args; 578 var args = this.args;
485 var exprs = this.expressions; 579 var exprs = this.expressions;
486 return function() { 580 return function() {
487 var env = new environment(parentenv); 581 var env = new environment(parentenv);
537 expressions.push(this.expressions[i].quote(env)); 631 expressions.push(this.expressions[i].quote(env));
538 } 632 }
539 return new lambda(args, expressions); 633 return new lambda(args, expressions);
540 }; 634 };
541 635
636 lambda.prototype.tpmeth_nodeType = function() {
637 return "lambda";
638 };
639
542 assignment.prototype.eval = function(env) { 640 assignment.prototype.eval = function(env) {
543 var val = this.expression.eval(env); 641 var val = this.expression.eval(env);
544 env.findSet(this.symbol.name, val); 642 env.findSet(this.symbol.name, val);
545 return val; 643 return val;
546 }; 644 };
555 env.syms[name] = null; 653 env.syms[name] = null;
556 var hygenic = '' + quote_prefix + name; 654 var hygenic = '' + quote_prefix + name;
557 env.quotetrans[name] = hygenic; 655 env.quotetrans[name] = hygenic;
558 return new assignment(new symbol(hygenic, this.symbol.symbols), this.expression.quote(env)); 656 return new assignment(new symbol(hygenic, this.symbol.symbols), this.expression.quote(env));
559 }; 657 };
658
659 assignment.prototype.tpmeth_nodeType = function() {
660 return "assignment";
661 };