comparison parser.js @ 217:adad61ea2f3a

Switched to a less hacky implementation of hygiene and exposed more AST properties to macros
author Michael Pavone <pavone@retrodev.com>
date Sat, 21 Dec 2013 12:07:51 -0800
parents e01137a97654
children 7435367a932a
comparison
equal deleted inserted replaced
216:2dac67e9d18b 217:adad61ea2f3a
1 1
2 function op(left, op, right) 2 function op(left, op, right)
3 { 3 {
4 this.left = left; 4 this.left = left;
5 if (op instanceof Array) {
6 op = op[0];
7 }
5 this.op = op; 8 this.op = op;
6 this.right = right; 9 this.right = right;
7 } 10 }
11 op.prototype.valueOf = function(indent) {
12 return this.left.valueOf(indent) + ' ' + this.op.valueOf(indent) + ' ' + this.right.valueOf(indent);
13 };
8 14
9 function symbol(name, symbols) 15 function symbol(name, symbols)
10 { 16 {
11 this.name = name; 17 this.name = name;
12 this.symbols = symbols; 18 this.symbols = symbols;
19 this.dirty = false;
13 } 20 }
14 symbol.prototype.cleanName = function() { 21 symbol.prototype.cleanName = function() {
15 return this.name[0] == ':' ? this.name.substr(1) : this.name; 22 return this.name[0] == ':' ? this.name.substr(1) : this.name;
16 } 23 }
24 symbol.prototype.valueOf = function() {
25 return this.name;
26 };
17 27
18 function intlit(val, bits, unsigned) 28 function intlit(val, bits, unsigned)
19 { 29 {
20 if (!bits) { 30 if (!bits) {
21 bits = 32; 31 bits = 32;
25 } 35 }
26 this.unsigned = unsigned; 36 this.unsigned = unsigned;
27 this.bits = bits; 37 this.bits = bits;
28 this.val = val; 38 this.val = val;
29 } 39 }
40 intlit.prototype.valueOf = function() {
41 var val = '' + this.val;
42 if (this.bits != 32 || this.unsigned) {
43 val += this.unsigned ? 'u' : 'i'
44 val += this.bits;
45 }
46 return val;
47 };
30 48
31 function floatlit(val) 49 function floatlit(val)
32 { 50 {
33 this.val = val; 51 this.val = val;
34 } 52 }
53 floatlit.prototype.valueOf = function() {
54 return '' + val;
55 };
35 56
36 function strlit(val) 57 function strlit(val)
37 { 58 {
38 this.val = val; 59 this.val = val;
39 } 60 }
61 strlit.prototype.valueOf = function() {
62 return '"'+this.val+'"';
63 };
40 64
41 function listlit(val) 65 function listlit(val)
42 { 66 {
43 this.val = val; 67 this.val = val;
44 } 68 }
69 listlit.prototype.valueOf = function(indent) {
70 if (indent === undefined) {
71 indent = '';
72 }
73 var nextindent = indent + '\t';
74 var val = '['
75 for (var i = 0; i < this.val.length; i++) {
76 val += '\n' + nextindent + this.val[i].valueOf(nextindent);
77 }
78 if (this.val.length) {
79 val += '\n' + indent;
80 }
81 val += ']';
82 return val;
83 };
45 84
46 function arraylit(val) 85 function arraylit(val)
47 { 86 {
48 this.val = val; 87 this.val = val;
49 } 88 }
89 arraylit.prototype.valueOf = function(indent) {
90 if (indent === undefined) {
91 indent = '';
92 }
93 var nextindent = indent + '\t';
94 var val = '#['
95 for (var i = 0; i < this.val.length; i++) {
96 val += '\n' + nextindent + this.val[i].valueOf(nextindent);
97 }
98 if (this.val.length) {
99 val += '\n' + indent;
100 }
101 val += ']';
102 return val;
103 };
50 104
51 function funcall(name, args) 105 function funcall(name, args)
52 { 106 {
53 this.name = name; 107 this.name = name;
54 this.args = args; 108 this.args = args;
55 this.receiver = null; 109 this.receiver = null;
56 } 110 this.dirty = false;
111 }
112 funcall.prototype.valueOf = function(indent) {
113 var parts = this.name.split(':');
114 var val = '';
115 if (this.receiver) {
116 val += this.receiver.valueOf(indent);
117 }
118 var curarg = 0;
119 for (var i = 0; i < parts.length; i++) {
120 if (val) {
121 val += ' ';
122 }
123 if (parts[i]) {
124 val += parts[i] + ': ';
125 }
126 if (curarg < this.args.length) {
127 val += this.args[curarg++].valueOf(indent);
128 }
129 }
130 while (curarg < this.args.length) {
131 val += ' ' + this.args[curarg++].valueOf(indent);
132 }
133 return val;
134 };
57 135
58 function object(messages) 136 function object(messages)
59 { 137 {
60 this.messages = messages; 138 this.messages = messages;
61 this.name = null; 139 this.name = null;
62 } 140 }
141 object.prototype.valueOf = function(indent) {
142 if (indent === undefined) {
143 indent = '';
144 }
145 var nextindent = indent + '\t';
146 var val = '#{';
147 for (var i = 0; i < this.messages.length; i++) {
148 val += '\n' + nextindent + this.messages[i].valueOf(nextindent);
149 }
150 if (val.length > 2) {
151 val += '\n' + indent;
152 }
153 val += '}';
154 return val;
155 };
63 156
64 function lambda(args, expressions) 157 function lambda(args, expressions)
65 { 158 {
66 this.args = args ? args : []; 159 this.args = args ? args : [];
67 this.expressions = expressions; 160 this.expressions = expressions;
68 } 161 }
162 lambda.prototype.valueOf = function(indent) {
163 if (indent === undefined) {
164 indent = '';
165 }
166 var nextindent = indent + '\t';
167 var val = '';
168 for (var i = 0; i < this.args.length; i++) {
169 val += this.args[i].valueOf(indent) + ' ';
170 }
171 val += '{';
172 for (var i = 0; i < this.expressions.length; i++) {
173 val += '\n' + nextindent + this.expressions[i].valueOf(nextindent);
174 }
175 if (this.expressions.length) {
176 val += '\n' + indent;
177 }
178 val += '}';
179 return val;
180 };
69 181
70 function assignment(sym, expr) 182 function assignment(sym, expr)
71 { 183 {
72 this.symbol = sym; 184 this.symbol = sym;
73 this.expression = expr; 185 this.expression = expr;
74 } 186 }
187 assignment.prototype.valueOf = function(indent) {
188 return this.symbol.valueOf(indent) + ' <- ' + this.expression.valueOf(indent);
189 };
75 190
76 function isLambda(node) 191 function isLambda(node)
77 { 192 {
78 return node instanceof lambda; 193 return node instanceof lambda;
79 } 194 }
85 'expr = e:(funcall / methcall / assignment / opexpr) ws { return e; };' + 200 'expr = e:(funcall / methcall / assignment / opexpr) ws { return e; };' +
86 'opexpr = left:compareop pieces:(hws ("&&" / "||") hws compareop)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 201 'opexpr = left:compareop pieces:(hws ("&&" / "||") hws compareop)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+
87 'compareop = left:maybecons pieces:(hws ("<=" / ">=" / "<" / ">" / "=" / "!=") hws maybecons)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 202 'compareop = left:maybecons pieces:(hws ("<=" / ">=" / "<" / ">" / "=" / "!=") hws maybecons)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+
88 'maybecons = consop / addsub;' + 203 'maybecons = consop / addsub;' +
89 'consop = left:addsub hws "|" hws right:maybecons { return new op(left, "|", right); };'+ 204 'consop = left:addsub hws "|" hws right:maybecons { return new op(left, "|", right); };'+
90 'addsub = left:muldiv pieces:(hws ("+"/"-"/"xor"/"and"/"or"/".") hws muldiv)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 205 'addsub = left:muldiv pieces:(hws ((("xor"/"and"/"or") ! [a-zA-Z_!?@0-9])/("+"/"-"/".")) hws muldiv)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+
91 'muldiv = left:primlitsym pieces:(hws ("*"/"/"/"%") hws primlitsym)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+ 206 'muldiv = left:primlitsym pieces:(hws ("*"/"/"/"%") hws primlitsym)* { if (pieces.length) { var cur = new op(left, pieces[0][1], pieces[0][3]); for (var i = 1; i < pieces.length; i++) { cur = new op(cur, pieces[i][1], pieces[i][3]); } return cur; } else { return left; } };'+
92 'primlitsym = hws val:(float / hex / binary / int / string / symbol / object / array / list / lambda / "(" ws expr:expr hws ")" { return expr; }) { return val; };' + 207 'primlitsym = hws val:(float / hex / binary / int / string / symbol / object / array / list / lambda / "(" ws expr:expr hws ")" { return expr; }) { return val; };' +
93 'symbol = chars:[a-zA-Z_!?@]+ trailing:(":"? [a-zA-Z_!?@0-9])* ! ":" { for (var i = 0; i < trailing.length; i++) { trailing[i] = trailing[i].join(""); } return new symbol(chars.join("") + trailing.join("")); };' + 208 'symbol = chars:[a-zA-Z_!?@]+ trailing:(":"? [a-zA-Z_!?@0-9])* ! ":" { for (var i = 0; i < trailing.length; i++) { trailing[i] = trailing[i].join(""); } return new symbol(chars.join("") + trailing.join("")); };' +
94 'float = digits:[0-9]+ "." decimals:[0-9]+ { return new floatlit(parseFloat(digits.join("") + "." + decimals.join(""))); };' + 209 'float = digits:[0-9]+ "." decimals:[0-9]+ { return new floatlit(parseFloat(digits.join("") + "." + decimals.join(""))); };' +
95 'binary = "0b" digits:[01]+ { return new intlit(parseInt(digits.join(""), 2)); };' + 210 'binary = "0b" digits:[01]+ { return new intlit(parseInt(digits.join(""), 2)); };' +