Mercurial > repos > tabletprog
annotate parser.js @ 96:84b65ee8b78b
Optimize self method calls into static function calls
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 26 Jul 2012 18:54:42 -0700 |
parents | ce6a81b3be70 |
children | 648659961e0e |
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 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
18 function intlit(val) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
19 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
20 this.val = val; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
21 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
22 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
23 function floatlit(val) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
24 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
25 this.val = val; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
26 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
27 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
28 function strlit(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 this.val = val; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
31 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
32 |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
33 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
|
34 { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
35 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
|
36 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
37 |
38 | 38 function arraylit(val) |
39 { | |
40 this.val = val; | |
41 } | |
42 | |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
43 function funcall(name, args) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
44 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
45 this.name = name; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
46 this.args = args; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
47 this.receiver = null; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
48 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
49 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
50 function object(messages) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
51 { |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
52 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
|
53 this.name = null; |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
54 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
55 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
56 function lambda(args, expressions) |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
57 { |
42
4e983fe32047
Fix closures as methods so that private vars work
Mike Pavone <pavone@retrodev.com>
parents:
38
diff
changeset
|
58 this.args = args ? args : []; |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
59 this.expressions = expressions; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
60 } |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
61 |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
62 function assignment(sym, expr) |
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 this.symbol = sym; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
65 this.expression = expr; |
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
66 } |
1 | 67 |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
68 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
|
69 { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
70 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
|
71 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
72 |
0 | 73 var grammar = |
1 | 74 'start = ws module:(object / lambda) ws { return module; };' + |
4 | 75 'ws = ([ \\t\\n\\r] / "//" [^\\n]* "\\n")*;' + |
76 'hws = ([ \\t] / "/*" ([^*] / "*" ! "/")* "*/" )*;' + | |
2
454c0346f357
Added method call syntax and comparison operators
Mike Pavone <pavone@retrodev.com>
parents:
1
diff
changeset
|
77 '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
|
78 '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; } };'+ |
fdb9785d2c93
Add logical operators to grammar. Allow vertical whitespace after funcall expression in object.
Mike Pavone <pavone@retrodev.com>
parents:
68
diff
changeset
|
79 'compareop = left:addsub pieces:(hws ("<=" / ">=" / "<" / ">" / "=" / "!=") hws addsub)* { 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; } };'+ |
86
ce6a81b3be70
Add xor operator to grammar
Mike Pavone <pavone@retrodev.com>
parents:
83
diff
changeset
|
80 'addsub = left:muldiv pieces:(hws ("+"/"-"/"xor"/".") 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 | 81 '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
|
82 'primlitsym = hws val:(float / hex / binary / int / string / symbol / object / array / list / lambda / "(" ws expr:expr hws ")" { return expr; }) { return val; };' + |
6
554602d4cbc6
Javascript compiler backend
Mike Pavone <pavone@retrodev.com>
parents:
5
diff
changeset
|
83 'symbol = chars:[a-zA-Z_!?@]+ trailing:(":"? [a-zA-Z_!?@0-9])* ! ":" { for (var i in trailing) { 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
|
84 '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
|
85 'binary = "0b" digits:[01]+ { return new intlit(parseInt(digits.join(""), 2)); };' + |
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
|
86 'hex = "0x" digits:[0-9a-fA-F]+ { return new intlit(parseInt(digits.join(""), 16)); };' + |
68
3a169ebb3224
Change strategy for handling true and false to avoid some initialization order problems and improve performance. Add support for negative integer literals. Update samples to reflect true/false change.
Mike Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
87 'int = sign:"-"? digits:[0-9]+ { return new intlit(parseInt(sign + digits.join(""), 10)); };' + |
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
|
88 'string = "\\"" text:(strpart/escape)* "\\"" { return new strlit(text.join("")); };' + |
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
|
89 'strpart = text:[^\\"\\\\]+ { return text.join(""); };' + |
56 | 90 '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
|
91 'object = "#{" ws messages:(assignment / funexpr)* "}" { return new object(messages); };' + |
38 | 92 'array = "#[" ws els:opexpr* "]" { return new arraylit(els); };' + |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
93 'list = "[" ws els:opexpr* "]" { return new listlit(els); };' + |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
22
diff
changeset
|
94 'assignment = ws sym: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
|
95 '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
|
96 '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
|
97 'funexpr = f: funcall ws { return f; };' + |
5
ed5b563147ec
Wrote constructors for AST objects
Mike Pavone <pavone@retrodev.com>
parents:
4
diff
changeset
|
98 'funcall = hws parts: funcallpart+ { var fun = ""; var args = []; for (var i in parts) { 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
|
99 '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
|
100 '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
|
101 '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
|
102 'methcallrest = funcall / unarymeth;' + |
6
554602d4cbc6
Javascript compiler backend
Mike Pavone <pavone@retrodev.com>
parents:
5
diff
changeset
|
103 'unarymeth = name:symbol { return new funcall(name.name, []); };'; |
0 | 104 var parser = PEG.buildParser(grammar); |
105 | |
106 |