resin 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/amber/bin/amberc +10 -350
- data/amber/js/Benchfib.deploy.js +80 -89
- data/amber/js/Benchfib.js +80 -89
- data/amber/js/Canvas.deploy.js +558 -545
- data/amber/js/Canvas.js +563 -545
- data/amber/js/Compiler-AST.deploy.js +431 -243
- data/amber/js/Compiler-AST.js +487 -244
- data/amber/js/Compiler-Core.deploy.js +201 -1045
- data/amber/js/Compiler-Core.js +208 -1207
- data/amber/js/Compiler-Exceptions.deploy.js +37 -18
- data/amber/js/Compiler-Exceptions.js +42 -18
- data/amber/js/Compiler-IR.deploy.js +1071 -774
- data/amber/js/Compiler-IR.js +1194 -848
- data/amber/js/Compiler-Inlining.deploy.js +395 -373
- data/amber/js/Compiler-Inlining.js +395 -373
- data/amber/js/Compiler-Interpreter.deploy.js +1202 -0
- data/amber/js/Compiler-Interpreter.js +1631 -0
- data/amber/js/Compiler-Semantic.deploy.js +695 -600
- data/amber/js/Compiler-Semantic.js +721 -611
- data/amber/js/Compiler-Tests.deploy.js +699 -376
- data/amber/js/Compiler-Tests.js +834 -381
- data/amber/js/Compiler.deploy.js +8563 -1805
- data/amber/js/Compiler.js +11476 -2633
- data/amber/js/Examples.deploy.js +29 -29
- data/amber/js/Examples.js +29 -29
- data/amber/js/IDE.deploy.js +3292 -2649
- data/amber/js/IDE.js +3318 -2710
- data/amber/js/Importer-Exporter.deploy.js +393 -349
- data/amber/js/Importer-Exporter.js +398 -354
- data/amber/js/Kernel-Announcements.deploy.js +53 -44
- data/amber/js/Kernel-Announcements.js +55 -44
- data/amber/js/Kernel-Classes.deploy.js +566 -368
- data/amber/js/Kernel-Classes.js +660 -402
- data/amber/js/Kernel-Collections.deploy.js +1149 -1098
- data/amber/js/Kernel-Collections.js +1183 -1116
- data/amber/js/Kernel-Exceptions.deploy.js +173 -75
- data/amber/js/Kernel-Exceptions.js +215 -77
- data/amber/js/Kernel-Methods.deploy.js +530 -313
- data/amber/js/Kernel-Methods.js +632 -338
- data/amber/js/Kernel-Objects.deploy.js +1734 -1577
- data/amber/js/Kernel-Objects.js +1867 -1654
- data/amber/js/Kernel-Tests.deploy.js +1416 -973
- data/amber/js/Kernel-Tests.js +1495 -981
- data/amber/js/Kernel-Transcript.deploy.js +23 -24
- data/amber/js/Kernel-Transcript.js +25 -26
- data/amber/js/SUnit-Tests.deploy.js +402 -0
- data/amber/js/SUnit-Tests.js +518 -0
- data/amber/js/SUnit.deploy.js +535 -237
- data/amber/js/SUnit.js +634 -246
- data/amber/js/amber.js +90 -53
- data/amber/js/boot.js +441 -255
- data/amber/js/init.js +1 -3
- data/amber/js/lib/CodeMirror/codemirror.css +3 -0
- data/amber/js/lib/CodeMirror/codemirror.js +104 -55
- data/amber/js/lib/peg-0.7.0.min.js +9 -0
- data/amber/js/parser.js +1504 -802
- data/amber/js/parser.pegjs +170 -165
- data/amber/st/Canvas.st +6 -0
- data/amber/st/Compiler-AST.st +54 -3
- data/amber/st/Compiler-Core.st +6 -551
- data/amber/st/Compiler-Exceptions.st +4 -0
- data/amber/st/Compiler-IR.st +205 -87
- data/amber/st/Compiler-Interpreter.st +597 -0
- data/amber/st/Compiler-Semantic.st +46 -21
- data/amber/st/Compiler-Tests.st +254 -7
- data/amber/st/Compiler.st +3172 -1541
- data/amber/st/IDE.st +57 -93
- data/amber/st/Importer-Exporter.st +4 -7
- data/amber/st/Kernel-Announcements.st +8 -0
- data/amber/st/Kernel-Classes.st +149 -40
- data/amber/st/Kernel-Collections.st +43 -32
- data/amber/st/Kernel-Exceptions.st +70 -1
- data/amber/st/Kernel-Methods.st +165 -27
- data/amber/st/Kernel-Objects.st +215 -140
- data/amber/st/Kernel-Tests.st +195 -10
- data/amber/st/Kernel-Transcript.st +1 -3
- data/amber/st/SUnit-Tests.st +186 -0
- data/amber/st/SUnit.st +186 -14
- data/bin/resin +6 -0
- data/lib/resin/cli.rb +19 -0
- metadata +41 -25
- data/amber/js/lib/peg-0.6.2.min.js +0 -2
- data/bin/resin-compile +0 -6
- data/bin/runresin +0 -12
data/amber/js/amber.js
CHANGED
@@ -19,7 +19,7 @@ amber = (function() {
|
|
19
19
|
var spec;
|
20
20
|
var jsToLoad = [];
|
21
21
|
var loadJS;
|
22
|
-
|
22
|
+
var nocache = '';
|
23
23
|
|
24
24
|
that.toggleIDE = function() {
|
25
25
|
if ($('#amber').length == 0) {
|
@@ -30,7 +30,7 @@ amber = (function() {
|
|
30
30
|
smalltalk.TabManager._current()._open();
|
31
31
|
}
|
32
32
|
return false;
|
33
|
-
}
|
33
|
+
};
|
34
34
|
|
35
35
|
that.load = function(obj) {
|
36
36
|
spec = obj || {};
|
@@ -56,9 +56,9 @@ amber = (function() {
|
|
56
56
|
}
|
57
57
|
|
58
58
|
loadDependencies();
|
59
|
-
addJSToLoad('lib/es5-shim-2.0.2/es5-shim.min.js');
|
60
|
-
addJSToLoad('lib/es5-shim-2.0.2/es5-sham.min.js');
|
61
|
-
addJSToLoad('boot.js');
|
59
|
+
addJSToLoad('js/lib/es5-shim-2.0.2/es5-shim.min.js');
|
60
|
+
addJSToLoad('js/lib/es5-shim-2.0.2/es5-sham.min.js');
|
61
|
+
addJSToLoad('js/boot.js');
|
62
62
|
|
63
63
|
if (deploy) {
|
64
64
|
loadPackages([
|
@@ -92,56 +92,90 @@ amber = (function() {
|
|
92
92
|
'Compiler-Semantic',
|
93
93
|
'Compiler-IR',
|
94
94
|
'Compiler-Inlining',
|
95
|
+
'Compiler-Interpreter',
|
95
96
|
'Compiler-Tests',
|
96
97
|
'parser',
|
97
98
|
'IDE',
|
98
99
|
'Examples',
|
99
100
|
'Benchfib',
|
100
|
-
'Kernel-Tests'
|
101
|
+
'Kernel-Tests',
|
102
|
+
'SUnit-Tests'
|
101
103
|
]);
|
102
104
|
}
|
103
105
|
|
104
106
|
var additionalFiles = spec.packages || spec.files;
|
107
|
+
var commitPathForInit = null;
|
105
108
|
if (additionalFiles) {
|
106
|
-
loadPackages(additionalFiles, spec.prefix, spec.packageHome);
|
109
|
+
commitPathForInit = loadPackages(additionalFiles, spec.prefix, spec.packageHome);
|
107
110
|
}
|
108
111
|
|
109
112
|
// Be sure to setup & initialize smalltalk classes
|
110
|
-
addJSToLoad('init.js');
|
111
|
-
initializeSmalltalk();
|
113
|
+
addJSToLoad('js/init.js');
|
114
|
+
initializeSmalltalk(commitPathForInit);
|
112
115
|
};
|
113
116
|
|
114
117
|
function loadPackages(names, prefix, urlHome){
|
115
|
-
var name
|
116
|
-
|
117
|
-
|
118
|
+
var name;
|
119
|
+
prefix = prefix || 'js';
|
120
|
+
urlHome = urlHome || home;
|
118
121
|
|
119
122
|
for (var i=0; i < names.length; i++) {
|
120
123
|
name = names[i].split(/\.js$/)[0];
|
121
124
|
addJSToLoad(name + '.js', prefix, urlHome);
|
122
125
|
}
|
123
|
-
|
126
|
+
|
127
|
+
return {
|
128
|
+
js: urlHome+prefix,
|
129
|
+
st: urlHome+'st'
|
130
|
+
};
|
131
|
+
}
|
124
132
|
|
125
133
|
function addJSToLoad(name, prefix, urlHome) {
|
126
|
-
|
134
|
+
urlHome = urlHome || home;
|
127
135
|
jsToLoad.push(buildJSURL(name, prefix, urlHome));
|
128
|
-
}
|
136
|
+
}
|
137
|
+
|
138
|
+
function resolve(base, path) {
|
139
|
+
if (/(^|:)\/\//.test(path)) {
|
140
|
+
// path: [http:]//foo.com/bar/; base: whatever/
|
141
|
+
// -> http://foo.com/bar/
|
142
|
+
return path;
|
143
|
+
}
|
144
|
+
if (!/^\//.test(path)) {
|
145
|
+
// path: relative/; base: whatever/
|
146
|
+
// -> whatever/relative/
|
147
|
+
return base + path;
|
148
|
+
}
|
149
|
+
var match = base.match(/^(([^:/]*:|^)\/\/[^/]*)/);
|
150
|
+
if (match) {
|
151
|
+
// path: /absolute/; base: [http:]//foo.com/whatever/
|
152
|
+
// -> [http:]//foo.com/absolute/
|
153
|
+
return match[1] + path;
|
154
|
+
}
|
155
|
+
// path: /absolute/; base: whatever/path/
|
156
|
+
// -> /absolute/
|
157
|
+
return path;
|
158
|
+
}
|
129
159
|
|
130
160
|
function buildJSURL(name, prefix, urlHome) {
|
131
|
-
|
132
|
-
|
133
|
-
|
161
|
+
prefix = prefix || '';
|
162
|
+
urlHome = urlHome || home;
|
163
|
+
|
164
|
+
var parts = name.match(/^(.*\/)([^/]*)$/);
|
165
|
+
if (parts) {
|
166
|
+
name = parts[2];
|
167
|
+
urlHome = resolve(urlHome, parts[1]);
|
168
|
+
}
|
134
169
|
|
135
170
|
if (!deploy) {
|
136
171
|
name = name + nocache;
|
137
172
|
}
|
138
173
|
|
139
174
|
return urlHome + prefix + '/' + name;
|
140
|
-
}
|
175
|
+
}
|
141
176
|
|
142
177
|
function loadCSS(name, prefix) {
|
143
|
-
|
144
|
-
var name = name;
|
178
|
+
prefix = prefix || 'css';
|
145
179
|
if (!deploy) {
|
146
180
|
name = name + nocache;
|
147
181
|
}
|
@@ -153,39 +187,43 @@ amber = (function() {
|
|
153
187
|
link.setAttribute("type", "text/css");
|
154
188
|
link.setAttribute("href", url);
|
155
189
|
document.getElementsByTagName("head")[0].appendChild(link);
|
156
|
-
}
|
190
|
+
}
|
157
191
|
|
158
192
|
function loadDependencies() {
|
159
193
|
if (typeof jQuery == 'undefined') {
|
160
|
-
writeScriptTag(buildJSURL('lib/jQuery/jquery-1.8.2.min.js'));
|
194
|
+
writeScriptTag(buildJSURL('js/lib/jQuery/jquery-1.8.2.min.js'));
|
161
195
|
}
|
162
196
|
|
163
197
|
if ((typeof jQuery == 'undefined') || (typeof jQuery.ui == 'undefined')) {
|
164
|
-
writeScriptTag(buildJSURL('lib/jQuery/jquery-ui-1.8.16.custom.min.js'));
|
198
|
+
writeScriptTag(buildJSURL('js/lib/jQuery/jquery-ui-1.8.16.custom.min.js'));
|
165
199
|
}
|
166
|
-
}
|
200
|
+
}
|
167
201
|
|
168
202
|
function loadIDEDependencies() {
|
169
|
-
addJSToLoad('lib/jQuery/jquery.textarea.js');
|
170
|
-
addJSToLoad('lib/CodeMirror/codemirror.js');
|
171
|
-
addJSToLoad('lib/CodeMirror/smalltalk.js');
|
203
|
+
addJSToLoad('js/lib/jQuery/jquery.textarea.js');
|
204
|
+
addJSToLoad('js/lib/CodeMirror/codemirror.js');
|
205
|
+
addJSToLoad('js/lib/CodeMirror/smalltalk.js');
|
172
206
|
loadCSS('lib/CodeMirror/codemirror.css', 'js');
|
173
207
|
loadCSS('lib/CodeMirror/amber.css', 'js');
|
174
|
-
}
|
208
|
+
}
|
175
209
|
|
176
210
|
// This will be called after JS files have been loaded
|
177
|
-
function initializeSmalltalk() {
|
211
|
+
function initializeSmalltalk(commitPath) {
|
178
212
|
window.smalltalkReady = function() {
|
213
|
+
if (commitPath) {
|
214
|
+
smalltalk['@@commitPath'] = commitPath;
|
215
|
+
smalltalk.Package._commitPathsFromLoader();
|
216
|
+
}
|
179
217
|
if (spec.ready) {
|
180
218
|
spec.ready();
|
181
|
-
}
|
182
|
-
|
219
|
+
}
|
220
|
+
evaluateSmalltalkScripts();
|
183
221
|
};
|
184
222
|
|
185
|
-
loadAllJS();
|
186
|
-
}
|
223
|
+
loadAllJS();
|
224
|
+
}
|
187
225
|
|
188
|
-
/*
|
226
|
+
/*
|
189
227
|
* When loaded using AJAX, scripts order not guaranteed.
|
190
228
|
* Load JS in the order they have been added using addJSToLoad().
|
191
229
|
* If loaded, will use jQuery's getScript instead of adding a script element
|
@@ -196,7 +234,7 @@ amber = (function() {
|
|
196
234
|
loadJS = loadJSViaJQuery;
|
197
235
|
}
|
198
236
|
loadNextJS();
|
199
|
-
}
|
237
|
+
}
|
200
238
|
|
201
239
|
function loadNextJS() {
|
202
240
|
loadJS(jsToLoad[0], function(){
|
@@ -205,37 +243,36 @@ amber = (function() {
|
|
205
243
|
loadNextJS();
|
206
244
|
}
|
207
245
|
});
|
208
|
-
}
|
246
|
+
}
|
209
247
|
|
210
248
|
function loadJSViaScriptTag(url, callback) {
|
211
249
|
writeScriptTag(url);
|
212
250
|
callback();
|
213
|
-
}
|
251
|
+
}
|
214
252
|
|
215
253
|
function loadJSViaJQuery(url, callback) {
|
216
254
|
$.ajax({
|
217
255
|
dataType: "script",
|
218
|
-
url:
|
256
|
+
url: url,
|
219
257
|
cache: deploy,
|
220
258
|
success: callback
|
221
259
|
});
|
222
|
-
}
|
260
|
+
}
|
223
261
|
|
224
262
|
function writeScriptTag(src) {
|
225
263
|
var scriptString = '<script src="' + src + '" type="text/javascript"></script>';
|
226
264
|
document.write(scriptString);
|
227
|
-
}
|
265
|
+
}
|
266
|
+
|
267
|
+
function evaluateSmalltalkScripts() {
|
268
|
+
jQuery(document).ready(function() {
|
269
|
+
jQuery('script[type="text/smalltalk"]').each(function(i, elt) {
|
270
|
+
smalltalk.Compiler._new()._evaluateExpression_(jQuery(elt).html());
|
271
|
+
});
|
272
|
+
})
|
273
|
+
}
|
228
274
|
|
229
|
-
|
230
|
-
jQuery(document).ready(function() {
|
231
|
-
jQuery('script[type="text/smalltalk"]').each(function(i, elt) {
|
232
|
-
smalltalk.send(
|
233
|
-
smalltalk.send(smalltalk.Compiler, '_new'),
|
234
|
-
'_evaluateExpression_',
|
235
|
-
[jQuery(elt).html()])
|
236
|
-
});
|
237
|
-
})
|
238
|
-
};
|
275
|
+
var localPackages;
|
239
276
|
|
240
277
|
function populateLocalPackages(){
|
241
278
|
var localStorageRE = /^smalltalk\.packages\.(.*)$/;
|
@@ -252,14 +289,14 @@ amber = (function() {
|
|
252
289
|
}
|
253
290
|
|
254
291
|
return localPackages;
|
255
|
-
}
|
292
|
+
}
|
256
293
|
|
257
294
|
function clearLocalPackages() {
|
258
295
|
for (var name in localPackages) {
|
259
296
|
log('Removing ' + name + ' from local storage');
|
260
297
|
localStorage.removeItem('smalltalk.packages.' + name);
|
261
298
|
}
|
262
|
-
}
|
299
|
+
}
|
263
300
|
|
264
301
|
function log(string) {
|
265
302
|
if (debug) {
|
data/amber/js/boot.js
CHANGED
@@ -13,29 +13,29 @@
|
|
13
13
|
| Amber is released under the MIT license
|
14
14
|
|
|
15
15
|
| Permission is hereby granted, free of charge, to any person obtaining
|
16
|
-
| a copy of this software and associated documentation files (the
|
17
|
-
| 'Software'), to deal in the Software without restriction, including
|
18
|
-
| without limitation the rights to use, copy, modify, merge, publish,
|
19
|
-
| distribute, sublicense, and/or sell copies of the Software, and to
|
20
|
-
| permit persons to whom the Software is furnished to do so, subject to
|
16
|
+
| a copy of this software and associated documentation files (the
|
17
|
+
| 'Software'), to deal in the Software without restriction, including
|
18
|
+
| without limitation the rights to use, copy, modify, merge, publish,
|
19
|
+
| distribute, sublicense, and/or sell copies of the Software, and to
|
20
|
+
| permit persons to whom the Software is furnished to do so, subject to
|
21
21
|
| the following conditions:
|
22
22
|
|
|
23
|
-
| The above copyright notice and this permission notice shall be
|
23
|
+
| The above copyright notice and this permission notice shall be
|
24
24
|
| included in all copies or substantial portions of the Software.
|
25
25
|
|
|
26
|
-
| THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
27
|
-
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
28
|
-
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
29
|
-
| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
30
|
-
| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
31
|
-
| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
32
|
-
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
|
+
| THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
27
|
+
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
28
|
+
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
29
|
+
| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
30
|
+
| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
31
|
+
| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
32
|
+
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
33
33
|
|
|
34
34
|
==================================================================== */
|
35
35
|
|
36
36
|
/* Make sure that console is defined */
|
37
37
|
|
38
|
-
if
|
38
|
+
if(typeof console === "undefined") {
|
39
39
|
this.console = {
|
40
40
|
log: function() {},
|
41
41
|
warn: function() {},
|
@@ -45,51 +45,61 @@ if (typeof console === "undefined") {
|
|
45
45
|
};
|
46
46
|
}
|
47
47
|
|
48
|
-
/*
|
48
|
+
/* Array extensions */
|
49
49
|
|
50
|
-
function
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
this.meta = true;
|
50
|
+
Array.prototype.addElement = function(el) {
|
51
|
+
if(typeof el === 'undefined') { return; }
|
52
|
+
if(this.indexOf(el) == -1) {
|
53
|
+
this.push(el);
|
54
|
+
}
|
56
55
|
};
|
57
|
-
function SmalltalkMethod(){};
|
58
|
-
function SmalltalkNil(){};
|
59
56
|
|
60
|
-
function
|
61
|
-
|
57
|
+
Array.prototype.removeElement = function(el) {
|
58
|
+
var i = this.indexOf(el);
|
59
|
+
if (i !== -1) { this.splice(i, 1); }
|
62
60
|
};
|
63
61
|
|
62
|
+
|
63
|
+
/* Smalltalk constructors definition */
|
64
|
+
|
65
|
+
function SmalltalkObject() {}
|
66
|
+
function SmalltalkBehavior() {}
|
67
|
+
function SmalltalkClass() {}
|
68
|
+
function SmalltalkMetaclass() {
|
69
|
+
this.meta = true;
|
70
|
+
}
|
71
|
+
function SmalltalkPackage() {}
|
72
|
+
function SmalltalkMethod() {}
|
73
|
+
function SmalltalkNil() {}
|
74
|
+
function SmalltalkSymbol(string) {
|
75
|
+
this.value = string;
|
76
|
+
}
|
64
77
|
function SmalltalkOrganizer() {
|
65
78
|
this.elements = [];
|
66
|
-
}
|
79
|
+
}
|
67
80
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
}
|
75
|
-
};
|
81
|
+
function inherits(child, parent) {
|
82
|
+
child.prototype = Object.create(parent.prototype, {
|
83
|
+
constructor: { value: child,
|
84
|
+
enumerable: false, configurable: true, writable: true }
|
85
|
+
});
|
86
|
+
}
|
76
87
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
};
|
88
|
+
inherits(SmalltalkBehavior, SmalltalkObject);
|
89
|
+
inherits(SmalltalkClass, SmalltalkBehavior);
|
90
|
+
inherits(SmalltalkMetaclass, SmalltalkBehavior);
|
91
|
+
inherits(SmalltalkNil, SmalltalkObject);
|
92
|
+
inherits(SmalltalkMethod, SmalltalkObject);
|
93
|
+
inherits(SmalltalkPackage, SmalltalkObject);
|
94
|
+
inherits(SmalltalkOrganizer, SmalltalkObject);
|
85
95
|
|
86
96
|
|
87
|
-
function Smalltalk(){
|
97
|
+
function Smalltalk() {
|
88
98
|
|
89
99
|
var st = this;
|
90
100
|
|
91
101
|
/* This is the current call context object. While it is publicly available,
|
92
|
-
Use smalltalk.getThisContext() instead which will answer a safe copy of
|
102
|
+
Use smalltalk.getThisContext() instead which will answer a safe copy of
|
93
103
|
the current context */
|
94
104
|
|
95
105
|
st.thisContext = undefined;
|
@@ -97,26 +107,69 @@ function Smalltalk(){
|
|
97
107
|
/* List of all reserved words in JavaScript. They may not be used as variables
|
98
108
|
in Smalltalk. */
|
99
109
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
110
|
+
// list of reserved JavaScript keywords as of
|
111
|
+
// http://es5.github.com/#x7.6.1.1
|
112
|
+
// and
|
113
|
+
// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.6.1
|
114
|
+
st.reservedWords = ['break', 'case', 'catch', 'continue', 'debugger',
|
115
|
+
'default', 'delete', 'do', 'else', 'finally', 'for', 'function',
|
116
|
+
'if', 'in', 'instanceof', 'new', 'return', 'switch', 'this', 'throw',
|
117
|
+
'try', 'typeof', 'var', 'void', 'while', 'with',
|
118
|
+
// ES5: future use: http://es5.github.com/#x7.6.1.2
|
119
|
+
'class', 'const', 'enum', 'export', 'extends', 'import', 'super',
|
120
|
+
// ES5: future use in strict mode
|
121
|
+
'implements', 'interface', 'let', 'package', 'private', 'protected',
|
122
|
+
'public', 'static', 'yield'];
|
123
|
+
|
124
|
+
var initialized = false;
|
125
|
+
|
126
|
+
/* Smalltalk classes */
|
127
|
+
|
128
|
+
var classes = [];
|
129
|
+
var wrappedClasses = [];
|
130
|
+
|
131
|
+
/* Method not implemented handlers */
|
132
|
+
|
133
|
+
var dnu = {
|
134
|
+
methods: [],
|
135
|
+
selectors: [],
|
136
|
+
|
137
|
+
get: function (string) {
|
138
|
+
var index = this.selectors.indexOf(string);
|
139
|
+
if(index !== -1) {
|
140
|
+
return this.methods[index];
|
141
|
+
}
|
142
|
+
this.selectors.push(string);
|
143
|
+
var selector = st.selector(string);
|
144
|
+
var method = {jsSelector: selector, fn: this.createHandler(selector)};
|
145
|
+
this.methods.push(method);
|
146
|
+
return method;
|
147
|
+
},
|
148
|
+
|
149
|
+
/* Dnu handler method */
|
150
|
+
|
151
|
+
createHandler: function (selector) {
|
152
|
+
return function () {
|
153
|
+
var args = Array.prototype.slice.call(arguments);
|
154
|
+
return messageNotUnderstood(this, selector, args);
|
155
|
+
};
|
156
|
+
}
|
157
|
+
};
|
105
158
|
|
106
159
|
/* The symbol table ensures symbol unicity */
|
107
160
|
|
108
|
-
symbolTable = {};
|
161
|
+
var symbolTable = {};
|
109
162
|
st.symbolFor = function(string) {
|
110
163
|
if(symbolTable[string] === undefined) {
|
111
164
|
symbolTable[string] = new SmalltalkSymbol(string);
|
112
|
-
}
|
165
|
+
}
|
113
166
|
|
114
167
|
return symbolTable[string];
|
115
168
|
};
|
116
169
|
|
117
170
|
/* Unique ID number generator */
|
118
171
|
|
119
|
-
oid = 0;
|
172
|
+
var oid = 0;
|
120
173
|
st.nextId = function() {
|
121
174
|
oid += 1;
|
122
175
|
return oid;
|
@@ -134,18 +187,22 @@ function Smalltalk(){
|
|
134
187
|
that.organization = new SmalltalkOrganizer();
|
135
188
|
that.properties = spec.properties || {};
|
136
189
|
return that;
|
137
|
-
}
|
190
|
+
}
|
138
191
|
|
139
|
-
/* Smalltalk class creation. A class is an instance of an automatically
|
192
|
+
/* Smalltalk class creation. A class is an instance of an automatically
|
140
193
|
created metaclass object. Newly created classes (not their metaclass)
|
141
194
|
should be added to the smalltalk object, see smalltalk.addClass().
|
142
195
|
Superclass linking is *not* handled here, see smalltalk.init() */
|
143
196
|
|
144
197
|
function klass(spec) {
|
145
|
-
|
146
|
-
var meta = metaclass();
|
147
|
-
var that =
|
148
|
-
that.
|
198
|
+
spec = spec || {};
|
199
|
+
var meta = metaclass(spec);
|
200
|
+
var that = meta.instanceClass;
|
201
|
+
that.fn = spec.fn || function() {};
|
202
|
+
setupClass(that, spec);
|
203
|
+
|
204
|
+
that.className = spec.className;
|
205
|
+
that.wrapped = spec.wrapped || false;
|
149
206
|
meta.className = spec.className + ' class';
|
150
207
|
if(spec.superclass) {
|
151
208
|
that.superclass = spec.superclass;
|
@@ -153,29 +210,36 @@ function Smalltalk(){
|
|
153
210
|
}
|
154
211
|
return that;
|
155
212
|
}
|
156
|
-
|
157
|
-
function metaclass() {
|
158
|
-
|
159
|
-
|
160
|
-
|
213
|
+
|
214
|
+
function metaclass(spec) {
|
215
|
+
spec = spec || {};
|
216
|
+
var that = new SmalltalkMetaclass();
|
217
|
+
inherits(
|
218
|
+
that.fn = function() {},
|
219
|
+
spec.superclass ? spec.superclass.klass.fn : SmalltalkClass
|
220
|
+
);
|
221
|
+
that.instanceClass = new that.fn();
|
222
|
+
setupClass(that);
|
223
|
+
return that;
|
161
224
|
}
|
162
|
-
|
163
|
-
function setupClass(
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
225
|
+
|
226
|
+
function setupClass(klass, spec) {
|
227
|
+
spec = spec || {};
|
228
|
+
klass.iVarNames = spec.iVarNames || [];
|
229
|
+
klass.pkg = spec.pkg;
|
230
|
+
|
231
|
+
Object.defineProperty(klass, "toString", {
|
232
|
+
value: function() { return 'Smalltalk ' + this.className; },
|
233
|
+
enumerable:false, configurable: true, writable: false
|
169
234
|
});
|
170
|
-
|
171
|
-
|
172
|
-
Object.
|
173
|
-
|
174
|
-
|
175
|
-
klass: { value: that, enumerable: false, configurable: true, writable: true }
|
235
|
+
|
236
|
+
klass.organization = new SmalltalkOrganizer();
|
237
|
+
Object.defineProperty(klass, "methods", {
|
238
|
+
value: {},
|
239
|
+
enumerable: false, configurable: true, writable: true
|
176
240
|
});
|
177
|
-
|
178
|
-
}
|
241
|
+
wireKlass(klass);
|
242
|
+
}
|
179
243
|
|
180
244
|
/* Smalltalk method object. To add a method to a class,
|
181
245
|
use smalltalk.addMethod() */
|
@@ -193,9 +257,9 @@ function Smalltalk(){
|
|
193
257
|
return that;
|
194
258
|
};
|
195
259
|
|
196
|
-
/* Initialize a class in its class hierarchy. Handle both
|
260
|
+
/* Initialize a class in its class hierarchy. Handle both classes and
|
197
261
|
metaclasses. */
|
198
|
-
|
262
|
+
|
199
263
|
st.init = function(klass) {
|
200
264
|
st.initClass(klass);
|
201
265
|
if(klass.klass && !klass.meta) {
|
@@ -203,71 +267,102 @@ function Smalltalk(){
|
|
203
267
|
}
|
204
268
|
};
|
205
269
|
|
206
|
-
|
207
|
-
|
208
|
-
|
270
|
+
st.initClass = function(klass) {
|
271
|
+
if(klass.wrapped) {
|
272
|
+
copySuperclass(klass);
|
273
|
+
}
|
274
|
+
else {
|
275
|
+
installSuperclass(klass);
|
276
|
+
}
|
277
|
+
|
278
|
+
if(klass === st.Object || klass.wrapped) {
|
279
|
+
installDnuHandlers(klass);
|
280
|
+
}
|
281
|
+
};
|
282
|
+
|
283
|
+
function wireKlass(klass) {
|
284
|
+
Object.defineProperty(klass.fn.prototype, "klass", {
|
285
|
+
value: klass,
|
286
|
+
enumerable: false, configurable: true, writable: true
|
287
|
+
});
|
288
|
+
}
|
289
|
+
|
290
|
+
function installSuperclass(klass) {
|
291
|
+
// only if the klass has not been initialized yet.
|
292
|
+
if(klass.fn.prototype._yourself) { return; }
|
209
293
|
|
210
294
|
if(klass.superclass && klass.superclass !== nil) {
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
295
|
+
inherits(klass.fn, klass.superclass.fn);
|
296
|
+
wireKlass(klass);
|
297
|
+
reinstallMethods(klass);
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
301
|
+
function copySuperclass(klass, superclass) {
|
302
|
+
for (superclass = superclass || klass.superclass;
|
303
|
+
superclass && superclass !== nil;
|
304
|
+
superclass = superclass.superclass) {
|
305
|
+
for (var keys = Object.keys(superclass.methods), i = 0; i < keys.length; i++) {
|
306
|
+
installMethodIfAbsent(superclass.methods[keys[i]], klass);
|
222
307
|
}
|
223
308
|
}
|
309
|
+
}
|
224
310
|
|
225
|
-
|
226
|
-
|
311
|
+
function installMethod(method, klass) {
|
312
|
+
Object.defineProperty(klass.fn.prototype, method.jsSelector, {
|
313
|
+
value: method.fn,
|
314
|
+
enumerable: false, configurable: true, writable: true
|
315
|
+
});
|
316
|
+
}
|
317
|
+
|
318
|
+
function installMethodIfAbsent(method, klass) {
|
319
|
+
if(!klass.fn.prototype[method.jsSelector]) {
|
320
|
+
installMethod(method, klass);
|
227
321
|
}
|
228
|
-
}
|
322
|
+
}
|
323
|
+
|
324
|
+
function reinstallMethods(klass) {
|
325
|
+
for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
|
326
|
+
installMethod(klass.methods[keys[i]], klass);
|
327
|
+
}
|
328
|
+
}
|
229
329
|
|
330
|
+
function installDnuHandlers(klass) {
|
331
|
+
var m = dnu.methods;
|
332
|
+
for(var i=0; i<m.length; i++) {
|
333
|
+
installMethodIfAbsent(m[i], klass);
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
function installNewDnuHandler(newHandler) {
|
338
|
+
installMethodIfAbsent(newHandler, st.Object);
|
339
|
+
for(var i = 0; i < wrappedClasses.length; i++) {
|
340
|
+
installMethodIfAbsent(newHandler, wrappedClasses[i]);
|
341
|
+
}
|
342
|
+
}
|
230
343
|
|
231
344
|
/* Answer all registered Packages as Array */
|
345
|
+
// TODO: Remove this hack
|
232
346
|
|
233
347
|
st.packages.all = function() {
|
234
348
|
var packages = [];
|
235
349
|
for(var i in st.packages) {
|
236
|
-
if
|
350
|
+
if(!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
|
237
351
|
packages.push(st.packages[i]);
|
238
352
|
}
|
239
353
|
return packages
|
240
354
|
};
|
241
355
|
|
242
356
|
/* Answer all registered Smalltalk classes */
|
357
|
+
//TODO: remove the function and make smalltalk.classes an array
|
243
358
|
|
244
359
|
st.classes = function() {
|
245
|
-
var classes = [], names = Object.keys(st), l = names.length;
|
246
|
-
for (var i=0; i<l; i++) {
|
247
|
-
var name = names[i];
|
248
|
-
if (name.search(/^[A-Z]/) !== -1) {
|
249
|
-
classes.push(st[name]);
|
250
|
-
}
|
251
|
-
}
|
252
360
|
return classes;
|
253
361
|
};
|
254
362
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
st.methods = function(klass) {
|
259
|
-
var methods = {};
|
260
|
-
inheritedMethods = klass.fn.prototype.inheritedMethods;
|
261
|
-
for(var i=0, keys=Object.keys(inheritedMethods); i<keys.length; i++) {
|
262
|
-
methods[keys[i]] = inheritedMethods[keys[i]];
|
263
|
-
}
|
264
|
-
var inheritedMethods = klass.fn.prototype.methods;
|
265
|
-
for(var i=0, keys=Object.keys(inheritedMethods); i<keys.length; i++) {
|
266
|
-
methods[keys[i]] = inheritedMethods[keys[i]];
|
267
|
-
}
|
268
|
-
return methods;
|
269
|
-
};
|
270
|
-
|
363
|
+
st.wrappedClasses = function() {
|
364
|
+
return wrappedClasses;
|
365
|
+
};
|
271
366
|
|
272
367
|
/* Answer the direct subclasses of klass. */
|
273
368
|
|
@@ -291,23 +386,32 @@ function Smalltalk(){
|
|
291
386
|
return subclasses;
|
292
387
|
};
|
293
388
|
|
294
|
-
/* Create a new class wrapping a JavaScript constructor, and add it to the
|
389
|
+
/* Create a new class wrapping a JavaScript constructor, and add it to the
|
295
390
|
global smalltalk object. Package is lazily created if it does not exist with given name. */
|
296
391
|
|
297
|
-
st.wrapClassName = function(className, pkgName, fn, superclass) {
|
392
|
+
st.wrapClassName = function(className, pkgName, fn, superclass, wrapped) {
|
393
|
+
if(wrapped !== false) {
|
394
|
+
wrapped = true;
|
395
|
+
}
|
298
396
|
var pkg = st.addPackage(pkgName);
|
299
397
|
st[className] = klass({
|
300
|
-
className: className,
|
398
|
+
className: className,
|
301
399
|
superclass: superclass,
|
302
|
-
pkg: pkg,
|
303
|
-
fn: fn
|
400
|
+
pkg: pkg,
|
401
|
+
fn: fn,
|
402
|
+
wrapped: wrapped
|
304
403
|
});
|
404
|
+
|
405
|
+
classes.addElement(st[className]);
|
406
|
+
if(wrapped) {wrappedClasses.addElement(st[className])}
|
407
|
+
pkg.organization.elements.addElement(st[className]);
|
305
408
|
};
|
306
409
|
|
307
410
|
/* Create an alias for an existing class */
|
411
|
+
|
308
412
|
st.alias = function(klass, alias) {
|
309
413
|
st[alias] = klass;
|
310
|
-
}
|
414
|
+
};
|
311
415
|
|
312
416
|
/* Add a package to the smalltalk.packages object, creating a new one if needed.
|
313
417
|
If pkgName is null or empty we return nil, which is an allowed package for a class.
|
@@ -323,7 +427,7 @@ function Smalltalk(){
|
|
323
427
|
} else {
|
324
428
|
if(properties) {
|
325
429
|
st.packages[pkgName].properties = properties;
|
326
|
-
}
|
430
|
+
}
|
327
431
|
}
|
328
432
|
return st.packages[pkgName];
|
329
433
|
};
|
@@ -333,104 +437,125 @@ function Smalltalk(){
|
|
333
437
|
|
334
438
|
st.addClass = function(className, superclass, iVarNames, pkgName) {
|
335
439
|
var pkg = st.addPackage(pkgName);
|
336
|
-
|
440
|
+
if (superclass == nil) { superclass = null; }
|
441
|
+
if(st[className] && st[className].superclass == superclass) {
|
337
442
|
st[className].superclass = superclass;
|
338
443
|
st[className].iVarNames = iVarNames;
|
339
444
|
st[className].pkg = pkg || st[className].pkg;
|
340
445
|
} else {
|
446
|
+
if(st[className]) {
|
447
|
+
st.removeClass(st[className]);
|
448
|
+
}
|
341
449
|
st[className] = klass({
|
342
|
-
className: className,
|
450
|
+
className: className,
|
343
451
|
superclass: superclass,
|
344
452
|
pkg: pkg,
|
345
453
|
iVarNames: iVarNames
|
346
454
|
});
|
347
455
|
}
|
348
456
|
|
349
|
-
|
457
|
+
classes.addElement(st[className]);
|
458
|
+
pkg.organization.elements.addElement(st[className]);
|
350
459
|
};
|
351
460
|
|
352
461
|
st.removeClass = function(klass) {
|
353
|
-
klass.pkg.organization.removeElement(klass);
|
462
|
+
klass.pkg.organization.elements.removeElement(klass);
|
463
|
+
classes.removeElement(klass);
|
354
464
|
delete st[klass.className];
|
355
465
|
};
|
356
466
|
|
357
467
|
/* Add/remove a method to/from a class */
|
358
468
|
|
359
469
|
st.addMethod = function(jsSelector, method, klass) {
|
360
|
-
Object.defineProperty(klass.fn.prototype, jsSelector, {
|
361
|
-
value: method.fn, configurable: true, writable: true
|
362
|
-
});
|
363
|
-
klass.fn.prototype.methods[method.selector] = method;
|
364
|
-
method.methodClass = klass;
|
365
470
|
method.jsSelector = jsSelector;
|
471
|
+
installMethod(method, klass);
|
472
|
+
klass.methods[method.selector] = method;
|
473
|
+
method.methodClass = klass;
|
366
474
|
|
367
|
-
klass.organization.addElement(method.category);
|
475
|
+
klass.organization.elements.addElement(method.category);
|
476
|
+
|
477
|
+
for(var i=0; i<method.messageSends.length; i++) {
|
478
|
+
var dnuHandler = dnu.get(method.messageSends[i]);
|
479
|
+
if(initialized) {
|
480
|
+
installNewDnuHandler(dnuHandler);
|
481
|
+
}
|
482
|
+
}
|
368
483
|
};
|
369
484
|
|
370
485
|
st.removeMethod = function(method) {
|
371
486
|
var protocol = method.category;
|
372
487
|
var klass = method.methodClass;
|
373
|
-
var methods = klass.fn.prototype.methods;
|
374
488
|
|
375
|
-
|
376
|
-
|
489
|
+
delete klass.fn.prototype[st.selector(method.selector)];
|
490
|
+
delete klass.methods[method.selector];
|
377
491
|
|
378
|
-
var selectors = Object.keys(methods);
|
492
|
+
var selectors = Object.keys(klass.methods);
|
379
493
|
var shouldDeleteProtocol = true;
|
380
|
-
|
381
|
-
|
494
|
+
|
495
|
+
for(var i = 0, l = selectors.length; i<l; i++) {
|
496
|
+
if(klass.methods[selectors[i]].category === protocol) {
|
382
497
|
shouldDeleteProtocol = false;
|
383
498
|
break;
|
384
499
|
};
|
385
500
|
};
|
386
501
|
if(shouldDeleteProtocol) {
|
387
|
-
klass.organization.removeElement(protocol)
|
502
|
+
klass.organization.elements.removeElement(protocol)
|
388
503
|
};
|
389
504
|
};
|
390
505
|
|
391
506
|
/* Handles unhandled errors during message sends */
|
507
|
+
// simply send the message and handle #dnu:
|
392
508
|
|
393
509
|
st.send = function(receiver, selector, args, klass) {
|
394
|
-
|
395
|
-
return withContextSend(receiver, selector, args, klass);
|
396
|
-
} else {
|
397
|
-
try {return withContextSend(receiver, selector, args, klass)}
|
398
|
-
catch(error) {
|
399
|
-
// Reset the context stack in any case
|
400
|
-
st.thisContext = undefined;
|
401
|
-
if(error.smalltalkError) {
|
402
|
-
handleError(error);
|
403
|
-
} else {
|
404
|
-
throw(error);
|
405
|
-
}
|
406
|
-
}
|
407
|
-
}
|
408
|
-
};
|
409
|
-
|
410
|
-
function withContextSend(receiver, selector, args, klass) {
|
411
|
-
var call, method;
|
510
|
+
var method;
|
412
511
|
if(receiver == null) {
|
413
512
|
receiver = nil;
|
414
513
|
}
|
415
514
|
method = klass ? klass.fn.prototype[selector] : receiver.klass && receiver[selector];
|
416
515
|
if(method) {
|
417
|
-
|
418
|
-
call = method.apply(receiver, args);
|
419
|
-
popContext(context);
|
420
|
-
return call;
|
516
|
+
return method.apply(receiver, args);
|
421
517
|
} else {
|
422
518
|
return messageNotUnderstood(receiver, selector, args);
|
423
519
|
}
|
520
|
+
}
|
521
|
+
|
522
|
+
st.withContext = function(worker, setup) {
|
523
|
+
if(st.thisContext) {
|
524
|
+
st.thisContext.pc++;
|
525
|
+
return inContext(worker, setup);
|
526
|
+
} else {
|
527
|
+
try {return inContext(worker, setup)}
|
528
|
+
catch(error) {
|
529
|
+
if(error.smalltalkError) {
|
530
|
+
handleError(error);
|
531
|
+
} else {
|
532
|
+
var errorWrapper = st.JavaScriptException._on_(error);
|
533
|
+
try {errorWrapper._signal()} catch(ex) {}
|
534
|
+
errorWrapper._context_(st.getThisContext());
|
535
|
+
handleError(errorWrapper);
|
536
|
+
}
|
537
|
+
// Reset the context stack in any case
|
538
|
+
st.thisContext = undefined;
|
539
|
+
// Throw the exception anyway, as we want to stop
|
540
|
+
// the execution to avoid infinite loops
|
541
|
+
throw error;
|
542
|
+
}
|
543
|
+
}
|
424
544
|
};
|
425
545
|
|
426
|
-
|
546
|
+
function inContext(worker, setup) {
|
547
|
+
var context = pushContext(setup);
|
548
|
+
var result = worker(context);
|
549
|
+
popContext(context);
|
550
|
+
return result;
|
551
|
+
}
|
552
|
+
|
553
|
+
/* Handles Smalltalk errors. Triggers the registered ErrorHandler
|
427
554
|
(See the Smalltalk class ErrorHandler and its subclasses */
|
428
555
|
|
429
556
|
function handleError(error) {
|
430
|
-
|
431
|
-
|
432
|
-
}
|
433
|
-
};
|
557
|
+
st.ErrorHandler._current()._handleError_(error);
|
558
|
+
}
|
434
559
|
|
435
560
|
/* Handles #dnu: *and* JavaScript method calls.
|
436
561
|
if the receiver has no klass, we consider it a JS object (outside of the
|
@@ -442,21 +567,21 @@ function Smalltalk(){
|
|
442
567
|
return callJavaScriptMethod(receiver, selector, args);
|
443
568
|
}
|
444
569
|
|
445
|
-
/* Handles not understood messages. Also see the Amber counter-part
|
570
|
+
/* Handles not understood messages. Also see the Amber counter-part
|
446
571
|
Object>>doesNotUnderstand: */
|
447
572
|
|
448
573
|
return receiver._doesNotUnderstand_(
|
449
|
-
|
574
|
+
st.Message._new()
|
450
575
|
._selector_(st.convertSelector(selector))
|
451
576
|
._arguments_(args)
|
452
|
-
|
453
|
-
}
|
577
|
+
);
|
578
|
+
}
|
454
579
|
|
455
580
|
/* Call a method of a JS object, or answer a property if it exists.
|
456
581
|
Else try wrapping a JSObjectProxy around the receiver.
|
457
582
|
|
458
583
|
If the object property is a function, then call it, except if it starts with
|
459
|
-
an uppercase character (we probably want to answer the function itself in this
|
584
|
+
an uppercase character (we probably want to answer the function itself in this
|
460
585
|
case and send it #new from Amber).
|
461
586
|
|
462
587
|
Converts keyword-based selectors by using the first
|
@@ -480,42 +605,47 @@ function Smalltalk(){
|
|
480
605
|
}
|
481
606
|
|
482
607
|
return st.send(st.JSObjectProxy._on_(receiver), selector, args);
|
483
|
-
}
|
484
|
-
|
485
|
-
|
486
|
-
/* Reuse one old context stored in oldContext */
|
487
|
-
|
488
|
-
st.oldContext = null;
|
489
|
-
|
608
|
+
}
|
490
609
|
|
491
610
|
/* Handle thisContext pseudo variable */
|
492
611
|
|
493
612
|
st.getThisContext = function() {
|
494
|
-
|
495
|
-
|
496
|
-
|
613
|
+
if(st.thisContext) {
|
614
|
+
st.thisContext.init();
|
615
|
+
return st.thisContext;
|
616
|
+
} else {
|
617
|
+
return nil;
|
618
|
+
}
|
497
619
|
};
|
498
620
|
|
499
|
-
function pushContext(
|
500
|
-
|
501
|
-
|
502
|
-
return st.thisContext = new SmalltalkMethodContext(receiver, selector, method, temps, tc);
|
503
|
-
}
|
504
|
-
st.oldContext = null;
|
505
|
-
c.homeContext = tc;
|
506
|
-
c.pc = 1;
|
507
|
-
c.receiver = receiver;
|
508
|
-
c.selector = selector;
|
509
|
-
c.method = method;
|
510
|
-
c.temps = temps || {};
|
511
|
-
return st.thisContext = c;
|
512
|
-
};
|
621
|
+
function pushContext(setup) {
|
622
|
+
return st.thisContext = new SmalltalkMethodContext(smalltalk.thisContext, setup);
|
623
|
+
}
|
513
624
|
|
514
625
|
function popContext(context) {
|
515
626
|
st.thisContext = context.homeContext;
|
516
|
-
|
517
|
-
|
518
|
-
|
627
|
+
}
|
628
|
+
|
629
|
+
/* Convert a Smalltalk selector into a JS selector */
|
630
|
+
|
631
|
+
st.selector = function(string) {
|
632
|
+
var selector = '_' + string;
|
633
|
+
selector = selector.replace(/:/g, '_');
|
634
|
+
selector = selector.replace(/[\&]/g, '_and');
|
635
|
+
selector = selector.replace(/[\|]/g, '_or');
|
636
|
+
selector = selector.replace(/[+]/g, '_plus');
|
637
|
+
selector = selector.replace(/-/g, '_minus');
|
638
|
+
selector = selector.replace(/[*]/g ,'_star');
|
639
|
+
selector = selector.replace(/[\/]/g ,'_slash');
|
640
|
+
selector = selector.replace(/[\\]/g ,'_backslash');
|
641
|
+
selector = selector.replace(/[\~]/g ,'_tild');
|
642
|
+
selector = selector.replace(/>/g ,'_gt');
|
643
|
+
selector = selector.replace(/</g ,'_lt');
|
644
|
+
selector = selector.replace(/=/g ,'_eq');
|
645
|
+
selector = selector.replace(/,/g ,'_comma');
|
646
|
+
selector = selector.replace(/[@]/g ,'_at');
|
647
|
+
return selector
|
648
|
+
};
|
519
649
|
|
520
650
|
/* Convert a string to a valid smalltalk selector.
|
521
651
|
if you modify the following functions, also change String>>asSelector
|
@@ -531,21 +661,25 @@ function Smalltalk(){
|
|
531
661
|
|
532
662
|
function convertKeywordSelector(selector) {
|
533
663
|
return selector.replace(/^_/, '').replace(/_/g, ':');
|
534
|
-
}
|
664
|
+
}
|
535
665
|
|
536
666
|
function convertBinarySelector(selector) {
|
537
667
|
return selector
|
538
668
|
.replace(/^_/, '')
|
539
|
-
.replace(/
|
540
|
-
.replace(/
|
541
|
-
.replace(/
|
542
|
-
.replace(/
|
543
|
-
.replace(/
|
544
|
-
.replace(/
|
545
|
-
.replace(/
|
546
|
-
.replace(/
|
547
|
-
.replace(/
|
548
|
-
|
669
|
+
.replace(/_and/g, '&')
|
670
|
+
.replace(/_or/g, '|')
|
671
|
+
.replace(/_plus/g, '+')
|
672
|
+
.replace(/_minus/g, '-')
|
673
|
+
.replace(/_star/g, '*')
|
674
|
+
.replace(/_slash/g, '/')
|
675
|
+
.replace(/_backslash/g, '\\')
|
676
|
+
.replace(/_tild/g, '~')
|
677
|
+
.replace(/_gt/g, '>')
|
678
|
+
.replace(/_lt/g, '<')
|
679
|
+
.replace(/_eq/g, '=')
|
680
|
+
.replace(/_comma/g, ',')
|
681
|
+
.replace(/_at/g, '@')
|
682
|
+
}
|
549
683
|
|
550
684
|
/* Converts a JavaScript object to valid Smalltalk Object */
|
551
685
|
st.readJSObject = function(js) {
|
@@ -554,12 +688,12 @@ function Smalltalk(){
|
|
554
688
|
var readArray = (js.constructor === Array);
|
555
689
|
|
556
690
|
if(readObject) {
|
557
|
-
object =
|
691
|
+
object = st.Dictionary._new();
|
558
692
|
}
|
559
693
|
for(var i in js) {
|
560
694
|
if(readObject) {
|
561
695
|
object._at_put_(i, st.readJSObject(js[i]));
|
562
|
-
}
|
696
|
+
}
|
563
697
|
if(readArray) {
|
564
698
|
object[i] = st.readJSObject(js[i]);
|
565
699
|
}
|
@@ -568,35 +702,76 @@ function Smalltalk(){
|
|
568
702
|
};
|
569
703
|
|
570
704
|
/* Boolean assertion */
|
571
|
-
st.assert = function(
|
572
|
-
if ((undefined !==
|
573
|
-
return
|
705
|
+
st.assert = function(shouldBeBoolean) {
|
706
|
+
if ((undefined !== shouldBeBoolean) && (shouldBeBoolean.klass === smalltalk.Boolean)) {
|
707
|
+
return shouldBeBoolean == true;
|
574
708
|
} else {
|
575
|
-
smalltalk.NonBooleanReceiver._new()._object_(
|
709
|
+
smalltalk.NonBooleanReceiver._new()._object_(shouldBeBoolean)._signal();
|
576
710
|
}
|
577
|
-
}
|
578
|
-
};
|
711
|
+
};
|
579
712
|
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
713
|
+
/* Smalltalk initialization. Called on page load */
|
714
|
+
|
715
|
+
st.initialize = function() {
|
716
|
+
if(initialized) { return; }
|
717
|
+
|
718
|
+
classes.forEach(function(klass) {
|
719
|
+
st.init(klass);
|
720
|
+
});
|
721
|
+
classes.forEach(function(klass) {
|
722
|
+
klass._initialize();
|
723
|
+
});
|
724
|
+
|
725
|
+
initialized = true;
|
726
|
+
};
|
727
|
+
}
|
728
|
+
|
729
|
+
inherits(Smalltalk, SmalltalkObject);
|
730
|
+
|
731
|
+
function SmalltalkMethodContext(home, setup) {
|
585
732
|
this.homeContext = home;
|
733
|
+
this.setup = setup || function() {};
|
734
|
+
this.pc = 0;
|
735
|
+
}
|
736
|
+
|
737
|
+
// Fallbacks
|
738
|
+
SmalltalkMethodContext.prototype.locals = {};
|
739
|
+
SmalltalkMethodContext.prototype.receiver = null;
|
740
|
+
SmalltalkMethodContext.prototype.selector = null;
|
741
|
+
SmalltalkMethodContext.prototype.lookupClass = null;
|
742
|
+
|
743
|
+
inherits(SmalltalkMethodContext, SmalltalkObject);
|
744
|
+
|
745
|
+
SmalltalkMethodContext.prototype.fill = function(receiver, selector, locals, lookupClass) {
|
746
|
+
this.receiver = receiver;
|
747
|
+
this.selector = selector;
|
748
|
+
this.locals = locals || {};
|
749
|
+
this.lookupClass = lookupClass;
|
586
750
|
};
|
587
751
|
|
588
|
-
SmalltalkMethodContext.prototype.
|
752
|
+
SmalltalkMethodContext.prototype.fillBlock = function(locals, ctx) {
|
753
|
+
this.locals = locals || {};
|
754
|
+
this.methodContext = ctx;
|
755
|
+
};
|
756
|
+
|
757
|
+
SmalltalkMethodContext.prototype.init = function() {
|
589
758
|
var home = this.homeContext;
|
590
|
-
if(home) {home = home.
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
759
|
+
if(home) {home = home.init()}
|
760
|
+
|
761
|
+
this.setup(this);
|
762
|
+
};
|
763
|
+
|
764
|
+
SmalltalkMethodContext.prototype.method = function() {
|
765
|
+
var method;
|
766
|
+
var lookup = this.lookupClass || this.receiver.klass;
|
767
|
+
while(!method && lookup) {
|
768
|
+
method = lookup.methods[smalltalk.convertSelector(this.selector)];
|
769
|
+
lookup = lookup.superclass
|
770
|
+
}
|
771
|
+
return method;
|
598
772
|
};
|
599
773
|
|
774
|
+
// TODO: this is just wrong :)
|
600
775
|
SmalltalkMethodContext.prototype.resume = function() {
|
601
776
|
//Brutally set the receiver as thisContext, then re-enter the function
|
602
777
|
smalltalk.thisContext = this;
|
@@ -612,39 +787,50 @@ if(this.jQuery) {
|
|
612
787
|
this.jQuery.allowJavaScriptCalls = true;
|
613
788
|
}
|
614
789
|
|
615
|
-
|
790
|
+
/*
|
791
|
+
* Answer the smalltalk representation of o.
|
792
|
+
* Used in message sends
|
793
|
+
*/
|
794
|
+
|
795
|
+
var _st = function(o) {
|
796
|
+
if(o == null) {return nil}
|
797
|
+
if(o.klass) {return o}
|
798
|
+
return smalltalk.JSObjectProxy._on_(o);
|
799
|
+
};
|
616
800
|
|
617
801
|
|
618
|
-
|
619
|
-
object metaclass to Class after the definition of Object */
|
802
|
+
/***************************************** BOOTSTRAP ******************************************/
|
620
803
|
|
621
|
-
smalltalk.wrapClassName("Object", "Kernel", SmalltalkObject);
|
622
|
-
smalltalk.wrapClassName("
|
623
|
-
smalltalk.wrapClassName("
|
624
|
-
smalltalk.wrapClassName("
|
625
|
-
smalltalk.wrapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
|
626
|
-
smalltalk.wrapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
|
627
|
-
smalltalk.wrapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);
|
628
|
-
smalltalk.wrapClassName("Organizer", "Kernel-Objects", SmalltalkOrganizer, smalltalk.Object);
|
804
|
+
smalltalk.wrapClassName("Object", "Kernel-Objects", SmalltalkObject, undefined, false);
|
805
|
+
smalltalk.wrapClassName("Behavior", "Kernel-Classes", SmalltalkBehavior, smalltalk.Object, false);
|
806
|
+
smalltalk.wrapClassName("Metaclass", "Kernel-Classes", SmalltalkMetaclass, smalltalk.Behavior, false);
|
807
|
+
smalltalk.wrapClassName("Class", "Kernel-Classes", SmalltalkClass, smalltalk.Behavior, false);
|
629
808
|
|
630
809
|
smalltalk.Object.klass.superclass = smalltalk.Class;
|
631
810
|
|
811
|
+
|
812
|
+
smalltalk.wrapClassName("Smalltalk", "Kernel-Objects", Smalltalk, smalltalk.Object, false);
|
813
|
+
smalltalk.wrapClassName("Package", "Kernel-Objects", SmalltalkPackage, smalltalk.Object, false);
|
814
|
+
smalltalk.wrapClassName("CompiledMethod", "Kernel-Methods", SmalltalkMethod, smalltalk.Object, false);
|
815
|
+
smalltalk.wrapClassName("Organizer", "Kernel-Objects", SmalltalkOrganizer, smalltalk.Object, false);
|
816
|
+
|
817
|
+
|
632
818
|
smalltalk.wrapClassName("Number", "Kernel", Number, smalltalk.Object);
|
633
819
|
smalltalk.wrapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
|
634
820
|
smalltalk.wrapClassName("Boolean", "Kernel", Boolean, smalltalk.Object);
|
635
821
|
smalltalk.wrapClassName("Date", "Kernel", Date, smalltalk.Object);
|
636
|
-
smalltalk.wrapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object);
|
822
|
+
smalltalk.wrapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object, false);
|
637
823
|
|
638
|
-
smalltalk.
|
639
|
-
smalltalk.
|
640
|
-
smalltalk.
|
824
|
+
smalltalk.addClass("Collection", smalltalk.Object, null, "Kernel");
|
825
|
+
smalltalk.addClass("SequenceableCollection", smalltalk.Collection, null, "Kernel");
|
826
|
+
smalltalk.addClass("CharacterArray", smalltalk.SequenceableCollection, null, "Kernel");
|
641
827
|
smalltalk.wrapClassName("String", "Kernel", String, smalltalk.CharacterArray);
|
642
|
-
smalltalk.wrapClassName("Symbol", "Kernel", SmalltalkSymbol, smalltalk.CharacterArray);
|
828
|
+
smalltalk.wrapClassName("Symbol", "Kernel", SmalltalkSymbol, smalltalk.CharacterArray, false);
|
643
829
|
smalltalk.wrapClassName("Array", "Kernel", Array, smalltalk.SequenceableCollection);
|
644
|
-
smalltalk.wrapClassName("RegularExpression", "Kernel", RegExp, smalltalk.
|
830
|
+
smalltalk.wrapClassName("RegularExpression", "Kernel", RegExp, smalltalk.Object);
|
645
831
|
|
646
832
|
smalltalk.wrapClassName("Error", "Kernel", Error, smalltalk.Object);
|
647
|
-
smalltalk.wrapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object);
|
833
|
+
smalltalk.wrapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object, false);
|
648
834
|
|
649
835
|
/* Alias definitions */
|
650
836
|
|