Mercurial > repos > tabletprog
annotate parser.js @ 201:d2e0664ba73e
Don't allow assignments to module variables
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 28 Aug 2013 01:05:14 -0700 |
parents | 810edf474f86 |
children | e01137a97654 |
rev | line source |
---|---|
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
1 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
2 function op(left, op, right) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
3 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
4 this.left = left; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
5 this.op = op; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
6 this.right = right; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
7 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
8 |
19
132c7756860e
Use populateSymbols to generate symbol tables during compilation rather than populating them as we go. This change allows us to refer to symbols defined later in the input stream and also gives the symbol table logic a single home that can be used both by the compiler and editor.
Mike Pavone <pavone@retrodev.com>
parents:
8
diff
changeset
|
9 function symbol(name, symbols) |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
10 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
11 this.name = name; |
19
132c7756860e
Use populateSymbols to generate symbol tables during compilation rather than populating them as we go. This change allows us to refer to symbols defined later in the input stream and also gives the symbol table logic a single home that can be used both by the compiler and editor.
Mike Pavone <pavone@retrodev.com>
parents:
8
diff
changeset
|
12 this.symbols = symbols; |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
13 } |
6
554602d4cbc6
Javascript compiler backend
Mike Pavone <pavone@retrodev.com>
parents:
5
diff
changeset
|
14 symbol.prototype.cleanName = function() { |
554602d4cbc6
Javascript compiler backend
Mike Pavone <pavone@retrodev.com>
parents:
5
diff
changeset
|
15 return this.name[0] == ':' ? this.name.substr(1) : this.name; |
554602d4cbc6
Javascript compiler backend
Mike Pavone <pavone@retrodev.com>
parents:
5
diff
changeset
|
16 } |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
17 |
155
9de2572a34a7
Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
18 function intlit(val, bits, unsigned) |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
19 { |
135
f98790d8a53d
Add int64, int16 and int8. Also add hex method to integer types.
Mike Pavone <pavone@retrodev.com>
parents:
134
diff
changeset
|
20 if (!bits) { |
f98790d8a53d
Add int64, int16 and int8. Also add hex method to integer types.
Mike Pavone <pavone@retrodev.com>
parents:
134
diff
changeset
|
21 bits = 32; |
f98790d8a53d
Add int64, int16 and int8. Also add hex method to integer types.
Mike Pavone <pavone@retrodev.com>
parents:
134
diff
changeset
|
22 } |
155
9de2572a34a7
Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
23 if (unsigned === undefined) { |
9de2572a34a7
Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
24 unsigned = false; |
9de2572a34a7
Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
25 } |
9de2572a34a7
Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
26 this.unsigned = unsigned; |
135
f98790d8a53d
Add int64, int16 and int8. Also add hex method to integer types.
Mike Pavone <pavone@retrodev.com>
parents:
134
diff
changeset
|
27 this.bits = bits; |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
28 this.val = val; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
29 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
30 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
31 function floatlit(val) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
32 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
33 this.val = val; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
34 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
35 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
36 function strlit(val) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
37 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
38 this.val = val; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
39 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
40 |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
41 function listlit(val) |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
42 { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
43 this.val = val; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
44 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
45 |
38 | 46 function arraylit(val) |
47 { | |
48 this.val = val; | |
49 } | |
50 | |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
51 function funcall(name, args) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
52 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
53 this.name = name; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
54 this.args = args; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
55 this.receiver = null; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
56 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
57 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
58 function object(messages) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
59 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
60 this.messages = messages; |
83
fdb9785d2c93
Add logical operators to grammar. Allow vertical whitespace after funcall expression in object.
Mike Pavone <pavone@retrodev.com>
parents:
68
diff
changeset
|
61 this.name = null; |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
62 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
63 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
64 function lambda(args, expressions) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
65 { |
42
4e983fe32047
Fix closures as methods so that private vars work
Mike Pavone <pavone@retrodev.com>
parents:
38
diff
changeset
|
66 this.args = args ? args : []; |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
67 this.expressions = expressions; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
68 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
69 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
70 function assignment(sym, expr) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
71 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
72 this.symbol = sym; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
73 this.expression = expr; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
74 } |
1 | 75 |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
76 function isLambda(node) |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
77 { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
78 return node instanceof lambda; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
79 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
80 |
122
9820ecd4eed4
Add support for implementing operators on user defined objects
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
81 var grammar = |
1 | 82 'start = ws module:(object / lambda) ws { return module; };' + |
4 | 83 'ws = ([ \\t\\n\\r] / "//" [^\\n]* "\\n")*;' + |
84 'hws = ([ \\t] / "/*" ([^*] / "*" ! "/")* "*/" )*;' + | |
2
454c0346f357
Added method call syntax and comparison operators
Mike Pavone <pavone@retrodev.com>
parents:
1
diff
changeset
|
85 'expr = e:(funcall / methcall / opexpr) ws { return e; };' + |
83
fdb9785d2c93
Add logical operators to grammar. Allow vertical whitespace after funcall expression in object.
Mike Pavone <pavone@retrodev.com>
parents:
68
diff
changeset
|
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; } };'+ |
170
18598163e3ef
Add linked list implementation and cons operator
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
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; } };'+ |
18598163e3ef
Add linked list implementation and cons operator
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
88 'maybecons = consop / addsub;' + |
18598163e3ef
Add linked list implementation and cons operator
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
89 'consop = left:addsub hws "|" hws right:maybecons { return new op(left, "|", right); };'+ |
134
34e0befbdd77
Add bitwise operations to int32 in the C backend
Mike Pavone <pavone@retrodev.com>
parents:
122
diff
changeset
|
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; } };'+ |
67 | 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; } };'+ |
53
9482a0afe07c
Fix whitespace for parens in grammar
Mike Pavone <pavone@retrodev.com>
parents:
49
diff
changeset
|
92 'primlitsym = hws val:(float / hex / binary / int / string / symbol / object / array / list / lambda / "(" ws expr:expr hws ")" { return expr; }) { return val; };' + |
104 | 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("")); };' + |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
94 'float = digits:[0-9]+ "." decimals:[0-9]+ { return new floatlit(parseFloat(digits.join("") + "." + decimals.join(""))); };' + |
49
f2cda2e6f70e
Fix os open to optionally take a file permission bit parameter. Update example to use this parameter. Add support for hex and binary integer literals
Mike Pavone <pavone@retrodev.com>
parents:
44
diff
changeset
|
95 'binary = "0b" digits:[01]+ { return new intlit(parseInt(digits.join(""), 2)); };' + |
155
9de2572a34a7
Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
96 'hex = "0x" digits:[0-9a-fA-F]+ size:([iu] ("8" / "16" / "32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 0; return new intlit(parseInt(digits.join(""), 16), bits, size[0] == "u"); };' + |
9de2572a34a7
Added some stuff for compiler debugging. Added unsigned integer types. Added integer size conversion methods to integer objects.
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
97 'int = sign:"-"? digits:[0-9]+ size:([iu] ("8" / "16" / "32" / "64"))? { var bits = size ? parseInt(size[1], 10) : 0; return new intlit(parseInt(sign + digits.join(""), 10), bits, size[0] == "u"); };' + |
44
9dd370530f69
Fix escape codes in string literals. Don't print out the return value of main method. Fixup fib example to use print: method. Cleanup error handling in compiler slightly
Mike Pavone <pavone@retrodev.com>
parents:
43
diff
changeset
|
98 'string = "\\"" text:(strpart/escape)* "\\"" { return new strlit(text.join("")); };' + |
122
9820ecd4eed4
Add support for implementing operators on user defined objects
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
99 'strpart = text:[^\\"\\\\]+ { return text.join(""); };' + |
56 | 100 'escape = "\\\\" char:[nt\\"r\\\\] { if (char == "n") { return "\\n"; } if (char == "r") { return "\\r"; } return char; };' + |
83
fdb9785d2c93
Add logical operators to grammar. Allow vertical whitespace after funcall expression in object.
Mike Pavone <pavone@retrodev.com>
parents:
68
diff
changeset
|
101 'object = "#{" ws messages:(assignment / funexpr)* "}" { return new object(messages); };' + |
176
ab204751d1e7
Allow all expressions in array and list literals
Mike Pavone <pavone@retrodev.com>
parents:
171
diff
changeset
|
102 'array = "#[" ws els:expr* "]" { return new arraylit(els); };' + |
ab204751d1e7
Allow all expressions in array and list literals
Mike Pavone <pavone@retrodev.com>
parents:
171
diff
changeset
|
103 'list = "[" ws els:expr* "]" { return new listlit(els); };' + |
170
18598163e3ef
Add linked list implementation and cons operator
Mike Pavone <pavone@retrodev.com>
parents:
138
diff
changeset
|
104 'opsym = name:("&&" / "||" / "<=" / ">=" / "<" / ">" / "=" / "!=" / "+" / "-" / "." / "*" / "/" / "%" / "|") { return new symbol(name); };' + |
187
810edf474f86
Fix parse precedence problem between opsyms and symbols in assignments
Mike Pavone <pavone@retrodev.com>
parents:
176
diff
changeset
|
105 'assignment = ws sym:(opsym / symbol) hws "<-" expr:expr ws { return new assignment(sym, expr); }' + |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
106 'lambda = args:((& ":") argname+ )? "{" ws exprs:(assignment / expr)* "}" { return new lambda(args[1], exprs); };' + |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
107 'argname = init:":"? chars:[a-zA-Z_!?@]+ trailing:[a-zA-Z_!?@0-9]* hws { return new symbol(init + chars.join("") + trailing.join("")); };' + |
83
fdb9785d2c93
Add logical operators to grammar. Allow vertical whitespace after funcall expression in object.
Mike Pavone <pavone@retrodev.com>
parents:
68
diff
changeset
|
108 'funexpr = f: funcall ws { return f; };' + |
104 | 109 'funcall = hws parts: funcallpart+ { var fun = ""; var args = []; for (var i = 0; i < parts.length; i++) { fun += parts[i].name; args = args.concat(parts[i].args); } return new funcall(fun, args); };' + |
2
454c0346f357
Added method call syntax and comparison operators
Mike Pavone <pavone@retrodev.com>
parents:
1
diff
changeset
|
110 'funcallpart = fun:funpart args:opexpr* hws { return { name: fun, args: args}; };' + |
454c0346f357
Added method call syntax and comparison operators
Mike Pavone <pavone@retrodev.com>
parents:
1
diff
changeset
|
111 'funpart = chars:[a-zA-Z_!?@]+ middle:[a-zA-Z_!?@0-9]* ":" & [ \\t\\n\\r] { return chars.join("") + middle.join("") + ":"; };' + |
454c0346f357
Added method call syntax and comparison operators
Mike Pavone <pavone@retrodev.com>
parents:
1
diff
changeset
|
112 'methcall = receiver:opexpr hws info:methcallrest { info.receiver = receiver; return info; };' + |
454c0346f357
Added method call syntax and comparison operators
Mike Pavone <pavone@retrodev.com>
parents:
1
diff
changeset
|
113 'methcallrest = funcall / unarymeth;' + |
6
554602d4cbc6
Javascript compiler backend
Mike Pavone <pavone@retrodev.com>
parents:
5
diff
changeset
|
114 'unarymeth = name:symbol { return new funcall(name.name, []); };'; |
0 | 115 var parser = PEG.buildParser(grammar); |
116 | |
117 |