annotate interp.js @ 251:2557ce4e671f

Fix a couple of compiler bugs. topenv was getting initialized in multiple places. This resulted in multiple copies of modules getting created which caused problems for macro expansion. Additionally, arguments were not being marked as declared during code generation so assigning to an argument that was not closed over generated invalid C code.
author Michael Pavone <pavone@retrodev.com>
date Fri, 11 Apr 2014 22:29:32 -0700
parents dc5f487247ee
children 0ee70ac20a02
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
1 Number.prototype['tpmeth_+'] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
2 return this + other;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
3 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
4 Number.prototype['tpmeth_-'] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
5 return this - other;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
6 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
7 Number.prototype['tpmeth_*'] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
8 return this * other;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
9 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
10 Number.prototype['tpmeth_/'] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
11 return this / other;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
12 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
13 Number.prototype['tpmeth_='] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
14 return this == other ? tptrue : tpfalse;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
15 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
16 Number.prototype['tpmeth_>'] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
17 return this > other ? tptrue : tpfalse;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
18 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
19 Number.prototype['tpmeth_<'] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
20 return this < other ? tptrue : tpfalse;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
21 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
22 Number.prototype['tpmeth_>='] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
23 return this >= other ? tptrue : tpfalse;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
24 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
25 Number.prototype['tpmeth_<='] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
26 return this <= other ? tptrue : tpfalse;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
27 };
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
28 Number.prototype.tpmeth_asStringChar = function() {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
29 return String.fromCharCode(this);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
30 };
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
31 Number.prototype['tpmeth_isString?'] = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
32 return false;
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
33 };
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
34 Number.prototype.tpmeth_string = function() {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
35 return '' + this;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
36 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
37 Number.prototype.tpmeth_print = function() {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
38 print(this);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
39 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
40
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
41 String.prototype['tpmeth_.'] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
42 return this + other;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
43 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
44 String.prototype['tpmeth_='] = function(other) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
45 return this == other ? tptrue : tpfalse;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
46 };
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
47 String.prototype.tpmeth_length = function() {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
48 return this.length;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
49 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
50 String.prototype.tpmeth_byte_length = function() {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
51 return this.length;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
52 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
53 String.prototype.tpmeth_byte = function(index) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
54 return this.charCodeAt(index);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
55 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
56 String.prototype['tpmeth_from:withLength'] = function(pos, length) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
57 return this.substr(pos, length);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
58 };
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
59 String.prototype['tpmeth_isString?'] = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
60 return true;
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
61 };
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
62 String.prototype.tpmeth_print = function() {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
63 print(this);
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
64 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
65
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
66 Function.prototype['tpmeth_while:do'] = function(body) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
67 var ret = null;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
68 for (;;) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
69 var res = this.call(null);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
70 if (res != tptrue) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
71 break;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
72 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
73 ret = body.call(null);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
74 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
75 return ret;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
76 };
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
77
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
78 var tptrue = null;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
79 var tpfalse = null;
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
80 var tplist = null;
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
81
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
82 function topenv(moduledirs)
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
83 {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
84 this.names = {};
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
85 this.modules = {};
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
86 for (var dirnum in moduledirs) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
87 var results = os.system("ls", [moduledirs[dirnum]]).split('\n');
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
88 for (var i in results) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
89 var tpidx = results[i].indexOf('.tp')
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
90 if (tpidx > 0 && tpidx == results[i].length - 3) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
91 this.names[results[i].substr(0, tpidx)] = moduledirs[dirnum] + "/" + results[i];
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
92 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
93 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
94 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
95 if (!tptrue) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
96 tptrue = this.find('true');
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
97 tptrue.valueOf = function() {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
98 return true;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
99 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
100 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
101 if (!tpfalse) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
102 tpfalse = this.find('false');
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
103 tpfalse.valueOf = function() {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
104 return false;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
105 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
106 }
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
107 if (!tplist) {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
108 tplist = this.find('list');
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
109 if (tplist instanceof Function) {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
110 tplist = tplist.call(null);
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
111 }
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
112 }
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
113 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
114
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
115 topenv.prototype = {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
116 find: function(name) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
117 if (name in this.modules) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
118 return this.modules[name];
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
119 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
120 if (name in this.names) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
121 var parsed = parseFile(this.names[name]);
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
122 var ret = parsed.macroexpand(this).eval(this);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
123 if (typeof ret == 'function') {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
124 ret = ret();
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
125 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
126 this.modules[name] = ret;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
127 return ret;
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
128 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
129 return null;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
130 },
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
131 findNoTop: function(name) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
132 return null;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
133 },
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
134 findSetPresent: function(name, val) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
135 return false;
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
136 },
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
137 findMacro: function(name) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
138 return null;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
139 },
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
140 findQuoteTrans: function(name) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
141 return null;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
142 }
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
143 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
144
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
145 function environment(parent)
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
146 {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
147 this.parent = parent;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
148 this.syms = {};
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
149 this.macros = {};
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
150 this.quotetrans = {};
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
151 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
152
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
153 environment.prototype = {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
154 find: function(name) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
155 if (name in this.syms) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
156 return this.syms[name];
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
157 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
158 if (this.parent) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
159 return this.parent.find(name);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
160 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
161 return null;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
162 },
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
163 findNoTop: function(name) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
164 if (name in this.syms) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
165 return this.syms[name];
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
166 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
167 if (this.parent) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
168 return this.parent.findNoTop(name);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
169 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
170 return null;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
171 },
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
172 findSet: function(name, val) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
173 if (name in this.syms
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
174 || !this.parent
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
175 || !this.parent.findSetPresent(name, val)) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
176 this.syms[name] = val;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
177 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
178 },
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
179 findSetPresent: function(name, val) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
180 if (name in this.syms) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
181 this.syms[name] = val;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
182 return true;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
183 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
184 if (this.parent) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
185 return this.parent.findSetPresent(name, val);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
186 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
187 return false;
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
188 },
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
189 findMacro: function(name) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
190 if (name in this.syms) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
191 if (name in this.macros) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
192 return this.syms[name];
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
193 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
194 return null;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
195 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
196 if (this.parent) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
197 return this.parent.findMacro(name);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
198 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
199 return null;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
200 },
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
201 findQuoteTrans: function(name) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
202 if (name in this.quotetrans) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
203 return this.quotetrans[name];
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
204 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
205 if (this.parent) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
206 return this.parent.findQuoteTrans(name);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
207 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
208 return null;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
209 },
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
210 defMacro: function(name, def) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
211 this.syms[name] = def;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
212 this.macros[name] = true;
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
213 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
214 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
215
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
216 function makeASTNode(val)
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
217 {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
218 if (typeof val == 'number') {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
219 return new intlit(val);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
220 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
221 if (typeof val == 'string') {
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
222 return new strlit(val);
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
223 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
224 if (val instanceof Array) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
225 return new arraylit(val);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
226 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
227 if (val == tptrue) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
228 return new symbol('true');
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
229 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
230 if (val == tpfalse) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
231 return new symbol('false');
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
232 }
221
218b11ec8fa2 Better handling for weird values being inserted into AST due to quoting
Michael Pavone <pavone@retrodev.com>
parents: 219
diff changeset
233 if ('makeHygienic' in val) {
218b11ec8fa2 Better handling for weird values being inserted into AST due to quoting
Michael Pavone <pavone@retrodev.com>
parents: 219
diff changeset
234 return val;
218b11ec8fa2 Better handling for weird values being inserted into AST due to quoting
Michael Pavone <pavone@retrodev.com>
parents: 219
diff changeset
235 }
218b11ec8fa2 Better handling for weird values being inserted into AST due to quoting
Michael Pavone <pavone@retrodev.com>
parents: 219
diff changeset
236 return null;
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
237 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
238
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
239 op.prototype.eval = function(env) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
240 var l = this.left.eval(env);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
241 var name = this.op;
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
242 if (name == '&&' || name == '||') {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
243 var r = (new lambda([], [this.right])).eval(env);
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
244 } else {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
245 var r = this.right.eval(env);
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
246 }
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
247 var fun = env.findNoTop(name);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
248 var ret;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
249 if (fun) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
250 ret = fun(l,r)
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
251 } else {
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
252 if (name == '&&') {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
253 name = 'if'
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
254 } else if (name == '||') {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
255 name = 'ifnot'
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
256 } else if (name == '|') {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
257 return r['tpmeth_|'](l);
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
258 }
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
259 ret = l['tpmeth_'+name](r);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
260 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
261 return ret;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
262 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
263
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
264 op.prototype.macroexpand = function(env) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
265 this.left = this.left.macroexpand(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
266 this.right = this.right.macroexpand(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
267 return this;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
268 };
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
269
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
270 op.prototype.quote = function(env) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
271 var left = this.left.quote(env);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
272 var right = this.right.quote(env);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
273 return new op(left, this.op, right);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
274 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
275
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
276 op.prototype.makeHygienic = function(env) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
277 var left = this.left.makeHygienic(env);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
278 var right = this.right.makeHygienic(env);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
279 return new op(left, this.op, right);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
280 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
281
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
282 op.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
283 return "op";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
284 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
285
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
286 op.prototype.tpmeth_left = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
287 return this.left;
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
288 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
289
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
290 op.prototype.tpmeth_right = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
291 return this.right;
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
292 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
293
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
294 op.prototype.tpmeth_opName = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
295 return this.op;
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
296 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
297
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
298 var quote_prefix = 0;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
299
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
300 symbol.prototype.eval = function(env) {
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
301 var res = env.find(this.name);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
302 if (res === null) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
303 throw new Error('Symbol ' + this.name + ' is not bound');
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
304 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
305 return res;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
306 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
307
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
308 symbol.prototype.quote = function(env) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
309 var val = env.find(this.name);
219
b70be565d54c Fix check of return value from env.find in symbol.quote so that falsey found values do not cause trouble.
Michael Pavone <pavone@retrodev.com>
parents: 217
diff changeset
310 if (val !== null) {
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
311 var newnode = makeASTNode(val);
221
218b11ec8fa2 Better handling for weird values being inserted into AST due to quoting
Michael Pavone <pavone@retrodev.com>
parents: 219
diff changeset
312 if (!newnode) {
218b11ec8fa2 Better handling for weird values being inserted into AST due to quoting
Michael Pavone <pavone@retrodev.com>
parents: 219
diff changeset
313 throw new Error(this.name + ' contains a value ' + val + ' that could not be converted to an AST node');
218b11ec8fa2 Better handling for weird values being inserted into AST due to quoting
Michael Pavone <pavone@retrodev.com>
parents: 219
diff changeset
314 }
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
315 return newnode;
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
316 } else {
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
317 this.dirty = true;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
318 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
319 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
320 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
321
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
322 symbol.prototype.makeHygienic = function(env) {
240
dc5f487247ee Don't rename the symbol self in quote blocks
Mike Pavone <pavone@retrodev.com>
parents: 238
diff changeset
323 if (this.dirty && this.cleanName() != 'self') {
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
324 var hygenic = env.findQuoteTrans(this.cleanName());
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
325 if (hygenic)
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
326 {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
327 return new symbol(hygenic, this.symbols);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
328 } else {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
329 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
330 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
331 } else {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
332 return this;
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
333 }
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
334 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
335
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
336 symbol.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
337 return "symbol";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
338 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
339
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
340 symbol.prototype.tpmeth_name = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
341 return this.cleanName();
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
342 };
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
343 symbol.prototype['tpmeth_name!'] = function(val) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
344 this.name = val;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
345 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
346 };
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
347
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
348 intlit.prototype.eval =
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
349 floatlit.prototype.eval =
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
350 strlit.prototype.eval =
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
351 arraylit.prototype.eval = function(env) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
352 return this.val;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
353 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
354
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
355 listlit.prototype.eval = function(env) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
356 var cur = tplist.tpmeth_empty();
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
357 for (var idx = this.val.length - 1; idx >= 0; --idx) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
358 cur = tplist['tpmeth_node:withTail'](this.val[idx].eval(env), cur);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
359 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
360 return cur;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
361 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
362
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
363 symbol.prototype.macroexpand =
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
364 intlit.prototype.macroexpand =
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
365 floatlit.prototype.macroexpand =
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
366 strlit.prototype.macroexpand = function(env) {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
367 return this;
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
368 };
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
369
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
370
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
371 arraylit.prototype.macroexpand =
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
372 listlit.prototype.macroexpand = function(env) {
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
373 for (var i = 0; i < this.val.length; i++) {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
374 this.val[i] = this.val[i].macroexpand(env);
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
375 }
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
376 return this;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
377 };
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
378
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
379 intlit.prototype.quote =
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
380 floatlit.prototype.quote =
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
381 strlit.prototype.quote =
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
382 arraylit.prototype.quote =
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
383 listlit.prototype.quote = function(env) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
384 return this;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
385 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
386
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
387 intlit.prototype.makeHygienic =
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
388 floatlit.prototype.makeHygienic =
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
389 strlit.prototype.makeHygienic =
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
390 arraylit.prototype.makeHygienic =
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
391 listlit.prototype.makeHygienic = function(env) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
392 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
393 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
394
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
395 intlit.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
396 return "intlit";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
397 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
398
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
399 floatlit.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
400 return "floatlit";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
401 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
402
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
403 strlit.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
404 return "strlit";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
405 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
406
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
407 arraylit.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
408 return "arraylit";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
409 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
410
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
411 listlit.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
412 return "strlit";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
413 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
414
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
415 intlit.prototype.tpmeth_value =
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
416 floatlit.prototype.tpmeth_value =
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
417 strlit.prototype.tpmeth_value =
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
418 arraylit.prototype.tpmeth_value = function() {
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
419 return this.val;
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
420 };
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
421
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
422 listlit.prototype.tpmeth_value = function() {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
423 var cur = tplist.tpmeth_empty();
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
424 for (var idx = this.val.length - 1; idx >= 0; --idx) {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
425 cur = tplist['tpmeth_node:withTail'](this.val[idx], cur);
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
426 }
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
427 return cur;
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
428 };
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
429
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
430 funcall.prototype.eval = function(env) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
431 var args = [];
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
432 var name = this.name;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
433 if (name[name.length-1] == ":") {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
434 name = name.substr(0, name.length-1);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
435 }
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
436 if (name == 'quote') {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
437 if (this.receiver) {
224
97c3e33cd3f4 Support macro expansion inside quoted code
Michael Pavone <pavone@retrodev.com>
parents: 221
diff changeset
438 return this.receiver.quote(env).macroexpand(env);
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
439 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
440 if (this.args.length) {
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
441 var cur = env;
224
97c3e33cd3f4 Support macro expansion inside quoted code
Michael Pavone <pavone@retrodev.com>
parents: 221
diff changeset
442 return this.args[0].quote(env).macroexpand(env);
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
443 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
444 throw new Error('quote takes an argument');
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
445 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
446 if (name == 'macro') {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
447 return null;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
448 }
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
449 if (this.receiver) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
450 args.push(this.receiver.eval(env));
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
451 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
452 for (var i = 0; i < this.args.length; i++) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
453 args.push(this.args[i].eval(env));
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
454 }
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
455 if (name == 'eval:else') {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
456 try {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
457 var res = args[0].eval(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
458 } catch(e) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
459 return args[2].call(null);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
460 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
461 return args[1].call(null, res);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
462 }
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
463 var fun = env.findNoTop(name);
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
464 if (fun && (fun.numargs === undefined || fun.numargs == args.length)) {
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
465 return fun.apply(null, args);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
466 } else {
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
467 //if (typeof args[0]'tpmeth_'+name in args[0]) {
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
468 try {
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
469 return args[0]['tpmeth_'+name].apply(args[0], args.slice(1));
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
470 } catch(e) {
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
471 var msg = 'Error, \n\t' + e.message.split('\n').join('\n\t') + '\ninvoking method ' + name + ' on object ' + args[0];
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
472 if (typeof args[0] == 'object') {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
473 msg += ' with keys ' + JSON.stringify(Object.keys(args[0]) + ' and constructor ' + args[0].constructor.name);
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
474 }
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
475 throw new Error(msg);
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
476 }
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
477 /*} else {JSON.stringify
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
478 throw new Error('No method named ' + name + ' on object ' + JSON.stringify(args[0]));
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
479 }*/
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
480 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
481 };
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
482
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
483 funcall.prototype.macroexpand = function(env) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
484 var name = this.name;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
485 if (name[name.length-1] == ":") {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
486 name = name.substr(0, name.length-1);
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
487 }
224
97c3e33cd3f4 Support macro expansion inside quoted code
Michael Pavone <pavone@retrodev.com>
parents: 221
diff changeset
488 if (name == 'quote') {
97c3e33cd3f4 Support macro expansion inside quoted code
Michael Pavone <pavone@retrodev.com>
parents: 221
diff changeset
489 return this;
97c3e33cd3f4 Support macro expansion inside quoted code
Michael Pavone <pavone@retrodev.com>
parents: 221
diff changeset
490 }
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
491 var macro = env.findMacro(name);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
492 if (this.receiver) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
493 this.receiver = this.receiver.macroexpand(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
494 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
495 for (var i = 0; i < this.args.length; i++) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
496 this.args[i] = this.args[i].macroexpand(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
497 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
498 if (!macro) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
499 return this;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
500 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
501 var args = [];
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
502 if (this.receiver) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
503 args.push(this.receiver);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
504 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
505 for (var i = 0; i < this.args.length; i++) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
506 args.push(this.args[i]);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
507 }
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
508 var ret = makeASTNode(macro.apply(null, args));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
509 ret = ret.makeHygienic(env);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
510 quote_prefix++;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
511 return ret;
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
512 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
513
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
514 funcall.prototype.quote = function(env) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
515 var receiver = this.receiver ? this.receiver.quote(env) : null;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
516 var args = [];
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
517 for (var i = 0; i < this.args.length; i++) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
518 args.push(this.args[i].quote(env));
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
519 }
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
520 var name = this.name;
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
521 if (name[name.length-1] == ":") {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
522 name = name.substr(0, name.length-1);
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
523 }
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
524 var fun = env.find(name);
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
525 if (fun) {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
526 fun = makeASTNode(fun);
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
527 if (fun instanceof symbol) {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
528 name = fun.cleanName();
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
529 } else if (fun instanceof lambda) {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
530 throw new Error('FIXME');
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
531 }
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
532 } else {
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
533 this.dirty = true;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
534 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
535 var ret = new funcall(name, args);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
536 ret.receiver = receiver;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
537 return ret;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
538 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
539
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
540 funcall.prototype.makeHygienic = function(env) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
541 var receiver = this.receiver ? this.receiver.makeHygienic(env) : null;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
542 var args = [];
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
543 for (var i = 0; i < this.args.length; i++) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
544 args.push(this.args[i].makeHygienic(env));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
545 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
546 var name = this.name;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
547 if (name[name.length-1] == ":") {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
548 name = name.substr(0, name.length-1);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
549 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
550 var hygienic = env.findQuoteTrans(name);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
551 if (hygienic) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
552 name = hygienic;
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
553 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
554 var ret = new funcall(name, args);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
555 ret.receiver = receiver;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
556 return ret;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
557 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
558
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
559 funcall.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
560 return "funcall";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
561 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
562
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
563 funcall.prototype['tpmeth_args!'] = function(arglist) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
564 this.args = [];
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
565 //TODO: Finish this
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
566 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
567
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
568 object.prototype.eval = function(parentenv) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
569 var env = new environment(parentenv);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
570 var obj = {env: env};
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
571 for (var i = 0; i < this.messages.length; i++) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
572 var msg = this.messages[i];
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
573 if (msg instanceof assignment) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
574 if (msg.expression instanceof lambda) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
575 obj['tpmeth_' + msg.symbol.name] = msg.expression.eval(env);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
576 (function(name) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
577 env.syms[name] = function() {
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
578 var ret = obj['tpmeth_' + name].apply(obj, arguments);
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
579 return ret;
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
580 };
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
581 env.syms[name].numargs = msg.expression.numArgs();
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
582 })(msg.symbol.name);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
583 } else {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
584 var makeProp = function(obj, name) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
585 obj['tprop_' + name] = msg.expression.eval(env);
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
586 obj['tpmeth_' + name] = function() {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
587 return this['tprop_'+name];
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
588 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
589 var setname = name+'!';
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
590 obj['tpmeth_' + setname] = function(val) {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
591 this['tprop_'+name] = val;
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
592 return this;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
593 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
594 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
595 makeProp(obj, msg.symbol.name);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
596 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
597 } else {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
598 throw new Error('pseudo function calls in object definitions not implemented yet');
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
599 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
600 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
601 return obj;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
602 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
603
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
604 object.prototype.macroexpand = function(parentenv) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
605 var env = new environment(parentenv);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
606 var obj = {env: env};
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
607 var outmessages = [];
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
608 for (var i = 0; i < this.messages.length; i++) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
609 var msg = this.messages[i].macroexpand(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
610 if (msg instanceof assignment) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
611 if (msg.expression instanceof lambda) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
612 (function(name, expr) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
613 env.syms[name] = function() {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
614 if (!obj['tpmeth_' + name]) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
615 obj['tpmeth_' + name] = expr.eval(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
616 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
617 return obj['tpmeth_' + name].apply(obj, arguments);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
618 };
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
619 env.syms[name].numargs = expr.numArgs();
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
620 })(msg.symbol.name, msg.expression);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
621 outmessages.push(msg);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
622 } else if (msg.expression instanceof funcall && msg.expression.name == 'macro:') {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
623 env.defMacro(msg.symbol.name, msg.expression.args[0].eval(env));
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
624 } else {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
625 outmessages.push(msg);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
626 /*
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
627 var makeProp = function(obj, name) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
628 obj['tprop_' + name] = msg.expression.eval(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
629 name = 'tpmeth_' + name;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
630 obj[name] = function() {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
631 return this[name];
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
632 };
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
633 var setname = name+'!';
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
634 obj[setname] = function(val) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
635 this[setname] = val;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
636 return this;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
637 };
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
638 };
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
639 makeProp(obj, msg.symbol.name);*/
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
640 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
641 } else {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
642 outmessages.push(msg);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
643 //throw new Error('pseudo function calls in object definitions not implemented yet');
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
644 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
645 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
646 this.messages = outmessages;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
647 return this;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
648 };
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
649
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
650 object.prototype.quote = function(parentenv) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
651 var env = new environment(parentenv);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
652 var outmessages = [];
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
653 for (var i = 0; i < this.messages.length; i++) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
654 var msg = this.messages[i];
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
655 if (msg instanceof assignment) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
656 env.syms[msg.symbol.name] = null;
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
657 if (!(msg.expression instanceof lambda)) {
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
658 env.syms[msg.symbol.name + '!'] = null;
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
659 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
660 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
661 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
662 for (var i = 0; i < this.messages.length; i++) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
663 var msg = this.messages[i];
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
664 if (msg instanceof assignment) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
665 outmessages.push(new assignment(msg.symbol, msg.expression.quote(env)));
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
666 } else {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
667 outmessages.push(msg.quote(env));
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
668 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
669 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
670 return new object(outmessages);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
671 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
672
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
673 object.prototype.makeHygienic = function(parentenv) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
674 var env = new environment(parentenv);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
675 var outmessages = [];
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
676 for (var i = 0; i < this.messages.length; i++) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
677 var msg = this.messages[i];
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
678 if (msg instanceof assignment) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
679 env.syms[msg.symbol.name] = null;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
680 //make sure method names don't get translated for hygiene
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
681 env.quotetrans[msg.symbol.name] = null;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
682 if (!(msg.expression instanceof lambda)) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
683 env.syms[msg.symbol.name + '!'] = null;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
684 env.quotetrans[msg.symbol.name + '!'] = null;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
685 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
686 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
687 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
688 for (var i = 0; i < this.messages.length; i++) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
689 var msg = this.messages[i];
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
690 if (msg instanceof assignment) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
691 outmessages.push(new assignment(msg.symbol, msg.expression.makeHygienic(env)));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
692 } else {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
693 outmessages.push(msg.makeHygienic(env));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
694 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
695 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
696 return new object(outmessages);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
697 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
698
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
699 object.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
700 return "object";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
701 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
702
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
703 object.prototype.tpmeth_addMessage = function(message) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
704 this.messages.push(makeASTNode(message));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
705 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
706 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
707
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
708 lambda.prototype.eval = function(parentenv) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
709 var args = this.args;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
710 var exprs = this.expressions;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
711 return function() {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
712 var env = new environment(parentenv);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
713 for (var i = 0, j = 0; i < arguments.length && j < args.length; i++, j++) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
714 while (j < args.length && args[j].cleanName() == 'self') {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
715 j++;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
716 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
717 env.syms[args[j].cleanName()] = arguments[i];
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
718 }
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
719 if (this != null) {
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
720 env.syms['self'] = this;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
721 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
722 var res = null;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
723 for (var i = 0; i < exprs.length; i++) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
724 res = exprs[i].eval(env);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
725 }
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
726 return res;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
727 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
728 };
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
729
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
730 lambda.prototype.macroexpand = function(parentenv) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
731 var env = new environment(parentenv);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
732 for (var i = 0; i < this.args.length; i++) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
733 env.syms[this.args[i].cleanName()] = {};
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
734 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
735 for (var i = 0; i < this.expressions.length; i++) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
736 var expr = this.expressions[i];
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
737 if (expr instanceof assignment) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
738 if (expr.expression instanceof funcall && expr.expression.name == 'macro:') {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
739 env.defMacro(expr.symbol.name, exp.expression.args[0].eval(env));
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
740 } else {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
741 env.syms[expr.symbol.cleanName()] = {};
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
742 this.expressions[i] = expr.macroexpand(env);
238
3bfc00e4f5e5 Eval lambda assignments at macro expandion time so they can be called by macros
Mike Pavone <pavone@retrodev.com>
parents: 224
diff changeset
743 if (this.expressions[i].expression instanceof lambda) {
3bfc00e4f5e5 Eval lambda assignments at macro expandion time so they can be called by macros
Mike Pavone <pavone@retrodev.com>
parents: 224
diff changeset
744 env.syms[expr.symbol.cleanName()] = this.expressions[i].expression.eval(env);
240
dc5f487247ee Don't rename the symbol self in quote blocks
Mike Pavone <pavone@retrodev.com>
parents: 238
diff changeset
745 } else {
dc5f487247ee Don't rename the symbol self in quote blocks
Mike Pavone <pavone@retrodev.com>
parents: 238
diff changeset
746 env.syms[expr.symbol.cleanName()] = null;
238
3bfc00e4f5e5 Eval lambda assignments at macro expandion time so they can be called by macros
Mike Pavone <pavone@retrodev.com>
parents: 224
diff changeset
747 }
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
748 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
749 } else {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
750 this.expressions[i] = expr.macroexpand(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
751 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
752 }
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
753 return this;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
754 };
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
755
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
756 lambda.prototype.quote = function(parentenv) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
757 var args = [];
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
758 var expressions = [];
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
759 var env = new environment(parentenv);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
760 for (var i = 0; i < this.args.length; i++) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
761 env.syms[this.args[i].cleanName()] = null;
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
762 var sym = new symbol(this.args[i].name, this.args[i].symbols);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
763 sym.dirty = true;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
764 args.push(sym);
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
765 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
766 for (var i = 0; i < this.expressions.length; i++) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
767 expressions.push(this.expressions[i].quote(env));
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
768 }
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
769 return new lambda(args, expressions);
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
770 };
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
771
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
772 lambda.prototype.makeHygienic = function(parentenv) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
773 var args = [];
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
774 var expressions = [];
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
775 var env = new environment(parentenv);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
776 for (var i = 0; i < this.args.length; i++) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
777 env.syms[this.args[i].cleanName()] = null;
240
dc5f487247ee Don't rename the symbol self in quote blocks
Mike Pavone <pavone@retrodev.com>
parents: 238
diff changeset
778 if (this.args[i].dirty && this.args[i].cleanName() != 'self') {
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
779 var hygienic = '' + quote_prefix + this.args[i].cleanName();
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
780 env.quotetrans[this.args[i].cleanName()] = hygienic;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
781 args.push(new symbol(hygienic, this.args[i].symbols));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
782 } else {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
783 args.push(this.args[i]);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
784 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
785 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
786 for (var i = 0; i < this.expressions.length; i++) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
787 expressions.push(this.expressions[i].makeHygienic(env));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
788 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
789 return new lambda(args, expressions);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
790 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
791
210
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
792 lambda.prototype.numArgs = function() {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
793 var num = this.args.length;
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
794 if (num && (this.args[0].cleanName() == 'self')) {
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
795 --num;
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
796 }
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
797 return num;
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
798 };
d0848563f25d Fix some bugs and allow proper access to list literals in interpreter/macro expander
Mike Pavone <pavone@retrodev.com>
parents: 209
diff changeset
799
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
800 lambda.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
801 return "lambda";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
802 };
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
803
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
804 lambda.prototype.tpmeth_args = function() {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
805 var cur = tplist.tpmeth_empty();
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
806 for (var idx = this.args.length - 1; idx >= 0; --idx) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
807 cur = tplist['tpmeth_node:withTail'](this.args[idx], cur);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
808 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
809 return cur;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
810 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
811
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
812 lambda.prototype.tpmeth_expressions = function() {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
813 var cur = tplist.tpmeth_empty();
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
814 for (var idx = this.expressions.length - 1; idx >= 0; --idx) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
815 cur = tplist['tpmeth_node:withTail'](this.expressions[idx], cur);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
816 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
817 return cur;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
818 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
819
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
820 lambda.prototype['tpmeth_expressions!'] = function(exprs) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
821 var expressions = [];
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
822 while (!exprs['tpmeth_empty?']().valueOf()) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
823 expressions.push(makeASTNode(exprs.tpmeth_value()));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
824 exprs = exprs.tpmeth_tail();
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
825 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
826 this.expressions = expressions;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
827 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
828 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
829
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
830 lambda.prototype.tpmeth_addExpression = function(expr) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
831 this.expressions.push(makeASTNode(expr));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
832 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
833 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
834
206
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
835 assignment.prototype.eval = function(env) {
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
836 var val = this.expression.eval(env);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
837 env.findSet(this.symbol.name, val);
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
838 return val;
b4a9d4e405c5 Implemented a simple interpreter to be used for macro expansion and a driver for testing it
Mike Pavone <pavone@retrodev.com>
parents:
diff changeset
839 };
207
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
840
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
841 assignment.prototype.macroexpand = function(env) {
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
842 this.expression = this.expression.macroexpand(env);
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
843 return this;
60eff5f81d9a Basic implementation of macros is now working
Mike Pavone <pavone@retrodev.com>
parents: 206
diff changeset
844 };
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
845
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
846 assignment.prototype.quote = function(env) {
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
847 var name = this.symbol.cleanName();
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
848 var val = env.find(name);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
849 var dirty = true;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
850 if (val) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
851 var node = makeASTNode(val);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
852 if (!(node instanceof symbol)) {
221
218b11ec8fa2 Better handling for weird values being inserted into AST due to quoting
Michael Pavone <pavone@retrodev.com>
parents: 219
diff changeset
853 throw new Error('Left hand side of assignment expression must be a symbol not a '+ node.constructor.name + ' '+(typeof node) + ', old name was ' + name);
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
854 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
855 name = node.cleanName();
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
856 dirty = node.dirty;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
857 }
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
858 env.syms[name] = null;
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
859 var sym = new symbol(name, this.symbol.symbols);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
860 sym.dirty = dirty;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
861 return new assignment(sym, this.expression.quote(env));
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
862 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
863
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
864 assignment.prototype.makeHygienic = function(env) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
865 var name = this.symbol.cleanName();
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
866 env.syms[name] = null;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
867 if (this.symbol.dirty) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
868 name = env.quotetrans[name] = '' + quote_prefix + name;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
869 }
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
870 return new assignment(new symbol(name, this.symbol.symbols), this.expression.makeHygienic(env));
208
a1b4a2bc8d72 Initial work on pattern match macrosfor the new parser
Mike Pavone <pavone@retrodev.com>
parents: 207
diff changeset
871 };
209
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
872
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
873 assignment.prototype.tpmeth_nodeType = function() {
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
874 return "assignment";
4b3b57f39f10 Implement zeroPlus macro
Michael Pavone <pavone@retrodev.com>
parents: 208
diff changeset
875 };
217
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
876
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
877 assignment.prototype.tpmeth_symbol = function() {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
878 return this.symbol;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
879 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
880
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
881 assignment.prototype['tpmeth_symbol!'] = function(val) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
882 this.symbol = makeASTNode(val);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
883 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
884 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
885
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
886 assignment.prototype.tpmeth_expression = function() {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
887 return this.expression;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
888 };
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
889
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
890 assignment.prototype['tpmeth_expression!'] = function(val) {
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
891 this.expression = makeASTNode(val);
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
892 return this;
adad61ea2f3a Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
Michael Pavone <pavone@retrodev.com>
parents: 213
diff changeset
893 };