boot.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. /* ====================================================================
  2. |
  3. | Amber Smalltalk
  4. | http://amber-lang.net
  5. |
  6. ======================================================================
  7. ======================================================================
  8. |
  9. | Copyright (c) 2010-2011
  10. | Nicolas Petton <petton.nicolas@gmail.com>
  11. |
  12. | Amber is released under the MIT license
  13. |
  14. | Permission is hereby granted, free of charge, to any person obtaining
  15. | a copy of this software and associated documentation files (the
  16. | 'Software'), to deal in the Software without restriction, including
  17. | without limitation the rights to use, copy, modify, merge, publish,
  18. | distribute, sublicense, and/or sell copies of the Software, and to
  19. | permit persons to whom the Software is furnished to do so, subject to
  20. | the following conditions:
  21. |
  22. | The above copyright notice and this permission notice shall be
  23. | included in all copies or substantial portions of the Software.
  24. |
  25. | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  26. | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  27. | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  28. | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  29. | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  30. | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  31. | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  32. |
  33. ==================================================================== */
  34. /* Make sure that console is defined */
  35. if (typeof console === "undefined") {
  36. this.console = {
  37. log: function() {},
  38. warn: function() {},
  39. info: function() {},
  40. debug: function() {},
  41. error: function() {}
  42. };
  43. }
  44. /* Smalltalk constructors definition */
  45. function SmalltalkObject(){};
  46. function SmalltalkBehavior(){};
  47. function SmalltalkClass(){};
  48. function SmalltalkMetaclass(){
  49. this.meta = true;
  50. };
  51. function SmalltalkPackage(){};
  52. function SmalltalkMethod(){};
  53. function SmalltalkNil(){};
  54. function SmalltalkSymbol(string){
  55. this.value = string;
  56. };
  57. function SmalltalkOrganizer() {
  58. this.elements = [];
  59. };
  60. SmalltalkBehavior.prototype = new SmalltalkObject();
  61. SmalltalkClass.prototype = new SmalltalkBehavior();
  62. SmalltalkMetaclass.prototype = new SmalltalkBehavior();
  63. SmalltalkNil.prototype = new SmalltalkObject();
  64. SmalltalkMethod.prototype = new SmalltalkObject();
  65. SmalltalkPackage.prototype = new SmalltalkObject();
  66. SmalltalkOrganizer.prototype = new SmalltalkObject();
  67. SmalltalkOrganizer.prototype.addElement = function(el) {
  68. if(typeof el === 'undefined' || el === nil) {
  69. return false;
  70. }
  71. if(this.elements.indexOf(el) == -1) {
  72. this.elements.push(el);
  73. }
  74. };
  75. SmalltalkOrganizer.prototype.removeElement = function(el) {
  76. for(var i=0; i<this.elements.length; i++) {
  77. if(this.elements[i] == el) {
  78. this.elements.splice(i, 1);
  79. break;
  80. }
  81. }
  82. };
  83. function Smalltalk(){
  84. var st = this;
  85. /* This is the current call context object. While it is publicly available,
  86. Use smalltalk.getThisContext() instead which will answer a safe copy of
  87. the current context */
  88. st.thisContext = undefined;
  89. /* List of all reserved words in JavaScript. They may not be used as variables
  90. in Smalltalk. */
  91. st.reservedWords = ['break', 'case', 'catch', 'char', 'class', 'continue', 'debugger',
  92. 'default', 'delete', 'do', 'else', 'finally', 'for', 'function',
  93. 'if', 'in', 'instanceof', 'native', 'new', 'private', 'protected',
  94. 'public', 'return', 'static', 'switch', 'this', 'throw',
  95. 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'];
  96. /* Method not implemented handlers selectors */
  97. var dnuHandlers = [];
  98. var addDnuHandler = function(string) {
  99. if(dnuHandlers.indexOf(string) == -1) {
  100. dnuHandlers.push(string);
  101. }
  102. };
  103. /* DNU handler method */
  104. var dnu = function(selector) {
  105. return function() {
  106. var args = Array.prototype.slice.call(arguments);
  107. return messageNotUnderstood(this, selector, args);
  108. };
  109. };
  110. /* The symbol table ensures symbol unicity */
  111. symbolTable = {};
  112. st.symbolFor = function(string) {
  113. if(symbolTable[string] === undefined) {
  114. symbolTable[string] = new SmalltalkSymbol(string);
  115. };
  116. return symbolTable[string];
  117. };
  118. /* Unique ID number generator */
  119. oid = 0;
  120. st.nextId = function() {
  121. oid += 1;
  122. return oid;
  123. };
  124. /* We hold all Packages in a separate Object */
  125. st.packages = {};
  126. /* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
  127. function pkg(spec) {
  128. var that = new SmalltalkPackage();
  129. that.pkgName = spec.pkgName;
  130. that.organization = new SmalltalkOrganizer();
  131. that.properties = spec.properties || {};
  132. return that;
  133. };
  134. /* Smalltalk class creation. A class is an instance of an automatically
  135. created metaclass object. Newly created classes (not their metaclass)
  136. should be added to the smalltalk object, see smalltalk.addClass().
  137. Superclass linking is *not* handled here, see smalltalk.init() */
  138. function klass(spec) {
  139. var spec = spec || {};
  140. var meta = metaclass();
  141. var that = meta.instanceClass;
  142. setupClass(that, spec);
  143. that.className = spec.className;
  144. that.wrapped = spec.wrapped || false;
  145. meta.className = spec.className + ' class';
  146. that.organization = new SmalltalkOrganizer();
  147. if(spec.superclass) {
  148. that.superclass = spec.superclass;
  149. meta.superclass = spec.superclass.klass;
  150. }
  151. return that;
  152. }
  153. function metaclass() {
  154. var metaclass = new SmalltalkMetaclass();
  155. setupClass(metaclass)
  156. metaclass.organization = new SmalltalkOrganizer();
  157. metaclass.fn.prototype = new SmalltalkClass();
  158. metaclass.instanceClass = new metaclass.fn;
  159. return metaclass;
  160. }
  161. function setupClass(klass, spec) {
  162. spec = spec || {};
  163. if(!klass.fn) {
  164. klass.fn = spec.fn || function(){};
  165. }
  166. klass.iVarNames = spec.iVarNames || [];
  167. klass.pkg = spec.pkg;
  168. Object.defineProperty(klass, "toString", {
  169. value: function() { return 'Smalltalk ' + this.className; },
  170. configurable: true
  171. });
  172. Object.defineProperties(klass, {
  173. methods: { value: {}, enumerable: false, configurable: true, writable: true }
  174. });
  175. Object.defineProperties(klass.fn.prototype, {
  176. klass: { value: klass, enumerable: false, configurable: true, writable: true }
  177. });
  178. };
  179. /* Smalltalk method object. To add a method to a class,
  180. use smalltalk.addMethod() */
  181. st.method = function(spec) {
  182. var that = new SmalltalkMethod();
  183. that.selector = spec.selector;
  184. that.jsSelector = spec.jsSelector;
  185. that.args = spec.args || {};
  186. that.category = spec.category;
  187. that.source = spec.source;
  188. that.messageSends = spec.messageSends || [];
  189. that.referencedClasses = spec.referencedClasses || [];
  190. that.fn = spec.fn;
  191. return that;
  192. };
  193. /* Initialize a class in its class hierarchy. Handle both classes and
  194. metaclasses. */
  195. st.init = function(klass) {
  196. st.initClass(klass);
  197. if(klass.klass && !klass.meta) {
  198. st.initClass(klass.klass);
  199. }
  200. };
  201. st.initClass = function(klass) {
  202. if(klass.wrapped) {
  203. copySuperclass(klass);
  204. } else {
  205. installSuperclass(klass);
  206. }
  207. if(klass === smalltalk.Object || klass.wrapped) {
  208. installDNUHandlers(klass);
  209. }
  210. };
  211. var installSuperclass = function(klass) {
  212. if(klass.superclass && klass.superclass !== nil) {
  213. // klass.fn.prototype = new klass.superclass.fn();
  214. // klass.fn.prototype.constructor = klass.fn;
  215. reinstallMethods(klass);
  216. }
  217. };
  218. var copySuperclass = function(klass, superclass) {
  219. superclass = superclass || klass.superclass;
  220. if(superclass && superclass !== nil) {
  221. for(var keys = Object.keys(superclass.methods), i=0; i<keys.length; i++) {
  222. var method = superclass.methods[keys[i]];
  223. if(!klass.fn.prototype[method.jsSelector]) {
  224. installMethod(method, klass);
  225. }
  226. }
  227. if(superclass.superclass) {
  228. copySuperclass(klass, superclass.superclass);
  229. }
  230. }
  231. };
  232. var installMethod = function(method, klass) {
  233. Object.defineProperty(klass.fn.prototype, method.jsSelector, {
  234. value: method.fn, configurable: true, writable: true
  235. });
  236. };
  237. var reinstallMethods = function(klass) {
  238. for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
  239. installMethod(klass.methods[keys[i]], klass)
  240. }
  241. };
  242. // st.initClass = function(klass) {
  243. // var subclasses = st.subclasses(klass);
  244. // var methods, prototype = klass.fn.prototype;
  245. // if(klass.superclass && klass.superclass !== nil) {
  246. // methods = st.allMethods(klass.superclass);
  247. // // Methods linking
  248. // for(var keys = Object.keys(methods), i=0; i<keys.length; i++) {
  249. // var key = keys[i];
  250. // if(!klass.methods[key]) {
  251. // klass.inheritedMethods[key] = methods[key];
  252. // Object.defineProperty(prototype, methods[key].jsSelector, {
  253. // value: methods[key].fn, configurable: true, writable: true
  254. // });
  255. // }
  256. // }
  257. // }
  258. // for(var i=0; i<subclasses.length; i++) {
  259. // st.initClass(subclasses[i]);
  260. // }
  261. // };
  262. /* Install all DNU methods in klass */
  263. installDNUHandlers = function(klass) {
  264. console.log('installing DNU handlers for ' + klass.className);
  265. var prototype = klass.fn.prototype;
  266. for(var i=0; i<dnuHandlers.length; i++) {
  267. var selector = dnuHandlers[i]._asSelector();
  268. if(!prototype[selector]) {
  269. Object.defineProperty(prototype, selector, {
  270. value: dnu(selector), configurable: true, writable: true
  271. });
  272. }
  273. }
  274. };
  275. /* Answer all registered Packages as Array */
  276. // TODO: Remove this hack
  277. st.packages.all = function() {
  278. var packages = [];
  279. for(var i in st.packages) {
  280. if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
  281. packages.push(st.packages[i]);
  282. }
  283. return packages
  284. };
  285. /* Answer all registered Smalltalk classes */
  286. //TODO: register classes in an array!
  287. st.classes = function() {
  288. var classes = [], names = Object.keys(st), l = names.length;
  289. for (var i=0; i<l; i++) {
  290. var name = names[i];
  291. if (name.search(/^[A-Z]/) !== -1) {
  292. classes.push(st[name]);
  293. }
  294. }
  295. return classes;
  296. };
  297. /* Answer all methods (included inherited ones) of klass. */
  298. // st.allMethods = function(klass) {
  299. // var methods = {};
  300. // var inheritedMethods = klass.inheritedMethods;
  301. // for(var i=0, keys=Object.keys(inheritedMethods); i<keys.length; i++) {
  302. // methods[keys[i]] = inheritedMethods[keys[i]];
  303. // }
  304. // inheritedMethods = klass.methods;
  305. // for(var i=0, keys=Object.keys(inheritedMethods); i<keys.length; i++) {
  306. // methods[keys[i]] = inheritedMethods[keys[i]];
  307. // }
  308. // return methods;
  309. // };
  310. /* Answer the direct subclasses of klass. */
  311. st.subclasses = function(klass) {
  312. var subclasses = [];
  313. var classes = st.classes();
  314. for(var i=0; i < classes.length; i++) {
  315. var c = classes[i];
  316. if(c.fn) {
  317. //Classes
  318. if(c.superclass === klass) {
  319. subclasses.push(c);
  320. }
  321. c = c.klass;
  322. //Metaclasses
  323. if(c && c.superclass === klass) {
  324. subclasses.push(c);
  325. }
  326. }
  327. }
  328. return subclasses;
  329. };
  330. /* Create a new class wrapping a JavaScript constructor, and add it to the
  331. global smalltalk object. Package is lazily created if it does not exist with given name. */
  332. st.wrapClassName = function(className, pkgName, fn, superclass, wrapped) {
  333. if(wrapped !== false) {
  334. wrapped = true;
  335. }
  336. var pkg = st.addPackage(pkgName);
  337. st[className] = klass({
  338. className: className,
  339. superclass: superclass,
  340. pkg: pkg,
  341. fn: fn,
  342. wrapped: wrapped
  343. });
  344. };
  345. /* Create an alias for an existing class */
  346. st.alias = function(klass, alias) {
  347. st[alias] = klass;
  348. }
  349. /* Add a package to the smalltalk.packages object, creating a new one if needed.
  350. If pkgName is null or empty we return nil, which is an allowed package for a class.
  351. If package already exists we still update the properties of it. */
  352. st.addPackage = function(pkgName, properties) {
  353. if(!pkgName) {return nil;}
  354. if(!(st.packages[pkgName])) {
  355. st.packages[pkgName] = pkg({
  356. pkgName: pkgName,
  357. properties: properties
  358. });
  359. } else {
  360. if(properties) {
  361. st.packages[pkgName].properties = properties;
  362. }
  363. }
  364. return st.packages[pkgName];
  365. };
  366. /* Add a class to the smalltalk object, creating a new one if needed.
  367. A Package is lazily created if it does not exist with given name. */
  368. st.addClass = function(className, superclass, iVarNames, pkgName) {
  369. var pkg = st.addPackage(pkgName);
  370. if(st[className]) {
  371. st[className].superclass = superclass;
  372. st[className].iVarNames = iVarNames;
  373. st[className].pkg = pkg || st[className].pkg;
  374. } else {
  375. st[className] = klass({
  376. className: className,
  377. superclass: superclass,
  378. pkg: pkg,
  379. iVarNames: iVarNames
  380. });
  381. }
  382. pkg.organization.addElement(st[className]);
  383. };
  384. st.removeClass = function(klass) {
  385. klass.pkg.organization.removeElement(klass);
  386. delete st[klass.className];
  387. };
  388. /* Add/remove a method to/from a class */
  389. st.addMethod = function(jsSelector, method, klass) {
  390. Object.defineProperty(klass.fn.prototype, jsSelector, {
  391. value: method.fn, configurable: true, writable: true
  392. });
  393. klass.methods[method.selector] = method;
  394. method.methodClass = klass;
  395. method.jsSelector = jsSelector;
  396. klass.organization.addElement(method.category);
  397. for(var i=0; i<method.messageSends.length; i++) {
  398. addDnuHandler(method.messageSends[i]);
  399. };
  400. };
  401. st.removeMethod = function(method) {
  402. var protocol = method.category;
  403. var shouldDeleteProtocol;
  404. var klass = method.methodClass;
  405. delete klass.fn.prototype[method.selector._asSelector()];
  406. delete klass.methods[method.selector];
  407. for(var i=0; i<klass.methods; i++) {
  408. if(klass.methods[i].category == protocol) {
  409. shouldDeleteProtocol = true;
  410. };
  411. };
  412. if(shouldDeleteProtocol) {
  413. klass.organization.removeElement(protocol)
  414. };
  415. };
  416. /* Handles unhandled errors during message sends */
  417. st.send = function(receiver, selector, args, klass) {
  418. if(st.thisContext) {
  419. return withContextSend(receiver, selector, args, klass);
  420. } else {
  421. try {return withContextSend(receiver, selector, args, klass)}
  422. catch(error) {
  423. // Reset the context stack in any case
  424. st.thisContext = undefined;
  425. if(error.smalltalkError) {
  426. handleError(error);
  427. } else {
  428. throw(error);
  429. }
  430. }
  431. }
  432. };
  433. function withContextSend(receiver, selector, args, klass) {
  434. var call, method;
  435. if(receiver == null) {
  436. receiver = nil;
  437. }
  438. method = klass ? klass.fn.prototype[selector] : receiver.klass && receiver[selector];
  439. if(method) {
  440. var context = pushContext(receiver, selector, method, args);
  441. call = method.apply(receiver, args);
  442. popContext(context);
  443. return call;
  444. } else {
  445. return messageNotUnderstood(receiver, selector, args);
  446. }
  447. };
  448. /* Handles Smalltalk errors. Triggers the registered ErrorHandler
  449. (See the Smalltalk class ErrorHandler and its subclasses */
  450. function handleError(error) {
  451. if(!error.cc) {
  452. smalltalk.ErrorHandler._current()._handleError_(error);
  453. }
  454. };
  455. /* Handles #dnu: *and* JavaScript method calls.
  456. if the receiver has no klass, we consider it a JS object (outside of the
  457. Amber system). Else assume that the receiver understands #doesNotUnderstand: */
  458. function messageNotUnderstood(receiver, selector, args) {
  459. /* Handles JS method calls. */
  460. if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
  461. return callJavaScriptMethod(receiver, selector, args);
  462. }
  463. /* Handles not understood messages. Also see the Amber counter-part
  464. Object>>doesNotUnderstand: */
  465. return receiver._doesNotUnderstand_(
  466. st.Message._new()
  467. ._selector_(st.convertSelector(selector))
  468. ._arguments_(args)
  469. );
  470. };
  471. /* Call a method of a JS object, or answer a property if it exists.
  472. Else try wrapping a JSObjectProxy around the receiver.
  473. If the object property is a function, then call it, except if it starts with
  474. an uppercase character (we probably want to answer the function itself in this
  475. case and send it #new from Amber).
  476. Converts keyword-based selectors by using the first
  477. keyword only, but keeping all message arguments.
  478. Example:
  479. "self do: aBlock with: anObject" -> "self.do(aBlock, anObject)" */
  480. function callJavaScriptMethod(receiver, selector, args) {
  481. var jsSelector = selector._asJavaScriptSelector();
  482. var jsProperty = receiver[jsSelector];
  483. if(typeof jsProperty === "function" && !/^[A-Z]/.test(jsSelector)) {
  484. return jsProperty.apply(receiver, args);
  485. } else if(jsProperty !== undefined) {
  486. if(args[0]) {
  487. receiver[jsSelector] = args[0];
  488. return nil;
  489. } else {
  490. return jsProperty;
  491. }
  492. }
  493. return st.send(st.JSObjectProxy._on_(receiver), selector, args);
  494. };
  495. /* Reuse one old context stored in oldContext */
  496. st.oldContext = null;
  497. /* Handle thisContext pseudo variable */
  498. st.getThisContext = function() {
  499. if(st.thisContext) {
  500. return st.thisContext.copy();
  501. }
  502. };
  503. function pushContext(receiver, selector, method, temps) {
  504. var c = st.oldContext, tc = st.thisContext;
  505. if (!c) {
  506. return st.thisContext = new SmalltalkMethodContext(receiver, selector, method, temps, tc);
  507. }
  508. st.oldContext = null;
  509. c.homeContext = tc;
  510. c.pc = 1;
  511. c.receiver = receiver;
  512. c.selector = selector;
  513. c.method = method;
  514. c.temps = temps || {};
  515. return st.thisContext = c;
  516. };
  517. function popContext(context) {
  518. st.thisContext = context.homeContext;
  519. context.homeContext = undefined;
  520. st.oldContext = context;
  521. };
  522. /* Convert a string to a valid smalltalk selector.
  523. if you modify the following functions, also change String>>asSelector
  524. accordingly */
  525. st.convertSelector = function(selector) {
  526. if(selector.match(/__/)) {
  527. return convertBinarySelector(selector);
  528. } else {
  529. return convertKeywordSelector(selector);
  530. }
  531. };
  532. function convertKeywordSelector(selector) {
  533. return selector.replace(/^_/, '').replace(/_/g, ':');
  534. };
  535. function convertBinarySelector(selector) {
  536. return selector
  537. .replace(/^_/, '')
  538. .replace(/_plus/, '+')
  539. .replace(/_minus/, '-')
  540. .replace(/_star/, '*')
  541. .replace(/_slash/, '/')
  542. .replace(/_gt/, '>')
  543. .replace(/_lt/, '<')
  544. .replace(/_eq/, '=')
  545. .replace(/_comma/, ',')
  546. .replace(/_at/, '@')
  547. };
  548. /* Converts a JavaScript object to valid Smalltalk Object */
  549. st.readJSObject = function(js) {
  550. var object = js;
  551. var readObject = (js.constructor === Object);
  552. var readArray = (js.constructor === Array);
  553. if(readObject) {
  554. object = smalltalk.Dictionary._new();
  555. }
  556. for(var i in js) {
  557. if(readObject) {
  558. object._at_put_(i, st.readJSObject(js[i]));
  559. }
  560. if(readArray) {
  561. object[i] = st.readJSObject(js[i]);
  562. }
  563. }
  564. return object;
  565. };
  566. /* Boolean assertion */
  567. st.assert = function(boolean) {
  568. if(boolean.klass === smalltalk.Boolean) {
  569. return boolean;
  570. } else {
  571. smalltalk.NonBooleanReceiver._new()._object_(boolean)._signal();
  572. }
  573. }
  574. };
  575. function SmalltalkMethodContext(receiver, selector, method, temps, home) {
  576. this.receiver = receiver;
  577. this.selector = selector;
  578. this.method = method;
  579. this.temps = temps || {};
  580. this.homeContext = home;
  581. this.resume = function() {
  582. //Brutally set the receiver as thisContext, then re-enter the function
  583. smalltalk.thisContext = this;
  584. return this.method.apply(receiver, temps);
  585. };
  586. };
  587. SmalltalkMethodContext.prototype.copy = function() {
  588. var home = this.homeContext;
  589. if(home) {home = home.copy()}
  590. return new SmalltalkMethodContext(
  591. this.receiver,
  592. this.selector,
  593. this.method,
  594. this.temps,
  595. home
  596. );
  597. };
  598. /* Global Smalltalk objects. */
  599. var nil = new SmalltalkNil();
  600. var smalltalk = new Smalltalk();
  601. if(this.jQuery) {
  602. this.jQuery.allowJavaScriptCalls = true;
  603. }
  604. /***************************************** BOOTSTRAP ******************************************/
  605. /* Boostrap Object, Behavior, Class and Metaclass */
  606. // (function() {
  607. // var objectClass, behaviorClass, classClass, metaclassClass;
  608. // var setupMetaclass = function(metaclass) {
  609. // metaclass = new SmalltalkMetaclass();
  610. // metaclass.fn = function() {};
  611. // metaclass.fn.prototype = new SmalltalkClass();
  612. // };
  613. // objectClass = new SmalltalkMetaclass();
  614. // objectClass.fn = function() {};
  615. // objectClass.fn.prototype = new SmalltalkClass();
  616. // behaviorClass = new SmalltalkMetaclass();
  617. // behaviorClass.fn = function() {};
  618. // behaviorClass.fn.prototype = new SmalltalkClass();
  619. // classClass = new SmalltalkMetaclass();
  620. // classClass.fn = function() {};
  621. // classClass.fn.prototype = new SmalltalkClass();
  622. // metaclassClass = new SmalltalkMetaclass();
  623. // metaclassClass.fn = function() {};
  624. // metaclassClass.fn.prototype = new SmalltalkClass();
  625. // smalltalk.Behavior = new behaviorClass.fn();
  626. // smalltalk.Behavior.fn = SmalltalkBehavior;
  627. // smalltalk.Behavior.klass = behaviorClass;
  628. // behaviorClass.superclass = smalltalk.Class;
  629. // smalltalk.Class = new classClass.fn();
  630. // smalltalk.Class.fn = SmalltalkClass;
  631. // smalltalk.Class.klass = classClass;
  632. // classClass.superclass = smalltalk.Class;
  633. // smalltalk.Metaclass = new metaclassClass.fn();
  634. // smalltalk.Metaclass.fn = SmalltalkMetaclass;
  635. // smalltalk.Metaclass.klass = metaclassClass;
  636. // metaclassClass.superclass = smalltalk.Class;
  637. // smalltalk.Object = new objectClass.fn();
  638. // smalltalk.Object.fn = SmalltalkObject;
  639. // smalltalk.Object.klass = objectClass;
  640. // objectClass.superclass = smalltalk.Class;
  641. // smalltalk.setupClass(objectClass);
  642. // smalltalk.setupClass(behaviorClass);
  643. // smalltalk.setupClass(classClass);
  644. // smalltalk.setupClass(metaclassClass);
  645. // smalltalk.setupClass(smalltalk.Object);
  646. // smalltalk.setupClass(smalltalk.Behavior);
  647. // smalltalk.setupClass(smalltalk.Class);
  648. // smalltalk.setupClass(smalltalk.Metaclass);
  649. // })();
  650. smalltalk.wrapClassName("Object", "Kernel-Objects", SmalltalkObject, false);
  651. smalltalk.wrapClassName("Behavior", "Kernel-Classes", SmalltalkBehavior, smalltalk.Object, false);
  652. smalltalk.wrapClassName("Metaclass", "Kernel-Classes", SmalltalkMetaclass, smalltalk.Behavior, false);
  653. smalltalk.wrapClassName("Class", "Kernel-Classes", SmalltalkClass, smalltalk.Behavior, false);
  654. smalltalk.wrapClassName("Smalltalk", "Kernel-Objects", Smalltalk, smalltalk.Object, false);
  655. smalltalk.wrapClassName("Package", "Kernel-Objects", SmalltalkPackage, smalltalk.Object, false);
  656. smalltalk.wrapClassName("CompiledMethod", "Kernel-Objects", SmalltalkMethod, smalltalk.Object, false);
  657. smalltalk.wrapClassName("Organizer", "Kernel-Objects", SmalltalkOrganizer, smalltalk.Object, false);
  658. smalltalk.wrapClassName("Number", "Kernel", Number, smalltalk.Object);
  659. smalltalk.wrapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
  660. smalltalk.wrapClassName("Boolean", "Kernel", Boolean, smalltalk.Object);
  661. smalltalk.wrapClassName("Date", "Kernel", Date, smalltalk.Object);
  662. smalltalk.wrapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object);
  663. smalltalk.wrapClassName("Collection", "Kernel", null, smalltalk.Object, false);
  664. smalltalk.wrapClassName("SequenceableCollection", "Kernel", null, smalltalk.Collection, false);
  665. smalltalk.wrapClassName("CharacterArray", "Kernel", null, smalltalk.SequenceableCollection, false);
  666. smalltalk.wrapClassName("String", "Kernel", String, smalltalk.CharacterArray);
  667. smalltalk.wrapClassName("Symbol", "Kernel", SmalltalkSymbol, smalltalk.CharacterArray, false);
  668. smalltalk.wrapClassName("Array", "Kernel", Array, smalltalk.SequenceableCollection);
  669. smalltalk.wrapClassName("RegularExpression", "Kernel", RegExp, smalltalk.String);
  670. smalltalk.wrapClassName("Error", "Kernel", Error, smalltalk.Object);
  671. smalltalk.wrapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object, false);
  672. /* Alias definitions */
  673. smalltalk.alias(smalltalk.Array, "OrderedCollection");
  674. smalltalk.alias(smalltalk.Date, "Time");