Mercurial > repos > tabletprog
annotate jsbackend.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 | a83989115028 |
children |
rev | line source |
---|---|
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1 var mainModule; |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
30
diff
changeset
|
2 var modules = {}; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
3 |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
4 function toobj(val) |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
5 { |
104 | 6 return (typeof val == "boolean") ? (val ? module_true : module_false) : val; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
9 function importSym(obj, src, key) |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
10 { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
11 if(!(key in src)) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
12 throw new Error(key +' not found in source object for import'); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
13 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
14 if(key in obj) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
15 throw new Error(key +' already exists in target object for import') |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
16 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
17 obj[key] = src[key]; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
18 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
19 |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
20 function doImport(obj, src, symlist) |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
21 { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
22 if (symlist === undefined) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
23 each(src, function(key,val) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
24 if (key != 'parent') { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
25 importSym(obj, src, key); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
26 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
27 }); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
28 } else { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
29 for (var i = 0; i < symlist.length; ++i) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
30 importSym(obj, src, symlist[i]); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
31 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
32 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
33 return obj; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
34 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
35 |
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:
12
diff
changeset
|
36 op.prototype.toJS = function(isReceiver) { |
110
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
37 if (this.op == '&&') { |
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
38 var ret = 'toobj(' + this.left.toJS() + ').sif(' + this.right.toJS() + ')'; |
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
39 } else if(this.op == '||') { |
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
40 var ret = 'toobj(' + this.left.toJS() + ').ifnot(' + this.right.toJS() + ')'; |
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
41 } else { |
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
42 var opmap = {'=': '==', '.': '+'}; |
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
43 var ret = '(' + this.left.toJS() +' '+ (this.op in opmap ? opmap[this.op] : this.op) +' '+ this.right.toJS() + ')'; |
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
44 } |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 return ret; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 }; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
48 function escapeJSName(name) |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
49 { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 name = name.replace("_", "UN_").replace(":", "CN_").replace("!", "EX_").replace('?', 'QS_').replace('@', 'AT_'); |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 var reserved = {'true': true, 'false': true, 'this': true, 'if': true, 'else': true, 'NaN': true}; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 if (name in reserved) { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 name = 's' + name; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 return name; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
58 symbol.prototype.toJS = function() { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
59 var name = this.cleanName(); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
60 if (name == 'self') { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
61 return this.symbols.selfVar(); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
62 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
63 var info = this.symbols.find(name); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
64 if (!info) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
65 throw new Error('symbol ' + name + ' not found'); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
66 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
67 var pre = ''; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
68 if (info.type == 'self') { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
69 pre = this.symbols.selfVar() + '.'; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
70 } else if(info.type == 'parent') { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
71 pre = 'this'; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
72 for (var i = 0; i < funinfo.depth; ++i) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
73 pre += '.parent'; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
74 } |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
30
diff
changeset
|
75 } else if (info.type == 'toplevel') { |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
76 return toplevel.moduleVar(name); |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
77 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
78 return pre + escapeJSName(name); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
79 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
80 |
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:
12
diff
changeset
|
81 intlit.prototype.toJS = function() { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 return this.val.toString(); |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 |
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:
12
diff
changeset
|
85 floatlit.prototype.toJS = function() { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 return this.val.toString(); |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 |
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:
12
diff
changeset
|
89 strlit.prototype.toJS = function() { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 return '"' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '"'; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
93 listlit.prototype.toJS = function() { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
94 var ret = '['; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
95 each(this.val, function(idx, el) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
96 ret += (idx ? ', ' : '') + el.toJS(); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
97 }); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
98 return ret + ']'; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
99 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
100 |
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:
12
diff
changeset
|
101 funcall.prototype.toJS = function() { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 var name = this.name[this.name.length-1] == ':' ? this.name.substr(0, this.name.length-1) : this.name; |
12
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
103 if (name == 'foreign') { |
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
104 if ((this.args[0] instanceof lambda) || (this.args[0] instanceof object)) { |
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
105 return null; |
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
106 } else if(this.args[0] instanceof symbol) { |
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
107 return this.args[0].name; |
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
108 } else { |
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
109 throw new Error("Unexpected AST type for foreign:"); |
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
110 } |
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
111 } |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 var args = this.args.slice(0, this.args.length); |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 if (this.receiver) { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 args.splice(0, 0, this.receiver); |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 } |
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:
12
diff
changeset
|
116 var funinfo = this.symbols.find(name); |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
117 if (!funinfo || funinfo.def instanceof setter || funinfo.type == 'toplevel') { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 var receiver = args[0]; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
119 args.splice(0, 1); |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 for (var i in args) { |
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:
12
diff
changeset
|
121 args[i] = args[i].toJS(); |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 } |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
123 var rJS = (funinfo ? '' : 'toobj(') + receiver.toJS(true) + (funinfo ? '' : ')') ; |
20
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
124 if ((name[name.length-1] == '!' && args.length == 1) || (funinfo && funinfo.def instanceof setter)) { |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
125 return '(' + rJS + '.' + escapeJSName(name.substr(0, name.length-1)) + ' = ' + args[0] + ', ' + rJS + ')'; |
20
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
126 } else { |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
127 var callee = rJS + '.' + escapeJSName(name); |
21
6c8ae6b47ab5
Small improvements to property support and elimination of setP and getP functions as they are no longer needed
Mike Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
128 if (args.length == 0) { |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
129 return callee; |
21
6c8ae6b47ab5
Small improvements to property support and elimination of setP and getP functions as they are no longer needed
Mike Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
130 } else { |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
131 return callee + '(' + args.join(', ') + ')'; |
21
6c8ae6b47ab5
Small improvements to property support and elimination of setP and getP functions as they are no longer needed
Mike Pavone <pavone@retrodev.com>
parents:
20
diff
changeset
|
132 } |
20
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
133 } |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 } |
20
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
135 var ret = ''; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
136 switch(funinfo.type) |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
137 { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
138 case 'self': |
115
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
139 if (args.length < funinfo.def.args.length || funinfo.def.args.length == 0 || funinfo.def.args[0].name != 'self') { |
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:
12
diff
changeset
|
140 var receiver = new symbol('self', this.symbols); |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 } else { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 var receiver = args[0]; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 args.splice(0, 1); |
30
608eb70fe261
Fix some compiler bugs and do initial work on module import
Mike Pavone <pavone@retrodev.com>
parents:
25
diff
changeset
|
144 if (args.length == 0) { |
608eb70fe261
Fix some compiler bugs and do initial work on module import
Mike Pavone <pavone@retrodev.com>
parents:
25
diff
changeset
|
145 var rJS = receiver.toJS(true); |
608eb70fe261
Fix some compiler bugs and do initial work on module import
Mike Pavone <pavone@retrodev.com>
parents:
25
diff
changeset
|
146 var callee = rJS + '.' + escapeJSName(name); |
608eb70fe261
Fix some compiler bugs and do initial work on module import
Mike Pavone <pavone@retrodev.com>
parents:
25
diff
changeset
|
147 |
608eb70fe261
Fix some compiler bugs and do initial work on module import
Mike Pavone <pavone@retrodev.com>
parents:
25
diff
changeset
|
148 return '(' + callee + ' instanceof Function ? ' + callee + '() : ' + callee + ')'; |
608eb70fe261
Fix some compiler bugs and do initial work on module import
Mike Pavone <pavone@retrodev.com>
parents:
25
diff
changeset
|
149 } |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
150 } |
20
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
151 ret = receiver.toJS(true) + '.'; |
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
152 break; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 case 'parent': |
115
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
154 var receiver = new symbol('self', this.symbols); |
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
155 ret = receiver.toJS(true); |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
156 for (var i = 0; i < funinfo.depth; ++i) { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 ret += '.parent'; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
158 } |
20
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
159 break; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 } |
20
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
161 for (var i in args) { |
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
162 args[i] = args[i].toJS(); |
bf03c9f0dd55
Initial work on proper property support
Mike Pavone <pavone@retrodev.com>
parents:
19
diff
changeset
|
163 } |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
164 return ret + escapeJSName(name) + '(' + args.join(', ') + ')'; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 |
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:
12
diff
changeset
|
167 object.prototype.toJS = function() { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 var messages = this.messages; |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
169 var compiled = []; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
170 var imports = [] |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 for (var i in messages) { |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
172 if (messages[i] instanceof funcall) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
173 if (messages[i].name == 'import:' && messages[i].args.length == 1) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
174 imports.push({symbols: false, src: messages[i].args[0]}); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
175 } else if(messages[i].name == 'import:from:' && messages[i].args.length == 2) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
176 var importsyms = []; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
177 each(messages[i].args[0].val, function(i, el) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
178 if (!(el instanceof symbol)) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
179 throw new Error('Names in import:from statement must be symbols'); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
180 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
181 importsyms.push(new strlit(el.name)); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
182 }); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
183 imports.push({symbols: new listlit(importsyms), src: messages[i].args[1]}); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
184 } else { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
185 throw new Error('Only import and import:from calls allowed in object context'); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
186 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
187 } else { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
188 var js = messages[i].toJSObject(); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
189 if (js) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
190 compiled.push(indent(js)); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
191 } |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
192 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
193 } |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
194 var pre = ''; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
195 var post = ''; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
196 for (var i = imports.length-1; i >= 0; i--) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
197 pre += 'doImport('; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
198 post += ', ' + imports[i].src.toJS(); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
199 if (imports[i].symbols) { |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
200 post += ', ' + imports[i].symbols.toJS(); |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
201 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
202 post += ')'; |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
203 } |
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
204 return pre+'{\n\tparent: ' + this.symbols.parentObject() + ',\n\t' + compiled.join(',\n\t') + '\n}'+post; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
205 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
206 |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
207 object.prototype.toJSModule = function() { |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
30
diff
changeset
|
208 this.populateSymbols(toplevel); |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
209 return '(function () {\n\tvar module = ' + indent(this.toJS()) + ';\n\treturn module;\n})();' |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
210 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
211 |
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:
12
diff
changeset
|
212 lambda.prototype.toJS = function() { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
213 var args = this.args ? this.args.slice(0, this.args.length) : []; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
214 if (args.length && args[0].cleanName() == 'self') { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
215 args.splice(0, 1); |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
216 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
217 var exprs = this.expressions; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
218 for (var i in args) { |
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:
12
diff
changeset
|
219 args[i] = args[i].toJS(); |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
220 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
221 var compiled = [] |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
222 for (var i in exprs) { |
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:
12
diff
changeset
|
223 var js = exprs[i].toJS(); |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
224 if (js) { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
225 compiled.push(indent(js)); |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
226 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
227 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
228 exprs = compiled; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
229 if (exprs.length) { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
230 exprs[exprs.length-1] = 'return ' + exprs[exprs.length-1] + ';'; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
231 } |
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:
12
diff
changeset
|
232 return 'function (' + args.join(', ') + ') {\n\t' + (this.symbols.needsSelfVar ? 'var self = this;\n\t' : '') + exprs.join(';\n\t') + '\n}' |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
233 }; |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
234 lambda.prototype.nonSelfArgs = function() { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
235 var args = this.args ? this.args.slice(0, this.args.length) : []; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
236 if (args.length && args[0].cleanName() == 'self') { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
237 args.splice(0, 1); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
238 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
239 return args; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
240 }; |
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:
12
diff
changeset
|
241 lambda.prototype.toJSModule = function() { |
31
668f533e5284
Add initial version of C backend
Mike Pavone <pavone@retrodev.com>
parents:
30
diff
changeset
|
242 this.populateSymbols(toplevel); |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
243 return this.toJS() + '();'; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
244 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
245 |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
246 modulefile.prototype.toJSModule = function(){ |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
247 return this.ast.toJSModule(); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
248 }; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
249 |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
250 function processUsedToplevelJS(toplevel) |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
251 { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
252 var alwaysused = ['true', 'false']; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
253 var ret = ''; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
254 var modulenum = 0; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
255 var visited = {}; |
104 | 256 for (var i = 0; i < alwaysused.length; i++) { |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
257 toplevel.used[alwaysused[i]] = true; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
258 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
259 var newused = Object.keys(toplevel.used); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
260 var allused = newused; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
261 while (newused.length) { |
104 | 262 for (var i = 0; i < newused.length; i++) { |
263 console.log(i, newused[i]); | |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
264 toplevel.names[newused[i]].populateSymbols(toplevel); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
265 visited[newused[i]] = true; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
266 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
267 newused = []; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
268 for (var symbol in toplevel.used) { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
269 if (!(symbol in visited)) { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
270 newused.push(symbol); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
271 allused.push(symbol); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
272 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
273 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
274 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
275 |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
276 for (var i = allused.length-1; i >= 0; i--) { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
277 var symbol = allused[i]; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
278 ret += 'var ' + toplevel.moduleVar(symbol) + ' = ' + toplevel.names[symbol].toJSModule() + '\n'; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
279 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
280 return ret; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
281 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
282 |
104 | 283 function asyncProcessTopLevelJS(toplevel, whenDone) |
284 { | |
285 var alwaysused = ['true', 'false']; | |
286 var ret = ''; | |
287 var modulenum = 0; | |
288 var visited = {}; | |
289 for (var i = 0; i < alwaysused.length; i++) { | |
290 toplevel.used[alwaysused[i]] = true; | |
291 } | |
292 var newused = Object.keys(toplevel.used); | |
293 var allused = newused; | |
294 var i = -1; | |
295 var handler = function() { | |
296 i++; | |
297 while(newused.length) | |
298 { | |
299 if (i < newused.length) { | |
300 visited[newused[i]] = true; | |
301 toplevel.names[newused[i]].popuplateSymbolsAsync(toplevel, handler); | |
302 return; | |
303 } else { | |
304 newused = []; | |
305 for (var symbol in toplevel.used) { | |
306 if (!(symbol in visited)) { | |
307 newused.push(symbol); | |
308 allused.push(symbol); | |
309 } | |
310 } | |
311 i = 0; | |
312 } | |
313 } | |
314 whenDone(); | |
315 }; | |
316 handler(); | |
317 } | |
318 | |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
319 function makeJSProg(mainmodule) |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
320 { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
321 return processUsedToplevelJS(toplevel) + 'main_module = ' + mainmodule.toJSModule() + '\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
322 'Number.prototype.__defineGetter__("string", function() { return "" + this; });\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
323 'String.prototype.__defineGetter__("string", function() { return this; });\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
324 'String.prototype.__defineGetter__("print", function() { write(this); });\n' + |
110
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
325 'Object.defineProperty(Array.prototype, "foreach", {value: function(action) { var ret = module_false; for (var i = 0; i < this.length; i++) { ret = action(i, this[i]) }; return ret; }});\n' + |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
326 'Function.prototype.whileCN_do = function(action) { var ret = module_false; while(toobj(this()) == module_true) { ret = action(); } return ret; };\n' + |
110
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
327 'module_true.valueOf = function() { return true; }\n' + |
d715fb3c39ab
Implemented clicking on symbols inside inscope box to replace function name in funcall.
Mike Pavone <pavone@retrodev.com>
parents:
104
diff
changeset
|
328 'module_false.valueOf = function() { return false; }\n' + |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
329 'function toobj(val) {\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
330 ' return (typeof val == "boolean") ? (val ? module_true : module_false) : val;\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
331 '}\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
332 'var m = main_module.main;\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
333 'if (m instanceof Function) {\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
334 ' m(arguments);\n' + |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
335 '}\n'; |
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:
12
diff
changeset
|
336 } |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
337 |
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:
12
diff
changeset
|
338 assignment.prototype.toJS = function() { |
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:
12
diff
changeset
|
339 var existing = this.symbols.find(this.symbol.name); |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
340 var prefix = ''; |
115
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
341 /*if (!existing) { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
342 prefix = 'var '; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
343 } else { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
344 switch (existing.type) |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
345 { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
346 case 'self': |
115
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
347 var self = new symbol('self', this.symbols); |
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
348 prefix = self.toJS() + '.'; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
349 break; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
350 case 'parent': |
115
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
351 var self = new symbol('self', this.symbols); |
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
352 prefix = self.toJS() + '.'; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
353 for (var i = 0; i < existing.depth; ++i) { |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
354 prefix += 'parent.'; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
355 } |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
356 break; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
357 } |
115
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
358 }*/ |
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:
12
diff
changeset
|
359 var val = this.expression.toJS(); |
12
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
360 if (val === null) { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
361 return null; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
362 } |
115
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
363 if ((existing.type == 'local' || existing.type == 'closedover') && !existing.isdeclared) { |
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
364 prefix = 'var '; |
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
365 this.symbols.declareVar(this.symbol.name); |
a83989115028
Fix some variable scope issues in the JS backend.
Mike Pavone <pavone@retrodev.com>
parents:
110
diff
changeset
|
366 } |
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:
12
diff
changeset
|
367 return prefix + this.symbol.toJS() + ' = ' + val; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
368 }; |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
369 function removeInitialFunction(str) |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
370 { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
371 var f = 'function'; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
372 str = str.trim(); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
373 if (str.substr(0, f.length) == f) { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
374 return str.substr(f.length); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
375 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
376 return str; |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
377 } |
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:
12
diff
changeset
|
378 assignment.prototype.toJSObject = function() { |
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:
12
diff
changeset
|
379 var val = this.expression.toJS(); |
12
6e4851a204a5
Add ability to load code into editor
Mike Pavone <pavone@retrodev.com>
parents:
10
diff
changeset
|
380 if (val === null) { |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
381 return null; |
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
382 } |
95
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
383 if (this.expression instanceof lambda) { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
384 var args = this.expression.nonSelfArgs(); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
385 if (args.length == 0) { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
386 return 'get ' + escapeJSName(this.symbol.name) + removeInitialFunction(val); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
387 } else if(args.length == 1 && this.symbol.name[this.symbol.name.length-1] == '!') { |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
388 return 'set ' + escapeJSName(this.symbol.name.substr(0, this.symbol.name.length-1)) + removeInitialFunction(val); |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
389 } |
926b65fe92b4
Do some cleanup on JS backend
Mike Pavone <pavone@retrodev.com>
parents:
31
diff
changeset
|
390 } |
25
4d87c38404d6
List literals, fixes to implicit self property lookup, import statement and editor improvements
Mike Pavone <pavone@retrodev.com>
parents:
23
diff
changeset
|
391 return escapeJSName(this.symbol.name) + ': ' + val; |
8
04ae32e91598
Move compiler and test page related code out of parser.js
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
392 }; |