Mercurial > repos > tabletprog
comparison jsbackend.js @ 8:04ae32e91598
Move compiler and test page related code out of parser.js
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 21 Mar 2012 20:33:39 -0700 |
parents | |
children | 37d7f60a8ea1 |
comparison
equal
deleted
inserted
replaced
7:8af72f11714e | 8:04ae32e91598 |
---|---|
1 var mainModule; | |
2 | |
3 function toobj(val) | |
4 { | |
5 switch(typeof val) | |
6 { | |
7 case 'boolean': | |
8 if(val) { | |
9 return mainModule.strue; | |
10 } else { | |
11 return mainModule.sfalse; | |
12 } | |
13 case 'number': | |
14 return mainModule.snumber(val); | |
15 } | |
16 throw new Error("can't make val into object"); | |
17 } | |
18 | |
19 op.prototype.toJS = function(symbols, isReceiver) { | |
20 var ret = '(' + this.left.toJS(symbols) +' '+ (this.op == '=' ? '==' : this.op) +' '+ this.right.toJS(symbols) + ')'; | |
21 if (isReceiver) { | |
22 ret = 'toobj' + ret; | |
23 } | |
24 return ret; | |
25 }; | |
26 | |
27 symbol.prototype.toJS = function(symbols) { | |
28 var name = this.cleanName(); | |
29 if (name == 'self') { | |
30 return symbols.selfVar(); | |
31 } | |
32 name = name.replace("_", "UN_").replace(":", "CN_").replace("!", "EX_").replace('?', 'QS_').replace('@', 'AT_'); | |
33 var reserved = {'true': true, 'false': true, 'this': true, 'if': true, 'else': true, 'NaN': true}; | |
34 if (name in reserved) { | |
35 name = 's' + name; | |
36 } | |
37 return name; | |
38 } | |
39 | |
40 intlit.prototype.toJS = function(symbols) { | |
41 return this.val.toString(); | |
42 } | |
43 | |
44 floatlit.prototype.toJS = function(symbols) { | |
45 return this.val.toString(); | |
46 } | |
47 | |
48 strlit.prototype.toJS = function(symbols) { | |
49 console.log('string:', this.val); | |
50 return '"' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '"'; | |
51 } | |
52 | |
53 funcall.prototype.toJS = function(symbols) { | |
54 var name = this.name[this.name.length-1] == ':' ? this.name.substr(0, this.name.length-1) : this.name; | |
55 var args = this.args.slice(0, this.args.length); | |
56 if (this.receiver) { | |
57 args.splice(0, 0, this.receiver); | |
58 } | |
59 var funinfo = symbols.find(name); | |
60 if (!funinfo) { | |
61 var receiver = args[0]; | |
62 args.splice(0, 1); | |
63 for (var i in args) { | |
64 args[i] = args[i].toJS(symbols); | |
65 } | |
66 return receiver.toJS(symbols, true) + '.' + (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')'; | |
67 } | |
68 switch(funinfo.type) | |
69 { | |
70 case 'self': | |
71 if (args.length < funinfo.def.args.length || funinfo.def.args[0].name != 'self') { | |
72 var receiver = new symbol('self'); | |
73 } else { | |
74 var receiver = args[0]; | |
75 args.splice(0, 1); | |
76 } | |
77 for (var i in args) { | |
78 args[i] = args[i].toJS(symbols); | |
79 } | |
80 return receiver.toJS(symbols, true) + '.' + (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')'; | |
81 case 'parent': | |
82 var ret = 'this'; | |
83 for (var i = 0; i < funinfo.depth; ++i) { | |
84 ret += '.parent'; | |
85 } | |
86 for (var i in args) { | |
87 args[i] = args[i].toJS(symbols); | |
88 } | |
89 ret += (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')'; | |
90 return ret; | |
91 case 'local': | |
92 case 'upvar': | |
93 case 'foreign': | |
94 for (var i in args) { | |
95 args[i] = args[i].toJS(symbols); | |
96 } | |
97 return (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')'; | |
98 } | |
99 } | |
100 | |
101 object.prototype.toJS = function(symbols) { | |
102 var messages = this.messages; | |
103 symbols = new osymbols(symbols); | |
104 var compiled = [] | |
105 for (var i in messages) { | |
106 var js = messages[i].toJSObject(symbols); | |
107 if (js) { | |
108 compiled.push(indent(js)); | |
109 } | |
110 } | |
111 return '{\n\tparent: ' + symbols.parentObject() + ',\n\t' + compiled.join(',\n\t') + '\n}'; | |
112 } | |
113 | |
114 object.prototype.toJSModule = function() { | |
115 return '(function () {\n\tvar module = ' + indent(this.toJS(null)) + ';\n\treturn module;\n})' | |
116 } | |
117 | |
118 lambda.prototype.toJS = function(symbols) { | |
119 var args = this.args ? this.args.slice(0, this.args.length) : []; | |
120 if (args.length && args[0].cleanName() == 'self') { | |
121 args.splice(0, 1); | |
122 } | |
123 var exprs = this.expressions; | |
124 symbols = new lsymbols(symbols); | |
125 for (var i in args) { | |
126 symbols.defineVar(args[i].cleanName(), null); | |
127 args[i] = args[i].toJS(symbols); | |
128 } | |
129 var compiled = [] | |
130 for (var i in exprs) { | |
131 var js = exprs[i].toJS(symbols); | |
132 if (js) { | |
133 compiled.push(indent(js)); | |
134 } | |
135 } | |
136 exprs = compiled; | |
137 if (exprs.length) { | |
138 exprs[exprs.length-1] = 'return ' + exprs[exprs.length-1] + ';'; | |
139 } | |
140 return 'function (' + args.join(', ') + ') {\n\t' + (symbols.needsSelfVar ? 'var self = this;\n\t' : '') + exprs.join(';\n\t') + '\n}' | |
141 }; | |
142 lambda.prototype.toJSModule = lambda.prototype.toJS | |
143 | |
144 assignment.prototype.toJS = function(symbols) { | |
145 var existing = symbols.find(this.symbol.name); | |
146 var prefix = ''; | |
147 if (!existing) { | |
148 symbols.defineVar(this.symbol.name, this.expression); | |
149 prefix = 'var '; | |
150 } else { | |
151 switch (existing.type) | |
152 { | |
153 case 'self': | |
154 prefix = 'this.'; | |
155 break; | |
156 case 'parent': | |
157 prefix = 'this.'; | |
158 for (var i = 0; i < existing.depth; ++i) { | |
159 prefix += 'parent.'; | |
160 } | |
161 break; | |
162 } | |
163 } | |
164 if (this.expression instanceof funcall && this.expression.name == 'foreign:') { | |
165 return null; | |
166 } | |
167 return prefix + this.symbol.toJS(symbols) + ' = ' + this.expression.toJS(symbols); | |
168 }; | |
169 assignment.prototype.toJSObject = function(symbols) { | |
170 symbols.defineMsg(this.symbol.name, this.expression); | |
171 if (this.expression instanceof funcall && this.expression.name == 'foreign:') { | |
172 return null; | |
173 } | |
174 return this.symbol.toJS(symbols) + ': ' + this.expression.toJS(symbols); | |
175 }; |