1
0
Pārlūkot izejas kodu

Merge remote-tracking branch 'remotes/upstream/master' into helios

Herbert Vojčík 12 gadi atpakaļ
vecāks
revīzija
168ef608c0
94 mainītis faili ar 4147 papildinājumiem un 6795 dzēšanām
  1. 0 2
      .gitignore
  2. 28 1
      CHANGELOG
  3. 0 53
      Makefile
  4. 2 2
      README.md
  5. 1 1
      bin/amberc
  6. 4 4
      bin/amberc.js
  7. 0 0
      bin/nodecompile.js
  8. 1 1
      bin/server
  9. 0 468
      css/amber-normalize.css
  10. 0 501
      css/amber-normalize.less
  11. 0 84
      css/documentation.css
  12. 0 75
      css/profstef.css
  13. 0 313
      css/style.css
  14. 0 37
      documentation.html
  15. BIN
      favicon.ico
  16. 1 7
      grunt.js
  17. BIN
      images/presentation.png
  18. BIN
      images/profstef.png
  19. BIN
      images/twitterwall.png
  20. 3 98
      index.html
  21. 0 737
      js/Documentation.deploy.js
  22. 0 962
      js/Documentation.js
  23. 23 1
      js/IDE.deploy.js
  24. 28 1
      js/IDE.js
  25. 139 72
      js/Importer-Exporter.deploy.js
  26. 141 74
      js/Importer-Exporter.js
  27. 45 13
      js/Kernel-Classes.deploy.js
  28. 68 26
      js/Kernel-Classes.js
  29. 323 163
      js/Kernel-Collections.deploy.js
  30. 359 158
      js/Kernel-Collections.js
  31. 16 5
      js/Kernel-Objects.deploy.js
  32. 22 6
      js/Kernel-Objects.js
  33. 459 388
      js/Kernel-Tests.deploy.js
  34. 461 390
      js/Kernel-Tests.js
  35. 16 28
      js/amber.js
  36. 2 1
      js/boot.js
  37. 2 2
      js/init.js
  38. 0 0
      js/lib/es5-shim-2.0.2/.gitignore
  39. 0 0
      js/lib/es5-shim-2.0.2/CHANGES
  40. 0 0
      js/lib/es5-shim-2.0.2/CONTRIBUTORS.md
  41. 0 0
      js/lib/es5-shim-2.0.2/LICENSE
  42. 0 0
      js/lib/es5-shim-2.0.2/README.md
  43. 0 0
      js/lib/es5-shim-2.0.2/es5-sham.js
  44. 0 0
      js/lib/es5-shim-2.0.2/es5-sham.min.js
  45. 0 0
      js/lib/es5-shim-2.0.2/es5-shim.js
  46. 0 0
      js/lib/es5-shim-2.0.2/es5-shim.min.js
  47. 0 0
      js/lib/es5-shim-2.0.2/package.json
  48. 0 0
      js/lib/es5-shim-2.0.2/tests/helpers/h-kill.js
  49. 0 0
      js/lib/es5-shim-2.0.2/tests/helpers/h-matchers.js
  50. 0 0
      js/lib/es5-shim-2.0.2/tests/helpers/h.js
  51. 0 0
      js/lib/es5-shim-2.0.2/tests/index.html
  52. 0 0
      js/lib/es5-shim-2.0.2/tests/lib/jasmine-html.js
  53. 0 0
      js/lib/es5-shim-2.0.2/tests/lib/jasmine.css
  54. 0 0
      js/lib/es5-shim-2.0.2/tests/lib/jasmine.js
  55. 0 0
      js/lib/es5-shim-2.0.2/tests/lib/jasmine_favicon.png
  56. 0 0
      js/lib/es5-shim-2.0.2/tests/lib/json2.js
  57. 0 0
      js/lib/es5-shim-2.0.2/tests/spec/s-array.js
  58. 0 0
      js/lib/es5-shim-2.0.2/tests/spec/s-date.js
  59. 0 0
      js/lib/es5-shim-2.0.2/tests/spec/s-function.js
  60. 0 0
      js/lib/es5-shim-2.0.2/tests/spec/s-object.js
  61. 0 0
      js/lib/es5-shim-2.0.2/tests/spec/s-string.js
  62. 0 419
      js/lib/showdown.js
  63. 0 40
      learn.html
  64. 34 34
      repl/REPL.js
  65. 436 258
      repl/amber.js
  66. 8 4
      server/FileServer.st
  67. 437 259
      server/server.js
  68. 1 1
      st/Benchfib.st
  69. 1 1
      st/Canvas.st
  70. 1 1
      st/Compiler-AST.st
  71. 1 1
      st/Compiler-Core.st
  72. 1 1
      st/Compiler-Exceptions.st
  73. 1 1
      st/Compiler-IR.st
  74. 1 1
      st/Compiler-Inlining.st
  75. 1 1
      st/Compiler-Interpreter.st
  76. 1 1
      st/Compiler-Semantic.st
  77. 1 1
      st/Compiler-Tests.st
  78. 652 118
      st/Compiler.st
  79. 0 758
      st/Documentation.st
  80. 1 1
      st/Examples.st
  81. 12 1
      st/IDE.st
  82. 5 5
      st/Importer-Exporter.st
  83. 1 1
      st/Kernel-Announcements.st
  84. 123 95
      st/Kernel-Classes.st
  85. 228 98
      st/Kernel-Collections.st
  86. 1 1
      st/Kernel-Exceptions.st
  87. 1 1
      st/Kernel-Methods.st
  88. 13 7
      st/Kernel-Objects.st
  89. 36 6
      st/Kernel-Tests.st
  90. 1 1
      st/Kernel-Transcript.st
  91. 1 1
      st/SUnit-Tests.st
  92. 1 1
      st/SUnit.st
  93. 1 1
      st/Spaces.st
  94. 1 1
      test/Test.st

+ 0 - 2
.gitignore

@@ -1,6 +1,4 @@
 # Ignoring compiled files in examples etc
-examples/nodejs/**/*.js
-examples/webos/**/*.js
 server/FileServer*.js
 
 # Ignoring Mac Finder files

+ 28 - 1
CHANGELOG

@@ -1,3 +1,30 @@
+Release 0.10 (on it's way)
+==========================
+
+Here's a summary of change since the 0.9.1 release:
+
+- Travis CI jobs
+- Almost 300 issues closed
+- 150 new unit tests written
+- All classes in the Kernel are documented
+
+- New and much improved compiler toolchain, providing:
+  - Semantic analysis
+  - AST Node annotation
+  - Intermediate representation (easier to optimize)
+  - Better inlining
+  - an AST interpreter
+  - support for blocks contexts
+
+- SUnit improvements and cleanup, with support for async assertions
+- New build system based on gruntjs, replacing the old makefiles
+- Improved ClassBuilder with better class migration support
+- New bin/amberc compiler written in Amber
+- Improved loader for third party packages
+- New IDE on it's way for Amber 1.0
+
+
+
 16th January 2012 - Release 0.9.1
 =================================
 
@@ -17,7 +44,7 @@ Here's a summary of changes since the 0.9 release:
 - Dictionary can now have any kind of object as keys. String-key dictionary has been renamed HashedCollection
 - New TwitterWall example
 - Improved HTML Canvas, now compatible with IE7
-- Improved JSObjectProxy for seemless JavaScript objects access from Amber
+- Improved JSObjectProxy for seamless JavaScript objects access from Amber
 - No more jQuery binding. Amber is fully capable of sending messages to JavaScript objects
 
 13th September 2011 - Release 0.9

+ 0 - 53
Makefile

@@ -1,53 +0,0 @@
-# Makefile for sub directories
-AMBER = st
-SERVER = server
-REPL = repl
-EXAMPLES = examples
-
-# REST is all except AMBER
-REST = $(SERVER) $(EXAMPLES) $(REPL)
-
-# And these are all
-DIRS = $(AMBER) $(REST)
-
-# The sets of directories to do various things in
-BUILDDIRS = $(DIRS:%=build-%)
-EXAMPLESDIRS = $(EXAMPLES:%=build-%)
-INSTALLDIRS = $(AMBER:%=install-%)
-CLEANDIRS = $(REST:%=clean-%)
-CLEANALLDIRS = $(DIRS:%=clean-%)
-
-all: $(BUILDDIRS)
-$(DIRS): $(BUILDDIRS)
-$(BUILDDIRS):
-	$(MAKE) -C $(@:build-%=%)
-
-amber: build-st
-
-# Examples and server need Amber first
-build-server: build-st
-build-examples: build-st
-
-examples: $(EXAMPLESDIRS)
-$(EXAMPLESDIRS):
-	$(MAKE) -C $(@:build-%=%)
-
-install: $(INSTALLDIRS)
-$(INSTALLDIRS):
-	$(MAKE) -C $(@:install-%=%) install
-
-clean: $(CLEANDIRS)
-$(CLEANDIRS): 
-	$(MAKE) -C $(@:clean-%=%) clean
-
-cleanall: $(CLEANALLDIRS) 
-$(CLEANALLDIRS): 
-	$(MAKE) -C $(@:clean-%=%) clean
-
-
-.PHONY: subdirs $(DIRS)
-.PHONY: subdirs $(BUILDDIRS)
-.PHONY: subdirs $(INSTALLDIRS)
-.PHONY: subdirs $(CLEANDIRS)
-.PHONY: subdirs $(CLEANALLDIRS)
-.PHONY: all install clean

+ 2 - 2
README.md

@@ -1,4 +1,4 @@
-Amber [![Travis CI Status](https://secure.travis-ci.org/NicolasPetton/amber.png)](https://travis-ci.org/#!/NicolasPetton/amber)
+Amber [![Travis CI Status](https://secure.travis-ci.org/amber-smalltalk/amber.png)](https://travis-ci.org/#!/amber-smalltalk/amber)
 =====
 
 By Nicolas Petton <petton.nicolas@gmail.com> and [Amber contributors](https://github.com/NicolasPetton/amber/contributors)
@@ -27,4 +27,4 @@ Amber is released under the MIT license. All contributions made for inclusion ar
 More infos
 ----------
 
-More on the [project page](http://amber-lang.net)
+More on the [project page](http://amber-lang.net)

+ 1 - 1
bin/amberc

@@ -20,7 +20,7 @@ var amber_dir = path.normalize(path.join(path.dirname(process.argv[1]), '..'));
 // Get default location of compiler.jar
 var closure_jar = path.resolve(path.join(process.env['HOME'], 'compiler.jar'));
 
-var compiler = new amberc.Compiler(amber_dir);
+var compiler = new amberc.Compiler(amber_dir, closure_jar);
 
 var configuration = handle_options(parameters, amber_dir);
 

+ 4 - 4
bin/amberc.js

@@ -82,7 +82,7 @@ var path = require('path'),
  */
 function AmberC(amber_dir, closure_jar) {
 	this.amber_dir = amber_dir;
-	this.closure_jar = closure_jar;
+	this.closure_jar = closure_jar || '';
 	this.kernel_libraries = ['boot', 'Kernel-Objects', 'Kernel-Classes', 'Kernel-Methods',
 	                         'Kernel-Collections', 'Kernel-Exceptions', 'Kernel-Transcript',
 	                         'Kernel-Announcements'];
@@ -580,13 +580,13 @@ AmberC.prototype.optimize = function() {
 
 	if (defaults.closure_parts) {
 		console.log('Compiling all js files using Google closure compiler.');
-		var allJsFiles = defaults.compiled.concat(defaults.libraries);
-		allJsFiles.forEach(function(file) {
+		defaults.compiled.forEach(function(file) {
+			console.log('Compiling ' + file + ' file using Google closure compiler.');
 			var minifiedName = path.basename(file, '.js') + '.min.js';
 			self.closure_compile(file, minifiedName, optimization_done.add());
 		});
 	}
-	if (defaults.closure_full) {
+	if (defaults.closure_full && (undefined !== defaults.program)) {
 		console.log('Compiling ' + defaults.program + '.js file using Google closure compiler.');
 		self.closure_compile(defaults.program + '.js', defaults.program + '.min.js', optimization_done.add());
 	}

+ 0 - 0
bin/nodecompile.js


+ 1 - 1
bin/server

@@ -1,3 +1,3 @@
 #!/bin/bash
 cd `dirname $0`/..
-node ./server/server.js
+node ./server/server.js $@

+ 0 - 468
css/amber-normalize.css

@@ -1,468 +0,0 @@
-/*! normalize.css 2012-03-11T12:53 UTC - http://github.com/necolas/normalize.css */
-/* normalize.css co-opted for the amber browser */
-#amber {
-  /* =============================================================================
-   HTML5 display definitions
-   ========================================================================== */
-
-  /*
- * Corrects block display not defined in IE6/7/8/9 & FF3
- */
-
-  /*
-     * Corrects inline-block display not defined in IE6/7/8/9 & FF3
-     */
-
-  /*
-     * Prevents modern browsers from displaying 'audio' without controls
-     * Remove excess height in iOS5 devices
-     */
-
-  /*
-     * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
-     * Known issue: no IE6 support
-     */
-
-  /* =============================================================================
-       Base
-       ========================================================================== */
-
-  /*
-     * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
-     *    http://clagnut.com/blog/348/#c790
-     * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
-     *    www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
-     */
-
-  /*
-     * Addresses font-family inconsistency between 'textarea' and other form elements.
-     */
-
-  /*
-     * Addresses margins handled incorrectly in IE6/7
-     */
-
-  /* =============================================================================
-       Links
-       ========================================================================== */
-
-  /*
-     * Addresses outline displayed oddly in Chrome
-     */
-
-  /*
-     * Improves readability when focused and also mouse hovered in all browsers
-     * people.opera.com/patrickl/experiments/keyboard/test
-     */
-
-  /* =============================================================================
-       Typography
-       ========================================================================== */
-
-  /*
-     * Addresses font sizes and margins set differently in IE6/7
-     * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
-     */
-
-  /*
-     * Addresses styling not present in IE7/8/9, S5, Chrome
-     */
-
-  /*
-     * Addresses style set to 'bolder' in FF3+, S4/5, Chrome
-     */
-
-  /*
-     * Addresses styling not present in S5, Chrome
-     */
-
-  /*
-     * Addresses styling not present in IE6/7/8/9
-     */
-
-  /*
-     * Addresses margins set differently in IE6/7
-     */
-
-  /*
-     * Corrects font family set oddly in IE6, S4/5, Chrome
-     * en.wikipedia.org/wiki/User:Davidgothberg/Test59
-     */
-
-  /*
-     * Improves readability of pre-formatted text in all browsers
-     */
-
-  /*
-     * 1. Addresses CSS quotes not supported in IE6/7
-     * 2. Addresses quote property not supported in S4
-     */
-
-  /* 1 */
-
-  /* 2 */
-
-  /*
-     * Prevents sub and sup affecting line-height in all browsers
-     * gist.github.com/413930
-     */
-
-  /* =============================================================================
-       Lists
-       ========================================================================== */
-
-  /*
-     * Addresses margins set differently in IE6/7
-     */
-
-  /*
-     * Addresses paddings set differently in IE6/7
-     */
-
-  /*
-     * Corrects list images handled incorrectly in IE7
-     */
-
-  /* =============================================================================
-       Embedded content
-       ========================================================================== */
-
-  /*
-     * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
-     * 2. Improves image quality when scaled in IE7
-     *    code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
-     */
-
-  /*
-     * Corrects overflow displayed oddly in IE9
-     */
-
-  /* =============================================================================
-       Figures
-       ========================================================================== */
-
-  /*
-     * Addresses margin not present in IE6/7/8/9, S5, O11
-     */
-
-  /* =============================================================================
-       Forms
-       ========================================================================== */
-
-  /*
-     * Corrects margin displayed oddly in IE6/7
-     */
-
-  /*
-     * Define consistent border, margin, and padding
-     */
-
-  /*
-     * 1. Corrects color not being inherited in IE6/7/8/9
-     * 2. Corrects text not wrapping in FF3
-     * 3. Corrects alignment displayed oddly in IE6/7
-     */
-
-  /*
-     * 1. Corrects font size not being inherited in all browsers
-     * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
-     * 3. Improves appearance and consistency in all browsers
-     */
-
-  /*
-     * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
-     */
-
-  /*
-     * 1. Improves usability and consistency of cursor style between image-type 'input' and others
-     * 2. Corrects inability to style clickable 'input' types in iOS
-     * 3. Removes inner spacing in IE7 without affecting normal text inputs
-     *    Known issue: inner spacing remains in IE6
-     */
-
-  /*
-     * Re-set default cursor for disabled elements
-     */
-
-  /*
-     * 1. Addresses box sizing set to content-box in IE8/9
-     * 2. Removes excess padding in IE8/9
-     * 3. Removes excess padding in IE7
-     Known issue: excess padding remains in IE6
-     */
-
-  /*
-     * 1. Addresses appearance set to searchfield in S5, Chrome
-     * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
-     */
-
-  /*
-     * Removes inner padding and search cancel button in S5, Chrome on OS X
-     */
-
-  /*
-     * Removes inner padding and border in FF3+
-     * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
-     */
-
-  /*
-     * 1. Removes default vertical scrollbar in IE6/7/8/9
-     * 2. Improves readability and alignment in all browsers
-     */
-
-  /* =============================================================================
-       Tables
-       ========================================================================== */
-
-  /*
-     * Remove most spacing between table cells
-     */
-
-}
-#amber article,
-#amber aside,
-#amber details,
-#amber figcaption,
-#amber figure,
-#amber footer,
-#amber header,
-#amber hgroup,
-#amber nav,
-#amber section,
-#amber summary {
-  display: block;
-}
-#amber audio, #amber canvas, #amber video {
-  display: inline-block;
-  *display: inline;
-  *zoom: 1;
-}
-#amber audio:not([controls]) {
-  display: none;
-  height: 0;
-}
-#amber [hidden] {
-  display: none;
-}
-#amber button,
-#amber input,
-#amber select,
-#amber textarea {
-  font-family: sans-serif;
-}
-#amber a:focus {
-  outline: thin dotted;
-}
-#amber a:hover, #amber a:active {
-  outline: 0;
-}
-#amber h1 {
-  font-size: 2em;
-  margin: 0.67em 0;
-}
-#amber h2 {
-  font-size: 1.5em;
-  margin: 0.83em 0;
-}
-#amber h3 {
-  font-size: 1.17em;
-  margin: 1em 0;
-}
-#amber h4 {
-  font-size: 1em;
-  margin: 1.33em 0;
-}
-#amber h5 {
-  font-size: 0.83em;
-  margin: 1.67em 0;
-}
-#amber h6 {
-  font-size: 0.75em;
-  margin: 2.33em 0;
-}
-#amber abbr[title] {
-  border-bottom: 1px dotted;
-}
-#amber b, #amber strong {
-  font-weight: bold;
-}
-#amber blockquote {
-  margin: 1em 40px;
-}
-#amber dfn {
-  font-style: italic;
-}
-#amber mark {
-  background: #ff0;
-  color: #000;
-}
-#amber p, #amber pre {
-  margin: 1em 0;
-}
-#amber pre,
-#amber code,
-#amber kbd,
-#amber samp {
-  font-family: monospace, serif;
-  _font-family: 'courier new', monospace;
-  font-size: 1em;
-}
-#amber pre {
-  white-space: pre;
-  white-space: pre-wrap;
-  word-wrap: break-word;
-}
-#amber q {
-  quotes: none;
-}
-#amber q:before, #amber q:after {
-  content: '';
-  content: none;
-}
-#amber small {
-  font-size: 75%;
-}
-#amber sub, #amber sup {
-  font-size: 75%;
-  line-height: 0;
-  position: relative;
-  vertical-align: baseline;
-}
-#amber sup {
-  top: -0.5em;
-}
-#amber sub {
-  bottom: -0.25em;
-}
-#amber dl,
-#amber menu,
-#amber ol,
-#amber ul {
-  margin: 1em 0;
-}
-#amber dd {
-  margin: 0 0 0 40px;
-}
-#amber menu, #amber ol, #amber ul {
-  padding: 0 0 0 40px;
-}
-#amber nav ul, #amber nav ol {
-  list-style: none;
-  list-style-image: none;
-}
-#amber img {
-  border: 0;
-  /* 1 */
-
-  -ms-interpolation-mode: bicubic;
-  /* 2 */
-
-}
-#amber svg:not(:root) {
-  overflow: hidden;
-}
-#amber figure {
-  margin: 0;
-}
-#amber form {
-  margin: 0;
-}
-#amber fieldset {
-  border: 1px solid #c0c0c0;
-  margin: 0 2px;
-  padding: 0.35em 0.625em 0.75em;
-}
-#amber legend {
-  border: 0;
-  /* 1 */
-
-  padding: 0;
-  white-space: normal;
-  /* 2 */
-
-  *margin-left: -7px;
-  /* 3 */
-
-}
-#amber button,
-#amber input,
-#amber select,
-#amber textarea {
-  font-size: 100%;
-  /* 1 */
-
-  margin: 0;
-  /* 2 */
-
-  vertical-align: baseline;
-  /* 3 */
-
-  *vertical-align: middle;
-  /* 3 */
-
-}
-#amber button, #amber input {
-  line-height: normal;
-  /* 1 */
-
-}
-#amber button,
-#amber input[type="button"],
-#amber input[type="reset"],
-#amber input[type="submit"] {
-  cursor: pointer;
-  /* 1 */
-
-  -webkit-appearance: button;
-  /* 2 */
-
-  *overflow: visible;
-  /* 3 */
-
-}
-#amber button[disabled], #amber input[disabled] {
-  cursor: default;
-}
-#amber input[type="checkbox"], #amber input[type="radio"] {
-  box-sizing: border-box;
-  /* 1 */
-
-  padding: 0;
-  /* 2 */
-
-  *height: 13px;
-  /* 3 */
-
-  *width: 13px;
-  /* 3 */
-
-}
-#amber input[type="search"] {
-  -webkit-appearance: textfield;
-  /* 1 */
-
-  -moz-box-sizing: content-box;
-  -webkit-box-sizing: content-box;
-  /* 2 */
-
-  box-sizing: content-box;
-}
-#amber input[type="search"]::-webkit-search-decoration, #amber input[type="search"]::-webkit-search-cancel-button {
-  -webkit-appearance: none;
-}
-#amber button::-moz-focus-inner, #amber input::-moz-focus-inner {
-  border: 0;
-  padding: 0;
-}
-#amber textarea {
-  overflow: auto;
-  /* 1 */
-
-  vertical-align: top;
-  /* 2 */
-
-}
-#amber table {
-  border-collapse: collapse;
-  border-spacing: 0;
-}

+ 0 - 501
css/amber-normalize.less

@@ -1,501 +0,0 @@
-/*! normalize.css 2012-03-11T12:53 UTC - http://github.com/necolas/normalize.css */
-
-/* normalize.css co-opted for the amber browser */
-
-#amber {
-
-/* =============================================================================
-   HTML5 display definitions
-   ========================================================================== */
-
-/*
- * Corrects block display not defined in IE6/7/8/9 & FF3
- */
-
-    article,
-    aside,
-    details,
-    figcaption,
-    figure,
-    footer,
-    header,
-    hgroup,
-    nav,
-    section,
-    summary {
-        display: block;
-    }
-
-    /*
-     * Corrects inline-block display not defined in IE6/7/8/9 & FF3
-     */
-
-    audio,
-    canvas,
-    video {
-        display: inline-block;
-        *display: inline;
-        *zoom: 1;
-    }
-
-    /*
-     * Prevents modern browsers from displaying 'audio' without controls
-     * Remove excess height in iOS5 devices
-     */
-
-    audio:not([controls]) {
-        display: none;
-        height: 0;
-    }
-
-    /*
-     * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
-     * Known issue: no IE6 support
-     */
-
-    [hidden] {
-        display: none;
-    }
-
-
-    /* =============================================================================
-       Base
-       ========================================================================== */
-
-    /*
-     * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
-     *    http://clagnut.com/blog/348/#c790
-     * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
-     *    www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
-     */
-
-
-    /*
-     * Addresses font-family inconsistency between 'textarea' and other form elements.
-     */
-
-
-    button,
-    input,
-    select,
-    textarea {
-        font-family: sans-serif;
-    }
-
-    /*
-     * Addresses margins handled incorrectly in IE6/7
-     */
-
-
-
-    /* =============================================================================
-       Links
-       ========================================================================== */
-
-    /*
-     * Addresses outline displayed oddly in Chrome
-     */
-
-    a:focus {
-        outline: thin dotted;
-    }
-
-    /*
-     * Improves readability when focused and also mouse hovered in all browsers
-     * people.opera.com/patrickl/experiments/keyboard/test
-     */
-
-    a:hover,
-    a:active {
-        outline: 0;
-    }
-
-
-    /* =============================================================================
-       Typography
-       ========================================================================== */
-
-    /*
-     * Addresses font sizes and margins set differently in IE6/7
-     * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
-     */
-
-    h1 {
-        font-size: 2em;
-        margin: 0.67em 0;
-    }
-
-    h2 {
-        font-size: 1.5em;
-        margin: 0.83em 0;
-    }
-
-    h3 {
-        font-size: 1.17em;
-        margin: 1em 0;
-    }
-
-    h4 {
-        font-size: 1em;
-        margin: 1.33em 0;
-    }
-
-    h5 {
-        font-size: 0.83em;
-        margin: 1.67em 0;
-    }
-
-    h6 {
-        font-size: 0.75em;
-        margin: 2.33em 0;
-    }
-
-    /*
-     * Addresses styling not present in IE7/8/9, S5, Chrome
-     */
-
-    abbr[title] {
-        border-bottom: 1px dotted;
-    }
-
-    /*
-     * Addresses style set to 'bolder' in FF3+, S4/5, Chrome
-     */
-
-    b,
-    strong {
-        font-weight: bold;
-    }
-
-    blockquote {
-        margin: 1em 40px;
-    }
-
-    /*
-     * Addresses styling not present in S5, Chrome
-     */
-
-    dfn {
-        font-style: italic;
-    }
-
-    /*
-     * Addresses styling not present in IE6/7/8/9
-     */
-
-    mark {
-        background: #ff0;
-        color: #000;
-    }
-
-    /*
-     * Addresses margins set differently in IE6/7
-     */
-
-    p,
-    pre {
-        margin: 1em 0;
-    }
-
-    /*
-     * Corrects font family set oddly in IE6, S4/5, Chrome
-     * en.wikipedia.org/wiki/User:Davidgothberg/Test59
-     */
-
-    pre,
-    code,
-    kbd,
-    samp {
-        font-family: monospace, serif;
-        _font-family: 'courier new', monospace;
-        font-size: 1em;
-    }
-
-    /*
-     * Improves readability of pre-formatted text in all browsers
-     */
-
-    pre {
-        white-space: pre;
-        white-space: pre-wrap;
-        word-wrap: break-word;
-    }
-
-    /*
-     * 1. Addresses CSS quotes not supported in IE6/7
-     * 2. Addresses quote property not supported in S4
-     */
-
-    /* 1 */
-
-    q {
-        quotes: none;
-    }
-
-    /* 2 */
-
-    q:before,
-    q:after {
-        content: '';
-        content: none;
-    }
-
-    small {
-        font-size: 75%;
-    }
-
-    /*
-     * Prevents sub and sup affecting line-height in all browsers
-     * gist.github.com/413930
-     */
-
-    sub,
-    sup {
-        font-size: 75%;
-        line-height: 0;
-        position: relative;
-        vertical-align: baseline;
-    }
-
-    sup {
-        top: -0.5em;
-    }
-
-    sub {
-        bottom: -0.25em;
-    }
-
-
-    /* =============================================================================
-       Lists
-       ========================================================================== */
-
-    /*
-     * Addresses margins set differently in IE6/7
-     */
-
-    dl,
-    menu,
-    ol,
-    ul {
-        margin: 1em 0;
-    }
-
-    dd {
-        margin: 0 0 0 40px;
-    }
-
-    /*
-     * Addresses paddings set differently in IE6/7
-     */
-
-    menu,
-    ol,
-    ul {
-        padding: 0 0 0 40px;
-    }
-
-    /*
-     * Corrects list images handled incorrectly in IE7
-     */
-
-    nav ul,
-    nav ol {
-        list-style: none;
-        list-style-image: none;
-    }
-
-
-    /* =============================================================================
-       Embedded content
-       ========================================================================== */
-
-    /*
-     * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
-     * 2. Improves image quality when scaled in IE7
-     *    code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
-     */
-
-    img {
-        border: 0; /* 1 */
-        -ms-interpolation-mode: bicubic; /* 2 */
-    }
-
-    /*
-     * Corrects overflow displayed oddly in IE9
-     */
-
-    svg:not(:root) {
-        overflow: hidden;
-    }
-
-
-    /* =============================================================================
-       Figures
-       ========================================================================== */
-
-    /*
-     * Addresses margin not present in IE6/7/8/9, S5, O11
-     */
-
-    figure {
-        margin: 0;
-    }
-
-
-    /* =============================================================================
-       Forms
-       ========================================================================== */
-
-    /*
-     * Corrects margin displayed oddly in IE6/7
-     */
-
-    form {
-        margin: 0;
-    }
-
-    /*
-     * Define consistent border, margin, and padding
-     */
-
-    fieldset {
-        border: 1px solid #c0c0c0;
-        margin: 0 2px;
-        padding: 0.35em 0.625em 0.75em;
-    }
-
-    /*
-     * 1. Corrects color not being inherited in IE6/7/8/9
-     * 2. Corrects text not wrapping in FF3
-     * 3. Corrects alignment displayed oddly in IE6/7
-     */
-
-    legend {
-        border: 0; /* 1 */
-        padding: 0;
-        white-space: normal; /* 2 */
-        *margin-left: -7px; /* 3 */
-    }
-
-    /*
-     * 1. Corrects font size not being inherited in all browsers
-     * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
-     * 3. Improves appearance and consistency in all browsers
-     */
-
-    button,
-    input,
-    select,
-    textarea {
-        font-size: 100%; /* 1 */
-        margin: 0; /* 2 */
-        vertical-align: baseline; /* 3 */
-        *vertical-align: middle; /* 3 */
-    }
-
-    /*
-     * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
-     */
-
-    button,
-    input {
-        line-height: normal; /* 1 */
-    }
-
-    /*
-     * 1. Improves usability and consistency of cursor style between image-type 'input' and others
-     * 2. Corrects inability to style clickable 'input' types in iOS
-     * 3. Removes inner spacing in IE7 without affecting normal text inputs
-     *    Known issue: inner spacing remains in IE6
-     */
-
-    button,
-    input[type="button"],
-    input[type="reset"],
-    input[type="submit"] {
-        cursor: pointer; /* 1 */
-        -webkit-appearance: button; /* 2 */
-        *overflow: visible;  /* 3 */
-    }
-
-    /*
-     * Re-set default cursor for disabled elements
-     */
-
-    button[disabled],
-    input[disabled] {
-        cursor: default;
-    }
-
-    /*
-     * 1. Addresses box sizing set to content-box in IE8/9
-     * 2. Removes excess padding in IE8/9
-     * 3. Removes excess padding in IE7
-     Known issue: excess padding remains in IE6
-     */
-
-    input[type="checkbox"],
-    input[type="radio"] {
-        box-sizing: border-box; /* 1 */
-        padding: 0; /* 2 */
-        *height: 13px; /* 3 */
-        *width: 13px; /* 3 */
-    }
-
-    /*
-     * 1. Addresses appearance set to searchfield in S5, Chrome
-     * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
-     */
-
-    input[type="search"] {
-        -webkit-appearance: textfield; /* 1 */
-        -moz-box-sizing: content-box;
-        -webkit-box-sizing: content-box; /* 2 */
-        box-sizing: content-box;
-    }
-
-    /*
-     * Removes inner padding and search cancel button in S5, Chrome on OS X
-     */
-
-    input[type="search"]::-webkit-search-decoration,
-    input[type="search"]::-webkit-search-cancel-button {
-        -webkit-appearance: none;
-    }
-
-    /*
-     * Removes inner padding and border in FF3+
-     * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
-     */
-
-    button::-moz-focus-inner,
-    input::-moz-focus-inner {
-        border: 0;
-        padding: 0;
-    }
-
-    /*
-     * 1. Removes default vertical scrollbar in IE6/7/8/9
-     * 2. Improves readability and alignment in all browsers
-     */
-
-    textarea {
-        overflow: auto; /* 1 */
-        vertical-align: top; /* 2 */
-    }
-
-
-    /* =============================================================================
-       Tables
-       ========================================================================== */
-
-    /*
-     * Remove most spacing between table cells
-     */
-
-    table {
-        border-collapse: collapse;
-        border-spacing: 0;
-    }
-}

+ 0 - 84
css/documentation.css

@@ -1,84 +0,0 @@
-#wrapper {
-    margin-left: 350px;
-    text-align: left;
-}
-
-#header {
-    text-align: left;
-    margin: 20px 0;
-}
-
-#header .left {
-    float: left;
-    margin-right: 20px;
-}
-
-#header h1 {
-    margin: 10px 0;
-}
-
-.documentation {
-    border-top: 1px solid #999;
-}
-
-.documentation a {
-    color: #C71212;
-    cursor: pointer;
-}
-
-.documentation a:hover {
-    color: white;
-    background: #D15E5E;
-    text-decoration: none;
-}
-
-.documentation pre {
-    border-radius: 3px;
-    border: 1px solid #ccc;
-    background: #eee;
-    padding: 5px;
-    margin: 0 20px;
-}
-
-.documentation code {
-    background: #eee;
-    padding: 0 5px;
-}
-
-
-.documentation .menu {
-    position: fixed;
-    left: 0;
-    bottom: 0;
-    top: 0;
-    width: 300px;
-    background: #ddd;
-    overflow-y: scroll;
-}
-
-.documentation .doc_chapter {
-    position: absolute;
-    background: #fafafa;
-    left: 300px;
-    right: 0;
-    padding: 0 20px;
-}
-
-.documentation .doc_chapter a {
-    background: #eae3c6;
-}
-
-.documentation .doc_chapter a:hover {
-    background: #D15E5E;
-    color: white;
-}
-
-.documentation .doc_chapter .links {
-    border-top: 1px solid #999;
-    margin-top: 10px;
-    padding-top: 10px;
-}
-
-.documentation .doc_chapter h2 {
-    border-bottom: 1px solid #999;
-}

+ 0 - 75
css/profstef.css

@@ -1,75 +0,0 @@
-html,body {
-	margin: 0;
-	padding: 0;
-	font: 14px "Helvetica Neue", "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif;
-	line-height: 1.5;
-	color: #444;
-}
-
-/* Fonts */
-
-h1, h2, h3 {
-    font-family: 'Istok Web';
-    font-weight: normal;
-    color: #442905;
-    line-height: 1.2;
-}
-
-h1 {
-    text-align: center;
-    font-weight: bold;
-    text-shadow: 0px 1px 1px #FFF;
-}
-
-
-.main {
-    width: 900px;
-    margin: 0;
-    border: 0;
-    text-align: center;
-    margin: 0 auto;
-}
-
-.main img {
-    margin: 30px 0;
-}
-
-a#back {
-    color: #666;
-    padding: 20px 0;
-}
-
-#tutorial {
-    padding: 20px 40px;
-    margin: 30px 0;
-    text-align: left;
-    border: 12px solid #aaa;
-    border-radius: 8px;
-    -webkit-border-radius: 8px;
-    -moz-border-radius: 8px;
-}
-
-#tutorial .CodeMirror-scroll {
-    overflow: auto;
-    height: auto;
-}
-
-#footer .main {
-    	border-top: 1px dashed #bbb;
-	padding-top: 10px;
-}
-
-#footer p {
-	text-align: center;
-	line-height: 1em;
-	color: #aaa;
-}
-
-#footer a {
-	color: #3faae1;
-	text-decoration: none;
-}
-
-#footer a:hover {
-	text-decoration: underline;
-}

+ 0 - 313
css/style.css

@@ -1,313 +0,0 @@
-/* CSS Reset */
-
-html,body {
-	margin: 0;
-	padding: 0;
-	font: 14px "Helvetica Neue", "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif;
-	line-height: 1.5;
-	color: #444;
-}
-
-/* Layout */
-
-.clear {clear:both}
-
-#header {
-    margin: 60px auto;
-    margin-bottom: 20px;
-}
-
-#header .main {
-    text-align: center;
-}
-
-.teaser {
-    background: #eee;
-    border: 3px solid #ccc;
-    border-left: 0;
-    border-right: 0;
-    padding: 20px;
-    margin-bottom: 50px;
-}
-
-#tabs {
-    list-type: none;
-    position: absolute;
-    top: 0;
-    right: 0;
-    padding-right: 20px;
-}
-
-#tabs li {
-    margin: 0 5px;
-    display: inline;
-}
-
-a {
-    text-decoration: none;
-    color: #613823;
-}
-
-a:hover {
-    text-decoration: underline;
-}
-
-a.selected {
-    text-decoration: underline;
-    color: #444;
-}
-
-	
-.main {
-	width: 900px;
-	margin: 0 auto;
-}
-
-
-.column {
-    float: left;
-    width: 440px;
-    margin-right: 10px;
-}
-
-
-/* Fonts */
-
-h1, h2, h3 {
-    font-family: 'Istok Web';
-    font-weight: normal;
-    color: #442905;
-    line-height: 1.2;
-}
-
-h1 {
-    font-weight: bold;
-    color: #333;
-    text-shadow: 0px 1px 1px #FFF;
-}
-
-.teaser h1 {
-    text-align: center;
-}
-
-.box {
-    margin: 40px 0;
-    color: #777;
-}
-
-.box.doc {
-    margin-top: 70px;
-    position: relative;
-    width: 630px;
-}
-
-.box .content .warning,
-.box .content .information {
-    position: absolute;
-    right: -250px;
-    margin-top: 20px;
-    width: 200px;
-    font-size: 14px;
-    color: #222;
-    font-family: arial,helevetica,sans;
-    padding: 10px;
-    opacity: 0.7;
-    -moz-transition: opacity 0.3s;
-    -webkit-transition: opacity 0.3s;
-    -o-transition: opacity 0.3s;
-}
-
-.box .content .warning:hover,
-.box .content .information:hover {
-    opacity: 1;
-}
-
-.box .content .information:before,
-.box .content .warning:before {
-    font-family: Georgia, sans-serif;
-    font-size: 28px;
-    font-style: italic;
-    position: absolute;
-    right: 0;
-    top: -21px;
-    opacity: 0.5;
-}
-
-.box .content .information:before {
-    content: "Info";
-    color: #a6b1f3;
-}
-
-.box .content .warning:before {
-    content: "Warning";
-    color: #e869e7;
-}
-
-.box .content .information {
-    background-color: #e4e8ff;
-}    
-
-.box .content .warning {
-    background-color: #f8ccf8;
-}
-
-.box .content .code {
-	background: #565656;
-	border-radius: 10px;
-	-moz-border-radius: 10px;
-	-webkit-border-radius: 10px;
-	padding: 7px;
-}
-
-.box .content .code p {
-	color: white;
-}
-
-.box.first .content .left ul {
-	padding-left: 10px;
-}
-
-.box.last .content .right {
-    width: 300px;
-}
-
-.doc .box.first .content .right {
-	float: right;
-	width: 230px;
-	margin-top: 20px;
-	padding: 10px;
-	background-color: #ececec;
-	border: 1px solid #e1e1e1;
-	border-radius: 10px;
-	-moz-border-radius: 10px;
-	-webkit-border-radius: 10px;
-}
-
-.doc .box.first .content .right ol, 
-.doc .box.first .content .right ol a {
-	color: #03388a;
-}
-
-.doc .box.first .content .right ol {
-	padding: 0 0 7px 35px;
-}
-
-.doc .box.first .content .right ol li{
-	padding: 7px 0 7px 0; 
-}
-
-.doc .box.first .content .right ul a {
-	font: 15px Helvetica, Arial, sans;
-	color: black;
-}
-
-.doc .box.first .content .right ul li {
-	list-style-type: none;
-	padding: 2px 0 2px 0;
-}
-
-.trysmalltalk {
-    text-align: right;
-    padding: 10px;
-}
-
-.trysmalltalk textarea {
-    width: 850px;
-    height: 300px;
-    padding: 20px;
-    background-color: #eaeaea;
-    border: 1px solid #d3d3d3;
-    border-radius: 10px;
-    -moz-border-radius: 10px;
-    -webkit-border-radius: 10px;
-    font: 16px monaco, courier, monospace;
-    color: 434343;
-    line-height: 1.6em;
-}
-
-.trysmalltalk button {
-    margin: 20px 0 0 5px;
-    padding: 4px;
-    background: #75aef5;
-    border: 1px solid #7caeed;
-    border-radius: 8px;
-    -moz-border-radius: 8px;
-    -webkit-border-radius: 8px;
-    color: white;
-    cursor: pointer;
-}
-
-.trysmalltalk .print-it {
-	background: #bebebe;
-	border: 1px solid #b2b2b2;
-}
-
-.trysmalltalk button:hover {
-	background: #3180e1;
-	border: 1px solid #518cd6; 
-}
-
-#counters {
-    border: 2px dashed;
-    text-align: center;
-    padding: 10px;
-    margin: 10px;
-    background: #ffffcc;
-    font-family: arial,helvetica,sans;
-}
-
-#counters h1 {
-    margin: 10px;
-    color: #333;
-}
-
-
-.trysmalltalk .print-it:hover {
-	background: #898989;
-	border: 1px solid #919293; 
-}
-
-
-.examples li {
-	list-style: none;
-	float: left;
-}
-
-.examples li img {
-		border-radius: 5px;
-		border: 5px solid rgba(0,0,0,0.4);
-		margin: 5px;
-}
-
-.examples a:hover img {
-		border-color: rgba(0,0,0,0.8);
-}
-
-
-
-#footer {
-	height: 200px;
-	border: 1px solid #ccc;
-	background: #f3f3f3 url('../images/mosquito.png') 50px 20px no-repeat;
-	margin: 0 auto;
-}
-
-#footer .main {
-	padding-top: 10px;
-}
-
-#footer p {
-	text-align: center;
-	line-height: 1em;
-	color: #aaa;
-}
-
-#footer a {
-	color: #3faae1;
-	text-decoration: none;
-}
-
-#footer a:hover {
-	text-decoration: underline;
-}
-

+ 0 - 37
documentation.html

@@ -1,37 +0,0 @@
-<!DOCTYPE html> 
-<html> 
-  <head> 
-    <title>Amber Smalltalk - Documentation</title> 
-    <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
-    <meta name="author" content="Nicolas Petton" /> 
-    <link rel="stylesheet" type="text/css" href='css/style.css' /> 
-    <link rel="stylesheet" type="text/css" href='css/documentation.css' /> 
-    <link type="image/x-icon" rel="shortcut icon" href="/favicon.ico"/> 
-    <link href='http://fonts.googleapis.com/css?family=Istok+Web' rel='stylesheet' type='text/css'> 
-    <script type='text/javascript' src='js/amber.js'></script> 
-    <script type='text/javascript' src='js/lib/showdown.js'></script> 
-  </head> 
-  <body> 
-    
-    <div id="wrapper"> 
-      
-      <div id="header"> 
-	<img class="left" src="images/amber_small.png"/> 
-	<div class="left">
-	  <h1>Amber Smalltalk - documentation</h1>
-	  <h2>Version 0.9.1</h2>
-	</div>
-	<div class="clear"></div>
-      <ul id="tabs"> 
-	<li><a href="./index.html">Overview</a></li> · 
-	<li><a href="./learn.html">Learn</a></li> ·
-	<li><a href="./documentation.html">Documentation</a></li> ·
-	<li><a target="_blank" target="_blank" href="https://github.com/NicolasPetton/amber">Source</a></li> 
-      </ul> 
-      
-      <div class="clear"></div> 
-    </div>
-    <script type='text/javascript'> loadAmber({files: ['Documentation.js']}) </script> 
-    
-  </body> 
-</html> 

BIN
favicon.ico


+ 1 - 7
grunt.js

@@ -66,12 +66,6 @@ module.exports = function(grunt) {
         src: ['Kernel-Tests.st', 'Compiler-Tests.st'],
         libraries: ['SUnit']
       },
-      amber_examples: {
-        working_dir: 'st',
-        target_dir : 'js',
-        src: ['Examples.st'],
-        libraries: ['Canvas', 'IDE']
-      },
       amber_dev: {
         working_dir: 'js',
         src: ['Kernel-Objects.js', 'Kernel-Classes.js', 'Kernel-Methods.js', 'Kernel-Collections.js',
@@ -79,7 +73,7 @@ module.exports = function(grunt) {
               'Compiler.js', 'Compiler-Exceptions.js', 'Compiler-Core.js', 'Compiler-AST.js',
               'Compiler-IR.js', 'Compiler-Inlining.js', 'Compiler-Semantic.js',
               'Kernel-Tests.js', 'Compiler-Tests.js',
-              'Canvas.js', 'IDE.js', 'SUnit.js', 'Documentation.js', 'Examples.js'],
+              'Canvas.js', 'IDE.js', 'SUnit.js', 'Documentation.js'],
         output_name: 'amber_lib'
       },
       server: {

BIN
images/presentation.png


BIN
images/profstef.png


BIN
images/twitterwall.png


+ 3 - 98
index.html

@@ -1,109 +1,14 @@
 <!DOCTYPE html> 
 <html> 
+
   <head> 
     <title>Amber Smalltalk</title> 
     <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
     <meta name="author" content="Nicolas Petton" /> 
-    <link rel="stylesheet" type="text/css" href='css/style.css' /> 
-    <link type="image/x-icon" rel="shortcut icon" href="/favicon.ico"/> 
-    <link href='http://fonts.googleapis.com/css?family=Istok+Web' rel='stylesheet' type='text/css'> 
     <script type='text/javascript' src='js/amber.js'></script> 
-    <script type='text/javascript' src='js/lib/showdown.js'></script> 
   </head> 
+
   <body> 
-    
-    <a href="http://github.com/NicolasPetton/amber"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_left_orange_ff7600.png" alt="Fork me on GitHub"></a>
-    
-    <div id="wrapper"> 
-      
-      <div id="header"> 
-	<div class="main"> 
-	  <div class="logo"> 
-	    <img src="images/amber.png"/> 
-	  </div> 
-	  
-	  <ul id="tabs"> 
-	    <li><a href="./index.html">Overview</a></li> · 
-	    <li><a href="./learn.html">Learn</a></li> ·
-	    <li><a href="./documentation.html">Documentation</a></li> ·
-	    <li><a target="_blank" target="_blank" href="https://github.com/NicolasPetton/amber">Source</a></li> 
-	  </ul> 
-	  
-	  <div class="clear"></div> 
-	  
-	</div> 
-      </div> 
-      
-      <div class="teaser"> 
-	<div class="main"> 
-	  <h1>Welcome aboard!</h1> 
-	  <div class="column">
-	    <h2>What is Amber?</h2>
-	    <p>Amber, formerly known as Jtalk, is an implementation of the Smalltalk-80 language. It is designed to make client-side development faster and easier. It allows developers to write client-side heavy web applications in Smalltalk. </p> 
-	    <p>Amber includes an integrated development environment with a class browser, workspace, transcript, object inspector and debugger.</p> 
-	    <p>Amber is written in itself, including the compiler, and compiles into efficient JavaScript, mapping one-to-one with the JS equivalent.</p> 
-	    <h2>Give it a try!</h2>
-	    <p><b>Try a <button onClick="smalltalk.Browser._open()"> Class browser</button> right now!</b></p> 
-	  </div> 
-	  <div class="column">
-	    <h2>Getting started</h2>
-	    <p>The <a href="https://github.com/NicolasPetton/amber/wiki">Wiki on GitHub</a> includes a <a href="https://github.com/NicolasPetton/amber/wiki/Getting-started">Getting started</a> tutorial for OSX, Linux and Windows.</p>
-	    <p>If you're new to Smalltalk, You can learn it online with <a href="http://amber-lang.net/learn.html">ProfStef</a>.</p>
-	    <h2>Join the community</h2>
-	    <ul>
-	      <li><a href="http://amber-lang.net">Amber's website</a></li>
-	      <li><a href="https://github.com/NicolasPetton/amber/wiki">Wiki on GitHub</a></li>
-	      <li><a href="http://groups.google.com/group/amber-lang">Mailing list</a></li>
-	      <li>Join us on IRC at #amber-lang on Freenode</li>
-	    </ul>
-	  </div>
-	  <div class="clear"></div> 
-	</div> 
-	
-	
-      </div> 
-      
-      <div id="content"> 
-	<div class="main"> 
-	  <div class="box"> 
-	    <h2>Client-side usage</h2> 
-	    <div class="content"> 
-	      <p>Load the full Amber Smalltalk environment with the IDE in your page:</p> 
-	      
-	      <code><pre>&lt;script src="js/amber.js" type="text/javascript"&gt;&lt;/script&gt;
-		  &lt;script type="text/javascript"&gt; loadAmber()&lt;/script&gt;</pre></code>
-	    </div> 
-	    
-	    
-	    <p>Or the deployment JavaScript file only (without the Smalltalk sources, parser, compiler and IDE):</p>
-	    <code><pre>&lt;script src="js/amber.js" type="text/javascript"&gt;&lt;/script&gt;
-		&lt;script type="text/javascript"&gt; loadAmber({deploy: true})&lt;/script&gt;</pre></code>
-	  </div> 
-	  
-	  <div class="box last examples"> 
-	    <h2>Examples</h2> 
-	    <div class="content"> 
-	      <ul>
-		<li>
-		  <a href="examples/presentation/index.html">
-		    <img src="images/presentation.png" alt="ESUG 2011 presentation"/>
-		  </a>
-		</li>
-		<li>
-		  <a href="examples/twitterwall/index.html">
-		    <img src="images/twitterwall.png" alt="Twitter Wall"/>
-		  </a>
-		</li>
-		<div class="clear"></div>
-	      </ul>
-	    </div> 
-	  </div> 
-	  
-	</div> 
-      </div> 
-    </div> 
-    
-    <script type='text/javascript'> loadAmber() </script> 
-    
+    <script type='text/javascript'> loadAmber({ready: function() {smalltalk.Browser._open()}}) </script> 
   </body> 
 </html> 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 737
js/Documentation.deploy.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 962
js/Documentation.js


+ 23 - 1
js/IDE.deploy.js

@@ -1,4 +1,4 @@
-smalltalk.addPackage('IDE', {});
+smalltalk.addPackage('IDE');
 smalltalk.addClass('ClassesList', smalltalk.Widget, ['browser', 'ul', 'nodes'], 'IDE');
 smalltalk.addMethod(
 "_browser",
@@ -1145,6 +1145,28 @@ return self}, function($ctx1) {$ctx1.fill(self,"new",{}, smalltalk.TabManager.kl
 messageSends: ["shouldNotImplement"]}),
 smalltalk.TabManager.klass);
 
+smalltalk.addMethod(
+"_toggleAmberIDE",
+smalltalk.method({
+selector: "toggleAmberIDE",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(_st(_st(window)._jQuery_("#amber"))._length()).__eq((0));
+if(smalltalk.assert($1)){
+_st((smalltalk.Browser || Browser))._open();
+} else {
+$2=_st(_st(window)._jQuery_("#amber"))._is_(":visible");
+if(smalltalk.assert($2)){
+_st(_st((smalltalk.TabManager || TabManager))._current())._close();
+} else {
+_st(_st((smalltalk.TabManager || TabManager))._current())._open();
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"toggleAmberIDE",{}, smalltalk.TabManager.klass)})},
+messageSends: ["ifTrue:ifFalse:", "open", "close", "current", "is:", "jQuery:", "=", "length"]}),
+smalltalk.TabManager.klass);
+
 
 smalltalk.addClass('TabWidget', smalltalk.Widget, ['div'], 'IDE');
 smalltalk.addMethod(

+ 28 - 1
js/IDE.js

@@ -1,4 +1,4 @@
-smalltalk.addPackage('IDE', {});
+smalltalk.addPackage('IDE');
 smalltalk.addClass('ClassesList', smalltalk.Widget, ['browser', 'ul', 'nodes'], 'IDE');
 smalltalk.addMethod(
 "_browser",
@@ -1490,6 +1490,33 @@ referencedClasses: []
 }),
 smalltalk.TabManager.klass);
 
+smalltalk.addMethod(
+"_toggleAmberIDE",
+smalltalk.method({
+selector: "toggleAmberIDE",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(_st(_st(window)._jQuery_("#amber"))._length()).__eq((0));
+if(smalltalk.assert($1)){
+_st((smalltalk.Browser || Browser))._open();
+} else {
+$2=_st(_st(window)._jQuery_("#amber"))._is_(":visible");
+if(smalltalk.assert($2)){
+_st(_st((smalltalk.TabManager || TabManager))._current())._close();
+} else {
+_st(_st((smalltalk.TabManager || TabManager))._current())._open();
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"toggleAmberIDE",{}, smalltalk.TabManager.klass)})},
+args: [],
+source: "toggleAmberIDE\x0a\x09(window jQuery: '#amber') length = 0\x0a\x09\x09ifTrue: [ Browser open ]\x0a      \x09ifFalse: [ \x0a\x09\x09\x09((window jQuery: '#amber') is: ':visible')\x0a\x09\x09\x09\x09ifTrue: [ TabManager current close ] \x0a\x09\x09\x09\x09ifFalse: [ TabManager current open ] ]",
+messageSends: ["ifTrue:ifFalse:", "open", "close", "current", "is:", "jQuery:", "=", "length"],
+referencedClasses: ["Browser", "TabManager"]
+}),
+smalltalk.TabManager.klass);
+
 
 smalltalk.addClass('TabWidget', smalltalk.Widget, ['div'], 'IDE');
 smalltalk.addMethod(

+ 139 - 72
js/Importer-Exporter.deploy.js

@@ -7,16 +7,19 @@ selector: "nextChunk",
 fn: function (){
 var self=this;
 var char,result,chunk;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
 var $early={};
 try {
 result=_st("")._writeStream();
 _st((function(){
-return smalltalk.withContext(function($ctx2) {
char=_st(self["@stream"])._next();
+return smalltalk.withContext(function($ctx2) {
+char=_st(self["@stream"])._next();
 char;
 return _st(char)._notNil();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
-return smalltalk.withContext(function($ctx2) {
$1=_st(char).__eq("!");
+return smalltalk.withContext(function($ctx2) {
+$1=_st(char).__eq("!");
 if(smalltalk.assert($1)){
 $2=_st(_st(self["@stream"])._peek()).__eq("!");
 if(smalltalk.assert($2)){
@@ -41,7 +44,8 @@ smalltalk.method({
 selector: "stream:",
 fn: function (aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@stream"]=aStream;
+return smalltalk.withContext(function($ctx1) { 
+self["@stream"]=aStream;
 return self}, function($ctx1) {$ctx1.fill(self,"stream:",{aStream:aStream}, smalltalk.ChunkParser)})},
 messageSends: []}),
 smalltalk.ChunkParser);
@@ -53,7 +57,8 @@ smalltalk.method({
 selector: "on:",
 fn: function (aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st(_st(self)._new())._stream_(aStream);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"on:",{aStream:aStream}, smalltalk.ChunkParser.klass)})},
@@ -68,7 +73,8 @@ smalltalk.method({
 selector: "classNameFor:",
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 if(smalltalk.assert($2)){
 $1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
@@ -91,10 +97,13 @@ smalltalk.method({
 selector: "exportAll",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st((smalltalk.String || String))._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packages())._do_((function(pkg){
-return smalltalk.withContext(function($ctx3) {
return _st(stream)._nextPutAll_(_st(self)._exportPackage_(_st(pkg)._name()));
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packages())._do_((function(pkg){
+return smalltalk.withContext(function($ctx3) {
+return _st(stream)._nextPutAll_(_st(self)._exportPackage_(_st(pkg)._name()));
 }, function($ctx3) {$ctx3.fillBlock({pkg:pkg},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
@@ -108,9 +117,11 @@ smalltalk.method({
 selector: "exportClass:",
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st((smalltalk.String || String))._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
_st(self)._exportDefinitionOf_on_(aClass,stream);
+return smalltalk.withContext(function($ctx2) {
+_st(self)._exportDefinitionOf_on_(aClass,stream);
 _st(self)._exportMethodsOf_on_(aClass,stream);
 _st(self)._exportMetaDefinitionOf_on_(aClass,stream);
 return _st(self)._exportMethodsOf_on_(_st(aClass)._class(),stream);
@@ -126,16 +137,19 @@ smalltalk.method({
 selector: "exportDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4,$5,$6,$7;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addClass(");
 _st($1)._nextPutAll_(_st(_st("'").__comma(_st(self)._classNameFor_(aClass))).__comma("', "));
 _st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._superclass())));
 $2=_st($1)._nextPutAll_(", [");
 _st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(", ");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(", ");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 $3=aStream;
 _st($3)._nextPutAll_("], '");
@@ -162,7 +176,8 @@ smalltalk.method({
 selector: "exportMetaDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
 $1=_st(_st(_st(aClass)._class())._instanceVariableNames())._isEmpty();
 if(! smalltalk.assert($1)){
 $2=aStream;
@@ -170,9 +185,11 @@ _st($2)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aCla
 $3=_st($2)._nextPutAll_(".iVarNames = [");
 $3;
 _st(_st(_st(aClass)._class())._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(",");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(",");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 _st(aStream)._nextPutAll_(_st("];").__comma(_st((smalltalk.String || String))._lf()));
 };
@@ -186,7 +203,8 @@ smalltalk.method({
 selector: "exportMethod:of:on:",
 fn: function (aMethod,aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addMethod(");
 _st($1)._lf();
@@ -225,11 +243,14 @@ smalltalk.method({
 selector: "exportMethodsOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 _st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
$1=_st(_st(each)._category())._match_("^\x5c*");
+return smalltalk.withContext(function($ctx2) {
+$1=_st(_st(each)._category())._match_("^\x5c*");
 if(! smalltalk.assert($1)){
 return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 };
@@ -246,13 +267,16 @@ selector: "exportPackage:",
 fn: function (packageName){
 var self=this;
 var package_;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st((smalltalk.String || String))._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
package_=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packageAt_(packageName);
+return smalltalk.withContext(function($ctx2) {
+package_=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packageAt_(packageName);
 package_;
 _st(self)._exportPackageDefinitionOf_on_(package_,stream);
 _st(_st(_st(package_)._sortedClasses())._asSet())._do_((function(each){
-return smalltalk.withContext(function($ctx3) {
return _st(stream)._nextPutAll_(_st(self)._exportClass_(each));
+return smalltalk.withContext(function($ctx3) {
+return _st(stream)._nextPutAll_(_st(self)._exportClass_(each));
 }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
 return _st(self)._exportPackageExtensionsOf_on_(package_,stream);
 }, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
@@ -267,13 +291,14 @@ smalltalk.method({
 selector: "exportPackageDefinitionOf:on:",
 fn: function (package_,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addPackage(");
-$2=_st($1)._nextPutAll_(_st(_st(_st(_st("'").__comma(_st(package_)._name())).__comma("', ")).__comma(_st(package_)._propertiesAsJSON())).__comma(");"));
-_st(aStream)._lf();
+_st($1)._nextPutAll_(_st(_st("'").__comma(_st(package_)._name())).__comma("');"));
+$2=_st($1)._lf();
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{package_:package_,aStream:aStream}, smalltalk.Exporter)})},
-messageSends: ["nextPutAll:", ",", "propertiesAsJSON", "name", "lf"]}),
+messageSends: ["nextPutAll:", ",", "name", "lf"]}),
 smalltalk.Exporter);
 
 smalltalk.addMethod(
@@ -283,14 +308,19 @@ selector: "exportPackageExtensionsOf:on:",
 fn: function (package_,aStream){
 var self=this;
 var name;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 name=_st(package_)._name();
 _st(_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes()))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st([each,_st(each)._class()])._do_((function(aClass){
-return smalltalk.withContext(function($ctx3) {
return _st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx4) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+return smalltalk.withContext(function($ctx2) {
+return _st([each,_st(each)._class()])._do_((function(aClass){
+return smalltalk.withContext(function($ctx3) {
+return _st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx4) {
+return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
 }, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(method){
-return smalltalk.withContext(function($ctx4) {
$1=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
+return smalltalk.withContext(function($ctx4) {
+$1=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
 if(smalltalk.assert($1)){
 return _st(self)._exportMethod_of_on_(method,aClass,aStream);
 };
@@ -310,7 +340,8 @@ smalltalk.method({
 selector: "chunkEscape:",
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st(_st(aString)._replace_with_("!","!!"))._trimBoth();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"chunkEscape:",{aString:aString}, smalltalk.ChunkExporter)})},
@@ -323,7 +354,8 @@ smalltalk.method({
 selector: "classNameFor:",
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 if(smalltalk.assert($2)){
 $1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(" class");
@@ -346,16 +378,19 @@ smalltalk.method({
 selector: "exportDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4,$5,$6,$7;
 $1=aStream;
 _st($1)._nextPutAll_(_st(self)._classNameFor_(_st(aClass)._superclass()));
 _st($1)._nextPutAll_(_st(" subclass: #").__comma(_st(self)._classNameFor_(aClass)));
 _st($1)._lf();
 $2=_st($1)._nextPutAll_("\x09instanceVariableNames: '");
 _st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(each);
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(" ");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(" ");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 $3=aStream;
 _st($3)._nextPutAll_("'");
@@ -382,7 +417,8 @@ smalltalk.method({
 selector: "exportMetaDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4,$5;
 $1=_st(_st(_st(aClass)._class())._instanceVariableNames())._isEmpty();
 if(! smalltalk.assert($1)){
 $2=aStream;
@@ -390,9 +426,11 @@ _st($2)._nextPutAll_(_st(self)._classNameFor_(_st(aClass)._class()));
 $3=_st($2)._nextPutAll_(" instanceVariableNames: '");
 $3;
 _st(_st(_st(aClass)._class())._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(each);
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(" ");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(" ");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 $4=aStream;
 _st($4)._nextPutAll_("'!");
@@ -410,7 +448,8 @@ smalltalk.method({
 selector: "exportMethod:of:on:",
 fn: function (aMethod,aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=aStream;
 _st($1)._lf();
 _st($1)._lf();
@@ -427,14 +466,17 @@ smalltalk.method({
 selector: "exportMethods:category:of:on:",
 fn: function (methods,category,aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4;
 $1=aStream;
 _st($1)._nextPutAll_(_st("!").__comma(_st(self)._classNameFor_(aClass)));
 $2=_st($1)._nextPutAll_(_st(_st(" methodsFor: '").__comma(category)).__comma("'!"));
 _st(_st(methods)._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(self)._exportMethod_of_on_(each,aClass,aStream);
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 $3=aStream;
 _st($3)._nextPutAll_(" !");
@@ -451,19 +493,23 @@ selector: "exportMethodsOf:on:",
 fn: function (aClass,aStream){
 var self=this;
 var map;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 map=_st((smalltalk.Dictionary || Dictionary))._new();
 _st(aClass)._protocolsDo_((function(category,methods){
-return smalltalk.withContext(function($ctx2) {
$1=_st(category)._match_("^\x5c*");
+return smalltalk.withContext(function($ctx2) {
+$1=_st(category)._match_("^\x5c*");
 if(! smalltalk.assert($1)){
 return _st(map)._at_put_(category,methods);
 };
 }, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
 _st(_st(_st(map)._keys())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx2) {
return _st(a).__lt_eq(b);
+return smalltalk.withContext(function($ctx2) {
+return _st(a).__lt_eq(b);
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 var methods;
-return smalltalk.withContext(function($ctx2) {
methods=_st(map)._at_(category);
+return smalltalk.withContext(function($ctx2) {
+methods=_st(map)._at_(category);
 methods;
 return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
 }, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
@@ -477,12 +523,13 @@ smalltalk.method({
 selector: "exportPackageDefinitionOf:on:",
 fn: function (package_,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=aStream;
-_st($1)._nextPutAll_(_st(_st(_st(_st("Smalltalk current createPackage: '").__comma(_st(package_)._name())).__comma("' properties: ")).__comma(_st(_st(package_)._properties())._storeString())).__comma("!"));
+_st($1)._nextPutAll_(_st(_st("Smalltalk current createPackage: '").__comma(_st(package_)._name())).__comma("'!"));
 $2=_st($1)._lf();
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{package_:package_,aStream:aStream}, smalltalk.ChunkExporter)})},
-messageSends: ["nextPutAll:", ",", "storeString", "properties", "name", "lf"]}),
+messageSends: ["nextPutAll:", ",", "name", "lf"]}),
 smalltalk.ChunkExporter);
 
 smalltalk.addMethod(
@@ -492,23 +539,29 @@ selector: "exportPackageExtensionsOf:on:",
 fn: function (package_,aStream){
 var self=this;
 var name,map;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 name=_st(package_)._name();
 _st(_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes()))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st([each,_st(each)._class()])._do_((function(aClass){
-return smalltalk.withContext(function($ctx3) {
map=_st((smalltalk.Dictionary || Dictionary))._new();
+return smalltalk.withContext(function($ctx2) {
+return _st([each,_st(each)._class()])._do_((function(aClass){
+return smalltalk.withContext(function($ctx3) {
+map=_st((smalltalk.Dictionary || Dictionary))._new();
 map;
 _st(aClass)._protocolsDo_((function(category,methods){
-return smalltalk.withContext(function($ctx4) {
$1=_st(category)._match_(_st("^\x5c*").__comma(name));
+return smalltalk.withContext(function($ctx4) {
+$1=_st(category)._match_(_st("^\x5c*").__comma(name));
 if(smalltalk.assert($1)){
 return _st(map)._at_put_(category,methods);
 };
 }, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
 return _st(_st(_st(map)._keys())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx4) {
return _st(a).__lt_eq(b);
+return smalltalk.withContext(function($ctx4) {
+return _st(a).__lt_eq(b);
 }, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 var methods;
-return smalltalk.withContext(function($ctx4) {
methods=_st(map)._at_(category);
+return smalltalk.withContext(function($ctx4) {
+methods=_st(map)._at_(category);
 methods;
 return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
 }, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
@@ -527,16 +580,19 @@ smalltalk.method({
 selector: "exportDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addClass(");
 _st($1)._nextPutAll_(_st(_st("'").__comma(_st(self)._classNameFor_(aClass))).__comma("', "));
 _st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._superclass())));
 $2=_st($1)._nextPutAll_(", [");
 _st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(", ");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(", ");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 $3=aStream;
 _st($3)._nextPutAll_("], '");
@@ -553,7 +609,8 @@ smalltalk.method({
 selector: "exportMethod:of:on:",
 fn: function (aMethod,aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addMethod(");
 _st($1)._lf();
@@ -586,15 +643,18 @@ selector: "import:",
 fn: function (aStream){
 var self=this;
 var chunk,result,parser,lastEmpty;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 parser=_st((smalltalk.ChunkParser || ChunkParser))._on_(aStream);
 lastEmpty=false;
 _st((function(){
-return smalltalk.withContext(function($ctx2) {
chunk=_st(parser)._nextChunk();
+return smalltalk.withContext(function($ctx2) {
+chunk=_st(parser)._nextChunk();
 chunk;
 return _st(chunk)._isNil();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileFalse_((function(){
-return smalltalk.withContext(function($ctx2) {
$1=_st(chunk)._isEmpty();
+return smalltalk.withContext(function($ctx2) {
+$1=_st(chunk)._isEmpty();
 if(smalltalk.assert($1)){
 lastEmpty=true;
 return lastEmpty;
@@ -622,7 +682,8 @@ smalltalk.method({
 selector: "initializePackageNamed:prefix:",
 fn: function (packageName,aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=_st((smalltalk.Package || Package))._named_(packageName);
 _st($1)._setupClasses();
 _st($1)._commitPathJs_(_st(_st("/").__comma(aString)).__comma("/js"));
@@ -638,15 +699,18 @@ selector: "loadPackage:prefix:",
 fn: function (packageName,aString){
 var self=this;
 var url;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 url=_st(_st(_st(_st("/").__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
 _st(jQuery)._ajax_options_(url,smalltalk.HashedCollection._fromPairs_([_st("type").__minus_gt("GET"),_st("dataType").__minus_gt("script"),_st("complete").__minus_gt((function(jqXHR,textStatus){
-return smalltalk.withContext(function($ctx2) {
$1=_st(_st(jqXHR)._readyState()).__eq((4));
+return smalltalk.withContext(function($ctx2) {
+$1=_st(_st(jqXHR)._readyState()).__eq((4));
 if(smalltalk.assert($1)){
 return _st(self)._initializePackageNamed_prefix_(packageName,aString);
 };
 }, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})})),_st("error").__minus_gt((function(){
-return smalltalk.withContext(function($ctx2) {
return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
+return smalltalk.withContext(function($ctx2) {
+return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url}, smalltalk.PackageLoader)})},
 messageSends: [",", "ajax:options:", "->", "ifTrue:", "initializePackageNamed:prefix:", "=", "readyState", "alert:"]}),
@@ -658,8 +722,10 @@ smalltalk.method({
 selector: "loadPackages:prefix:",
 fn: function (aCollection,aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(aCollection)._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(self)._loadPackage_prefix_(each,aString);
+return smalltalk.withContext(function($ctx1) { 
+_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._loadPackage_prefix_(each,aString);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackages:prefix:",{aCollection:aCollection,aString:aString}, smalltalk.PackageLoader)})},
 messageSends: ["do:", "loadPackage:prefix:"]}),
@@ -672,7 +738,8 @@ smalltalk.method({
 selector: "loadPackages:prefix:",
 fn: function (aCollection,aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st(_st(self)._new())._loadPackages_prefix_(aCollection,aString);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"loadPackages:prefix:",{aCollection:aCollection,aString:aString}, smalltalk.PackageLoader.klass)})},

+ 141 - 74
js/Importer-Exporter.js

@@ -8,16 +8,19 @@ category: 'reading',
 fn: function (){
 var self=this;
 var char,result,chunk;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
 var $early={};
 try {
 result=_st("")._writeStream();
 _st((function(){
-return smalltalk.withContext(function($ctx2) {
char=_st(self["@stream"])._next();
+return smalltalk.withContext(function($ctx2) {
+char=_st(self["@stream"])._next();
 char;
 return _st(char)._notNil();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
-return smalltalk.withContext(function($ctx2) {
$1=_st(char).__eq("!");
+return smalltalk.withContext(function($ctx2) {
+$1=_st(char).__eq("!");
 if(smalltalk.assert($1)){
 $2=_st(_st(self["@stream"])._peek()).__eq("!");
 if(smalltalk.assert($2)){
@@ -47,7 +50,8 @@ selector: "stream:",
 category: 'accessing',
 fn: function (aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@stream"]=aStream;
+return smalltalk.withContext(function($ctx1) { 
+self["@stream"]=aStream;
 return self}, function($ctx1) {$ctx1.fill(self,"stream:",{aStream:aStream}, smalltalk.ChunkParser)})},
 args: ["aStream"],
 source: "stream: aStream\x0a\x09stream := aStream",
@@ -64,7 +68,8 @@ selector: "on:",
 category: 'not yet classified',
 fn: function (aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st(_st(self)._new())._stream_(aStream);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"on:",{aStream:aStream}, smalltalk.ChunkParser.klass)})},
@@ -84,7 +89,8 @@ selector: "classNameFor:",
 category: 'private',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 if(smalltalk.assert($2)){
 $1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
@@ -112,10 +118,13 @@ selector: "exportAll",
 category: 'fileOut',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st((smalltalk.String || String))._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packages())._do_((function(pkg){
-return smalltalk.withContext(function($ctx3) {
return _st(stream)._nextPutAll_(_st(self)._exportPackage_(_st(pkg)._name()));
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packages())._do_((function(pkg){
+return smalltalk.withContext(function($ctx3) {
+return _st(stream)._nextPutAll_(_st(self)._exportPackage_(_st(pkg)._name()));
 }, function($ctx3) {$ctx3.fillBlock({pkg:pkg},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
@@ -134,9 +143,11 @@ selector: "exportClass:",
 category: 'fileOut',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st((smalltalk.String || String))._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
_st(self)._exportDefinitionOf_on_(aClass,stream);
+return smalltalk.withContext(function($ctx2) {
+_st(self)._exportDefinitionOf_on_(aClass,stream);
 _st(self)._exportMethodsOf_on_(aClass,stream);
 _st(self)._exportMetaDefinitionOf_on_(aClass,stream);
 return _st(self)._exportMethodsOf_on_(_st(aClass)._class(),stream);
@@ -157,16 +168,19 @@ selector: "exportDefinitionOf:on:",
 category: 'private',
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4,$5,$6,$7;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addClass(");
 _st($1)._nextPutAll_(_st(_st("'").__comma(_st(self)._classNameFor_(aClass))).__comma("', "));
 _st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._superclass())));
 $2=_st($1)._nextPutAll_(", [");
 _st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(", ");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(", ");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 $3=aStream;
 _st($3)._nextPutAll_("], '");
@@ -198,7 +212,8 @@ selector: "exportMetaDefinitionOf:on:",
 category: 'private',
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
 $1=_st(_st(_st(aClass)._class())._instanceVariableNames())._isEmpty();
 if(! smalltalk.assert($1)){
 $2=aStream;
@@ -206,9 +221,11 @@ _st($2)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aCla
 $3=_st($2)._nextPutAll_(".iVarNames = [");
 $3;
 _st(_st(_st(aClass)._class())._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(",");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(",");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 _st(aStream)._nextPutAll_(_st("];").__comma(_st((smalltalk.String || String))._lf()));
 };
@@ -227,7 +244,8 @@ selector: "exportMethod:of:on:",
 category: 'private',
 fn: function (aMethod,aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addMethod(");
 _st($1)._lf();
@@ -271,11 +289,14 @@ selector: "exportMethodsOf:on:",
 category: 'private',
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 _st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
$1=_st(_st(each)._category())._match_("^\x5c*");
+return smalltalk.withContext(function($ctx2) {
+$1=_st(_st(each)._category())._match_("^\x5c*");
 if(! smalltalk.assert($1)){
 return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 };
@@ -297,13 +318,16 @@ category: 'fileOut',
 fn: function (packageName){
 var self=this;
 var package_;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st((smalltalk.String || String))._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
package_=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packageAt_(packageName);
+return smalltalk.withContext(function($ctx2) {
+package_=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packageAt_(packageName);
 package_;
 _st(self)._exportPackageDefinitionOf_on_(package_,stream);
 _st(_st(_st(package_)._sortedClasses())._asSet())._do_((function(each){
-return smalltalk.withContext(function($ctx3) {
return _st(stream)._nextPutAll_(_st(self)._exportClass_(each));
+return smalltalk.withContext(function($ctx3) {
+return _st(stream)._nextPutAll_(_st(self)._exportClass_(each));
 }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
 return _st(self)._exportPackageExtensionsOf_on_(package_,stream);
 }, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
@@ -323,15 +347,16 @@ selector: "exportPackageDefinitionOf:on:",
 category: 'private',
 fn: function (package_,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addPackage(");
-$2=_st($1)._nextPutAll_(_st(_st(_st(_st("'").__comma(_st(package_)._name())).__comma("', ")).__comma(_st(package_)._propertiesAsJSON())).__comma(");"));
-_st(aStream)._lf();
+_st($1)._nextPutAll_(_st(_st("'").__comma(_st(package_)._name())).__comma("');"));
+$2=_st($1)._lf();
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{package_:package_,aStream:aStream}, smalltalk.Exporter)})},
 args: ["package", "aStream"],
-source: "exportPackageDefinitionOf: package on: aStream\x0a\x09aStream \x0a\x09    nextPutAll: 'smalltalk.addPackage(';\x0a\x09    nextPutAll: '''', package name, ''', ', package propertiesAsJSON , ');'.\x0a\x09aStream lf",
-messageSends: ["nextPutAll:", ",", "propertiesAsJSON", "name", "lf"],
+source: "exportPackageDefinitionOf: package on: aStream\x0a\x09aStream \x0a\x09    nextPutAll: 'smalltalk.addPackage(';\x0a\x09    nextPutAll: '''', package name, ''');';\x0a        lf",
+messageSends: ["nextPutAll:", ",", "name", "lf"],
 referencedClasses: []
 }),
 smalltalk.Exporter);
@@ -344,14 +369,19 @@ category: 'private',
 fn: function (package_,aStream){
 var self=this;
 var name;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 name=_st(package_)._name();
 _st(_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes()))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st([each,_st(each)._class()])._do_((function(aClass){
-return smalltalk.withContext(function($ctx3) {
return _st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx4) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+return smalltalk.withContext(function($ctx2) {
+return _st([each,_st(each)._class()])._do_((function(aClass){
+return smalltalk.withContext(function($ctx3) {
+return _st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx4) {
+return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
 }, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(method){
-return smalltalk.withContext(function($ctx4) {
$1=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
+return smalltalk.withContext(function($ctx4) {
+$1=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
 if(smalltalk.assert($1)){
 return _st(self)._exportMethod_of_on_(method,aClass,aStream);
 };
@@ -376,7 +406,8 @@ selector: "chunkEscape:",
 category: 'not yet classified',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st(_st(aString)._replace_with_("!","!!"))._trimBoth();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"chunkEscape:",{aString:aString}, smalltalk.ChunkExporter)})},
@@ -394,7 +425,8 @@ selector: "classNameFor:",
 category: 'not yet classified',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 if(smalltalk.assert($2)){
 $1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(" class");
@@ -422,16 +454,19 @@ selector: "exportDefinitionOf:on:",
 category: 'not yet classified',
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4,$5,$6,$7;
 $1=aStream;
 _st($1)._nextPutAll_(_st(self)._classNameFor_(_st(aClass)._superclass()));
 _st($1)._nextPutAll_(_st(" subclass: #").__comma(_st(self)._classNameFor_(aClass)));
 _st($1)._lf();
 $2=_st($1)._nextPutAll_("\x09instanceVariableNames: '");
 _st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(each);
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(" ");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(" ");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 $3=aStream;
 _st($3)._nextPutAll_("'");
@@ -463,7 +498,8 @@ selector: "exportMetaDefinitionOf:on:",
 category: 'not yet classified',
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4,$5;
 $1=_st(_st(_st(aClass)._class())._instanceVariableNames())._isEmpty();
 if(! smalltalk.assert($1)){
 $2=aStream;
@@ -471,9 +507,11 @@ _st($2)._nextPutAll_(_st(self)._classNameFor_(_st(aClass)._class()));
 $3=_st($2)._nextPutAll_(" instanceVariableNames: '");
 $3;
 _st(_st(_st(aClass)._class())._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(each);
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(" ");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(" ");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 $4=aStream;
 _st($4)._nextPutAll_("'!");
@@ -496,7 +534,8 @@ selector: "exportMethod:of:on:",
 category: 'not yet classified',
 fn: function (aMethod,aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=aStream;
 _st($1)._lf();
 _st($1)._lf();
@@ -518,14 +557,17 @@ selector: "exportMethods:category:of:on:",
 category: 'not yet classified',
 fn: function (methods,category,aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4;
 $1=aStream;
 _st($1)._nextPutAll_(_st("!").__comma(_st(self)._classNameFor_(aClass)));
 $2=_st($1)._nextPutAll_(_st(_st(" methodsFor: '").__comma(category)).__comma("'!"));
 _st(_st(methods)._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(self)._exportMethod_of_on_(each,aClass,aStream);
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 $3=aStream;
 _st($3)._nextPutAll_(" !");
@@ -547,19 +589,23 @@ category: 'not yet classified',
 fn: function (aClass,aStream){
 var self=this;
 var map;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 map=_st((smalltalk.Dictionary || Dictionary))._new();
 _st(aClass)._protocolsDo_((function(category,methods){
-return smalltalk.withContext(function($ctx2) {
$1=_st(category)._match_("^\x5c*");
+return smalltalk.withContext(function($ctx2) {
+$1=_st(category)._match_("^\x5c*");
 if(! smalltalk.assert($1)){
 return _st(map)._at_put_(category,methods);
 };
 }, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
 _st(_st(_st(map)._keys())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx2) {
return _st(a).__lt_eq(b);
+return smalltalk.withContext(function($ctx2) {
+return _st(a).__lt_eq(b);
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 var methods;
-return smalltalk.withContext(function($ctx2) {
methods=_st(map)._at_(category);
+return smalltalk.withContext(function($ctx2) {
+methods=_st(map)._at_(category);
 methods;
 return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
 }, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
@@ -578,14 +624,15 @@ selector: "exportPackageDefinitionOf:on:",
 category: 'not yet classified',
 fn: function (package_,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=aStream;
-_st($1)._nextPutAll_(_st(_st(_st(_st("Smalltalk current createPackage: '").__comma(_st(package_)._name())).__comma("' properties: ")).__comma(_st(_st(package_)._properties())._storeString())).__comma("!"));
+_st($1)._nextPutAll_(_st(_st("Smalltalk current createPackage: '").__comma(_st(package_)._name())).__comma("'!"));
 $2=_st($1)._lf();
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{package_:package_,aStream:aStream}, smalltalk.ChunkExporter)})},
 args: ["package", "aStream"],
-source: "exportPackageDefinitionOf: package on: aStream\x0a\x09\x22Chunk format.\x22\x0a\x0a\x09aStream \x0a\x09    nextPutAll: 'Smalltalk current createPackage: ''', package name,\x0a\x09\x09''' properties: ', package properties storeString, '!'; lf.",
-messageSends: ["nextPutAll:", ",", "storeString", "properties", "name", "lf"],
+source: "exportPackageDefinitionOf: package on: aStream\x0a\x09\x22Chunk format.\x22\x0a\x0a\x09aStream \x0a\x09\x09nextPutAll: 'Smalltalk current createPackage: ''', package name, '''!';\x0a\x09\x09lf",
+messageSends: ["nextPutAll:", ",", "name", "lf"],
 referencedClasses: []
 }),
 smalltalk.ChunkExporter);
@@ -598,23 +645,29 @@ category: 'not yet classified',
 fn: function (package_,aStream){
 var self=this;
 var name,map;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 name=_st(package_)._name();
 _st(_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes()))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st([each,_st(each)._class()])._do_((function(aClass){
-return smalltalk.withContext(function($ctx3) {
map=_st((smalltalk.Dictionary || Dictionary))._new();
+return smalltalk.withContext(function($ctx2) {
+return _st([each,_st(each)._class()])._do_((function(aClass){
+return smalltalk.withContext(function($ctx3) {
+map=_st((smalltalk.Dictionary || Dictionary))._new();
 map;
 _st(aClass)._protocolsDo_((function(category,methods){
-return smalltalk.withContext(function($ctx4) {
$1=_st(category)._match_(_st("^\x5c*").__comma(name));
+return smalltalk.withContext(function($ctx4) {
+$1=_st(category)._match_(_st("^\x5c*").__comma(name));
 if(smalltalk.assert($1)){
 return _st(map)._at_put_(category,methods);
 };
 }, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
 return _st(_st(_st(map)._keys())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx4) {
return _st(a).__lt_eq(b);
+return smalltalk.withContext(function($ctx4) {
+return _st(a).__lt_eq(b);
 }, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 var methods;
-return smalltalk.withContext(function($ctx4) {
methods=_st(map)._at_(category);
+return smalltalk.withContext(function($ctx4) {
+methods=_st(map)._at_(category);
 methods;
 return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
 }, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
@@ -638,16 +691,19 @@ selector: "exportDefinitionOf:on:",
 category: 'private',
 fn: function (aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addClass(");
 _st($1)._nextPutAll_(_st(_st("'").__comma(_st(self)._classNameFor_(aClass))).__comma("', "));
 _st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._superclass())));
 $2=_st($1)._nextPutAll_(", [");
 _st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(", ");
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(", ");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 $3=aStream;
 _st($3)._nextPutAll_("], '");
@@ -669,7 +725,8 @@ selector: "exportMethod:of:on:",
 category: 'private',
 fn: function (aMethod,aClass,aStream){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=aStream;
 _st($1)._nextPutAll_("smalltalk.addMethod(");
 _st($1)._lf();
@@ -707,15 +764,18 @@ category: 'fileIn',
 fn: function (aStream){
 var self=this;
 var chunk,result,parser,lastEmpty;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 parser=_st((smalltalk.ChunkParser || ChunkParser))._on_(aStream);
 lastEmpty=false;
 _st((function(){
-return smalltalk.withContext(function($ctx2) {
chunk=_st(parser)._nextChunk();
+return smalltalk.withContext(function($ctx2) {
+chunk=_st(parser)._nextChunk();
 chunk;
 return _st(chunk)._isNil();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileFalse_((function(){
-return smalltalk.withContext(function($ctx2) {
$1=_st(chunk)._isEmpty();
+return smalltalk.withContext(function($ctx2) {
+$1=_st(chunk)._isEmpty();
 if(smalltalk.assert($1)){
 lastEmpty=true;
 return lastEmpty;
@@ -748,7 +808,8 @@ selector: "initializePackageNamed:prefix:",
 category: 'laoding',
 fn: function (packageName,aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 $1=_st((smalltalk.Package || Package))._named_(packageName);
 _st($1)._setupClasses();
 _st($1)._commitPathJs_(_st(_st("/").__comma(aString)).__comma("/js"));
@@ -769,15 +830,18 @@ category: 'laoding',
 fn: function (packageName,aString){
 var self=this;
 var url;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 url=_st(_st(_st(_st("/").__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
 _st(jQuery)._ajax_options_(url,smalltalk.HashedCollection._fromPairs_([_st("type").__minus_gt("GET"),_st("dataType").__minus_gt("script"),_st("complete").__minus_gt((function(jqXHR,textStatus){
-return smalltalk.withContext(function($ctx2) {
$1=_st(_st(jqXHR)._readyState()).__eq((4));
+return smalltalk.withContext(function($ctx2) {
+$1=_st(_st(jqXHR)._readyState()).__eq((4));
 if(smalltalk.assert($1)){
 return _st(self)._initializePackageNamed_prefix_(packageName,aString);
 };
 }, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})})),_st("error").__minus_gt((function(){
-return smalltalk.withContext(function($ctx2) {
return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
+return smalltalk.withContext(function($ctx2) {
+return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url}, smalltalk.PackageLoader)})},
 args: ["packageName", "aString"],
@@ -794,8 +858,10 @@ selector: "loadPackages:prefix:",
 category: 'laoding',
 fn: function (aCollection,aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(aCollection)._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(self)._loadPackage_prefix_(each,aString);
+return smalltalk.withContext(function($ctx1) { 
+_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._loadPackage_prefix_(each,aString);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackages:prefix:",{aCollection:aCollection,aString:aString}, smalltalk.PackageLoader)})},
 args: ["aCollection", "aString"],
@@ -813,7 +879,8 @@ selector: "loadPackages:prefix:",
 category: 'not yet classified',
 fn: function (aCollection,aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
 $1=_st(_st(self)._new())._loadPackages_prefix_(aCollection,aString);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"loadPackages:prefix:",{aCollection:aCollection,aString:aString}, smalltalk.PackageLoader.klass)})},

+ 45 - 13
js/Kernel-Classes.deploy.js

@@ -940,6 +940,21 @@ return self}, function($ctx1) {$ctx1.fill(self,"basicRenameClass:to:",{aClass:aC
 messageSends: []}),
 smalltalk.ClassBuilder);
 
+smalltalk.addMethod(
+"_basicSwapClassNames_with_",
+smalltalk.method({
+selector: "basicSwapClassNames:with:",
+fn: function (aClass,anotherClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+		var tmp = aClass.className;
+		aClass.className = anotherClass.className;
+        anotherClass.className = tmp;
+	;
+return self}, function($ctx1) {$ctx1.fill(self,"basicSwapClassNames:with:",{aClass:aClass,anotherClass:anotherClass}, smalltalk.ClassBuilder)})},
+messageSends: []}),
+smalltalk.ClassBuilder);
+
 smalltalk.addMethod(
 "_class_instanceVariableNames_",
 smalltalk.method({
@@ -1041,28 +1056,45 @@ smalltalk.method({
 selector: "migrateClassNamed:superclass:instanceVariableNames:package:",
 fn: function (aString,aClass,aCollection,packageName){
 var self=this;
-var oldClass,newClass;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+var oldClass,newClass,tmp;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
+tmp=_st("new*").__comma(aString);
 oldClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
-_st(self)._basicRenameClass_to_(oldClass,_st("Old").__comma(aString));
-newClass=_st(self)._addSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
-_st(_st(oldClass)._subclasses())._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(self)._migrateClass_superclass_(each,newClass);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+newClass=_st(self)._addSubclassOf_named_instanceVariableNames_package_(aClass,tmp,aCollection,packageName);
+_st(self)._basicSwapClassNames_with_(oldClass,newClass);
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._copyClass_to_(oldClass,newClass);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_((smalltalk.Error || Error),(function(exception){
 return smalltalk.withContext(function($ctx2) {
$1=self;
-_st($1)._basicRemoveClass_(newClass);
-$2=_st($1)._basicRenameClass_to_(oldClass,aString);
+_st($1)._basicSwapClassNames_with_(oldClass,newClass);
+$2=_st($1)._basicRemoveClass_(newClass);
 $2;
 return _st(exception)._signal();
 }, function($ctx2) {$ctx2.fillBlock({exception:exception},$ctx1)})}));
+$3=self;
+_st($3)._rawRenameClass_to_(oldClass,tmp);
+$4=_st($3)._rawRenameClass_to_(newClass,aString);
+_st(_st(oldClass)._subclasses())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._migrateClass_superclass_(each,newClass);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 _st(self)._basicRemoveClass_(oldClass);
-$3=newClass;
-return $3;
-}, function($ctx1) {$ctx1.fill(self,"migrateClassNamed:superclass:instanceVariableNames:package:",{aString:aString,aClass:aClass,aCollection:aCollection,packageName:packageName,oldClass:oldClass,newClass:newClass}, smalltalk.ClassBuilder)})},
-messageSends: ["at:", "current", "basicRenameClass:to:", ",", "addSubclassOf:named:instanceVariableNames:package:", "do:", "migrateClass:superclass:", "subclasses", "on:do:", "basicRemoveClass:", "signal", "copyClass:to:"]}),
+$5=newClass;
+return $5;
+}, function($ctx1) {$ctx1.fill(self,"migrateClassNamed:superclass:instanceVariableNames:package:",{aString:aString,aClass:aClass,aCollection:aCollection,packageName:packageName,oldClass:oldClass,newClass:newClass,tmp:tmp}, smalltalk.ClassBuilder)})},
+messageSends: [",", "at:", "current", "addSubclassOf:named:instanceVariableNames:package:", "basicSwapClassNames:with:", "on:do:", "basicRemoveClass:", "signal", "copyClass:to:", "rawRenameClass:to:", "do:", "migrateClass:superclass:", "subclasses"]}),
+smalltalk.ClassBuilder);
+
+smalltalk.addMethod(
+"_rawRenameClass_to_",
+smalltalk.method({
+selector: "rawRenameClass:to:",
+fn: function (aClass,aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+		smalltalk[aString] = aClass;
+	;
+return self}, function($ctx1) {$ctx1.fill(self,"rawRenameClass:to:",{aClass:aClass,aString:aString}, smalltalk.ClassBuilder)})},
+messageSends: []}),
 smalltalk.ClassBuilder);
 
 smalltalk.addMethod(

+ 68 - 26
js/Kernel-Classes.js

@@ -1146,7 +1146,7 @@ smalltalk.addMethod(
 "_addSubclassOf_named_instanceVariableNames_package_",
 smalltalk.method({
 selector: "addSubclassOf:named:instanceVariableNames:package:",
-category: 'private',
+category: 'class definition',
 fn: function (aClass,aString,aCollection,packageName){
 var self=this;
 var theClass;
@@ -1264,11 +1264,31 @@ referencedClasses: []
 }),
 smalltalk.ClassBuilder);
 
+smalltalk.addMethod(
+"_basicSwapClassNames_with_",
+smalltalk.method({
+selector: "basicSwapClassNames:with:",
+category: 'private',
+fn: function (aClass,anotherClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+		var tmp = aClass.className;
+		aClass.className = anotherClass.className;
+        anotherClass.className = tmp;
+	;
+return self}, function($ctx1) {$ctx1.fill(self,"basicSwapClassNames:with:",{aClass:aClass,anotherClass:anotherClass}, smalltalk.ClassBuilder)})},
+args: ["aClass", "anotherClass"],
+source: "basicSwapClassNames: aClass with: anotherClass\x0a\x09<\x0a\x09\x09var tmp = aClass.className;\x0a\x09\x09aClass.className = anotherClass.className;\x0a        anotherClass.className = tmp;\x0a\x09>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ClassBuilder);
+
 smalltalk.addMethod(
 "_class_instanceVariableNames_",
 smalltalk.method({
 selector: "class:instanceVariableNames:",
-category: 'api',
+category: 'class definition',
 fn: function (aClass,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2;
@@ -1290,7 +1310,7 @@ smalltalk.addMethod(
 "_copyClass_named_",
 smalltalk.method({
 selector: "copyClass:named:",
-category: 'private',
+category: 'copying',
 fn: function (aClass,aString){
 var self=this;
 var newClass;
@@ -1311,7 +1331,7 @@ smalltalk.addMethod(
 "_copyClass_to_",
 smalltalk.method({
 selector: "copyClass:to:",
-category: 'private',
+category: 'copying',
 fn: function (aClass,anotherClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(anotherClass)._comment_(_st(aClass)._comment());
@@ -1335,7 +1355,7 @@ smalltalk.addMethod(
 "_installMethod_forClass_category_",
 smalltalk.method({
 selector: "installMethod:forClass:category:",
-category: 'api',
+category: 'method definition',
 fn: function (aCompiledMethod,aBehavior,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
@@ -1356,7 +1376,7 @@ smalltalk.addMethod(
 "_instanceVariableNamesFor_",
 smalltalk.method({
 selector: "instanceVariableNamesFor:",
-category: 'private',
+category: 'accessing',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
@@ -1376,7 +1396,7 @@ smalltalk.addMethod(
 "_migrateClass_superclass_",
 smalltalk.method({
 selector: "migrateClass:superclass:",
-category: 'private',
+category: 'class migration',
 fn: function (aClass,anotherClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(console)._log_(_st(aClass)._name());
@@ -1393,42 +1413,64 @@ smalltalk.addMethod(
 "_migrateClassNamed_superclass_instanceVariableNames_package_",
 smalltalk.method({
 selector: "migrateClassNamed:superclass:instanceVariableNames:package:",
-category: 'private',
+category: 'class migration',
 fn: function (aString,aClass,aCollection,packageName){
 var self=this;
-var oldClass,newClass;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+var oldClass,newClass,tmp;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
+tmp=_st("new*").__comma(aString);
 oldClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
-_st(self)._basicRenameClass_to_(oldClass,_st("Old").__comma(aString));
-newClass=_st(self)._addSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
-_st(_st(oldClass)._subclasses())._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
return _st(self)._migrateClass_superclass_(each,newClass);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+newClass=_st(self)._addSubclassOf_named_instanceVariableNames_package_(aClass,tmp,aCollection,packageName);
+_st(self)._basicSwapClassNames_with_(oldClass,newClass);
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._copyClass_to_(oldClass,newClass);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_((smalltalk.Error || Error),(function(exception){
 return smalltalk.withContext(function($ctx2) {
$1=self;
-_st($1)._basicRemoveClass_(newClass);
-$2=_st($1)._basicRenameClass_to_(oldClass,aString);
+_st($1)._basicSwapClassNames_with_(oldClass,newClass);
+$2=_st($1)._basicRemoveClass_(newClass);
 $2;
 return _st(exception)._signal();
 }, function($ctx2) {$ctx2.fillBlock({exception:exception},$ctx1)})}));
+$3=self;
+_st($3)._rawRenameClass_to_(oldClass,tmp);
+$4=_st($3)._rawRenameClass_to_(newClass,aString);
+_st(_st(oldClass)._subclasses())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._migrateClass_superclass_(each,newClass);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 _st(self)._basicRemoveClass_(oldClass);
-$3=newClass;
-return $3;
-}, function($ctx1) {$ctx1.fill(self,"migrateClassNamed:superclass:instanceVariableNames:package:",{aString:aString,aClass:aClass,aCollection:aCollection,packageName:packageName,oldClass:oldClass,newClass:newClass}, smalltalk.ClassBuilder)})},
+$5=newClass;
+return $5;
+}, function($ctx1) {$ctx1.fill(self,"migrateClassNamed:superclass:instanceVariableNames:package:",{aString:aString,aClass:aClass,aCollection:aCollection,packageName:packageName,oldClass:oldClass,newClass:newClass,tmp:tmp}, smalltalk.ClassBuilder)})},
 args: ["aString", "aClass", "aCollection", "packageName"],
-source: "migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName\x0a\x09| oldClass newClass |\x0a    \x0a    oldClass := Smalltalk current at: aString.\x0a    \x0a    \x22Rename the old class for existing instances\x22\x0a\x09self basicRenameClass: oldClass to: 'Old', aString.\x0a    \x0a    newClass := self \x0a\x09\x09addSubclassOf: aClass\x0a\x09\x09named: aString \x0a\x09\x09instanceVariableNames: aCollection\x0a\x09\x09package: packageName.\x0a\x0a\x09oldClass subclasses do: [ :each |\x0a    \x09self migrateClass: each superclass: newClass ].\x0a\x0a    [ self copyClass: oldClass to: newClass ] \x0a    \x09on: Error\x0a        do: [ :exception |\x0a        \x09self \x0a            \x09basicRemoveClass: newClass;\x0a            \x09basicRenameClass: oldClass to: aString.\x0a            exception signal ].\x0a            \x0a    self basicRemoveClass: oldClass.\x0a\x09^newClass",
-messageSends: ["at:", "current", "basicRenameClass:to:", ",", "addSubclassOf:named:instanceVariableNames:package:", "do:", "migrateClass:superclass:", "subclasses", "on:do:", "basicRemoveClass:", "signal", "copyClass:to:"],
+source: "migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName\x0a\x09| oldClass newClass tmp |\x0a    \x0a    tmp := 'new*', aString.\x0a    oldClass := Smalltalk current at: aString.\x0a    \x0a    newClass := self \x0a\x09\x09addSubclassOf: aClass\x0a\x09\x09named: tmp\x0a\x09\x09instanceVariableNames: aCollection\x0a\x09\x09package: packageName.\x0a\x0a\x09self basicSwapClassNames: oldClass with: newClass.\x0a\x0a\x09[ self copyClass: oldClass to: newClass ]\x0a\x09\x09on: Error\x0a\x09\x09do: [ :exception |\x0a\x09\x09\x09self\x0a            \x09basicSwapClassNames: oldClass with: newClass;\x0a            \x09basicRemoveClass: newClass.\x0a            exception signal ].\x0a\x0a\x09self\x0a\x09\x09rawRenameClass: oldClass to: tmp;\x0a        rawRenameClass: newClass to: aString.\x0a\x0a\x09oldClass subclasses do: [ :each |\x0a    \x09self migrateClass: each superclass: newClass ].\x0a\x0a    self basicRemoveClass: oldClass.\x0a\x09^newClass",
+messageSends: [",", "at:", "current", "addSubclassOf:named:instanceVariableNames:package:", "basicSwapClassNames:with:", "on:do:", "basicRemoveClass:", "signal", "copyClass:to:", "rawRenameClass:to:", "do:", "migrateClass:superclass:", "subclasses"],
 referencedClasses: ["Smalltalk", "Error"]
 }),
 smalltalk.ClassBuilder);
 
+smalltalk.addMethod(
+"_rawRenameClass_to_",
+smalltalk.method({
+selector: "rawRenameClass:to:",
+category: 'private',
+fn: function (aClass,aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+		smalltalk[aString] = aClass;
+	;
+return self}, function($ctx1) {$ctx1.fill(self,"rawRenameClass:to:",{aClass:aClass,aString:aString}, smalltalk.ClassBuilder)})},
+args: ["aClass", "aString"],
+source: "rawRenameClass: aClass to: aString\x0a\x09<\x0a\x09\x09smalltalk[aString] = aClass;\x0a\x09>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ClassBuilder);
+
 smalltalk.addMethod(
 "_renameClass_to_",
 smalltalk.method({
 selector: "renameClass:to:",
-category: 'api',
+category: 'class migration',
 fn: function (aClass,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2;
@@ -1449,7 +1491,7 @@ smalltalk.addMethod(
 "_setupClass_",
 smalltalk.method({
 selector: "setupClass:",
-category: 'api',
+category: 'public',
 fn: function (aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
smalltalk.init(aClass);;
@@ -1465,7 +1507,7 @@ smalltalk.addMethod(
 "_superclass_subclass_",
 smalltalk.method({
 selector: "superclass:subclass:",
-category: 'api',
+category: 'class definition',
 fn: function (aClass,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
@@ -1483,7 +1525,7 @@ smalltalk.addMethod(
 "_superclass_subclass_instanceVariableNames_package_",
 smalltalk.method({
 selector: "superclass:subclass:instanceVariableNames:package:",
-category: 'api',
+category: 'class definition',
 fn: function (aClass,aString,aString2,aString3){
 var self=this;
 var newClass;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 323 - 163
js/Kernel-Collections.deploy.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 359 - 158
js/Kernel-Collections.js


+ 16 - 5
js/Kernel-Objects.deploy.js

@@ -2574,11 +2574,11 @@ selector: "commitPathsFromLoader",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-    var cp = smalltalk['@@commitPath'];
-    if (!cp) return;
-    if (cp.js) self._defaultCommitPathJs_(cp.js);
-    if (cp.st) self._defaultCommitPathSt_(cp.st);
-    ;
+	var cp = typeof amber !== 'undefined' && amber.commitPath;
+	if (!cp) return;
+	if (cp.js) self._defaultCommitPathJs_(cp.js);
+	if (cp.st) self._defaultCommitPathSt_(cp.st);
+;
 return self}, function($ctx1) {$ctx1.fill(self,"commitPathsFromLoader",{}, smalltalk.Package.klass)})},
 messageSends: []}),
 smalltalk.Package.klass);
@@ -3250,6 +3250,17 @@ return self}, function($ctx1) {$ctx1.fill(self,"reservedWords",{}, smalltalk.Sma
 messageSends: []}),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+"_version",
+smalltalk.method({
+selector: "version",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return "0.10";
+}, function($ctx1) {$ctx1.fill(self,"version",{}, smalltalk.Smalltalk)})},
+messageSends: []}),
+smalltalk.Smalltalk);
+
 
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.addMethod(

+ 22 - 6
js/Kernel-Objects.js

@@ -3561,14 +3561,14 @@ category: 'commit paths',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-    var cp = smalltalk['@@commitPath'];
-    if (!cp) return;
-    if (cp.js) self._defaultCommitPathJs_(cp.js);
-    if (cp.st) self._defaultCommitPathSt_(cp.st);
-    ;
+	var cp = typeof amber !== 'undefined' && amber.commitPath;
+	if (!cp) return;
+	if (cp.js) self._defaultCommitPathJs_(cp.js);
+	if (cp.st) self._defaultCommitPathSt_(cp.st);
+;
 return self}, function($ctx1) {$ctx1.fill(self,"commitPathsFromLoader",{}, smalltalk.Package.klass)})},
 args: [],
-source: "commitPathsFromLoader\x0a    <\x0a    var cp = smalltalk['@@commitPath'];\x0a    if (!cp) return;\x0a    if (cp.js) self._defaultCommitPathJs_(cp.js);\x0a    if (cp.st) self._defaultCommitPathSt_(cp.st);\x0a    >",
+source: "commitPathsFromLoader\x0a<\x0a\x09var cp = typeof amber !== 'undefined' && amber.commitPath;\x0a\x09if (!cp) return;\x0a\x09if (cp.js) self._defaultCommitPathJs_(cp.js);\x0a\x09if (cp.st) self._defaultCommitPathSt_(cp.st);\x0a>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4474,6 +4474,22 @@ referencedClasses: []
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+"_version",
+smalltalk.method({
+selector: "version",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return "0.10";
+}, function($ctx1) {$ctx1.fill(self,"version",{}, smalltalk.Smalltalk)})},
+args: [],
+source: "version\x0a\x09\x22Answer the version string of Amber\x22\x0a    \x0a    ^ '0.10'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.addMethod(

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 459 - 388
js/Kernel-Tests.deploy.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 461 - 390
js/Kernel-Tests.js


+ 16 - 28
js/amber.js

@@ -21,17 +21,6 @@ amber = (function() {
 	var loadJS;
 	var nocache = '';
 
-	that.toggleIDE = function() {
-		if ($('#amber').length == 0) {
-			smalltalk.Browser._open();
-		} else if ($('#amber').is(':visible')) {
-			smalltalk.TabManager._current()._close();
-		} else {
-			smalltalk.TabManager._current()._open();
-		}
-		return false;
-	};
-
 	that.load = function(obj) {
 		spec = obj || {};
 
@@ -104,14 +93,13 @@ amber = (function() {
 		}
 
 		var additionalFiles = spec.packages || spec.files;
-		var commitPathForInit = null;
 		if (additionalFiles) {
-			commitPathForInit = loadPackages(additionalFiles, spec.prefix, spec.packageHome);
+			that.commitPath = loadPackages(additionalFiles, spec.prefix, spec.packageHome);
 		}
 
 		// Be sure to setup & initialize smalltalk classes
 		addJSToLoad('js/init.js');
-		initializeSmalltalk(commitPathForInit);
+		initializeSmalltalk();
 	};
 
 	function loadPackages(names, prefix, urlHome){
@@ -208,19 +196,15 @@ amber = (function() {
 	}
 
 	// This will be called after JS files have been loaded
-	function initializeSmalltalk(commitPath) {
-		window.smalltalkReady = function() {
-			if (commitPath) {
-				smalltalk['@@commitPath'] = commitPath;
-				smalltalk.Package._commitPathsFromLoader();
-			}
-			if (spec.ready) {
-				spec.ready();
-			}
-			evaluateSmalltalkScripts();
-		};
-
-		loadAllJS();
+	function initializeSmalltalk() {
+		that.smalltalkReady = function() {
+            if (spec.ready) {
+                spec.ready();
+            }
+            evaluateSmalltalkScripts();
+        };
+
+        loadAllJS();
 	}
 
 	/*
@@ -308,4 +292,8 @@ amber = (function() {
 })();
 
 window.loadAmber = amber.load;
-window.toggleAmberIDE = amber.toggleIDE;
+
+// Backward compatibility
+function toggleAmberIDE () {
+    return smalltalk.TabManager._toggleAmberIDE();
+}

+ 2 - 1
js/boot.js

@@ -822,7 +822,8 @@ smalltalk.wrapClassName("Date", "Kernel", Date, smalltalk.Object);
 smalltalk.wrapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object, false);
 
 smalltalk.addClass("Collection", smalltalk.Object, null, "Kernel");
-smalltalk.addClass("SequenceableCollection", smalltalk.Collection, null, "Kernel");
+smalltalk.addClass("IndexableCollection", smalltalk.Collection, null, "Kernel");
+smalltalk.addClass("SequenceableCollection", smalltalk.IndexableCollection, null, "Kernel");
 smalltalk.addClass("CharacterArray", smalltalk.SequenceableCollection, null, "Kernel");
 smalltalk.wrapClassName("String", "Kernel", String, smalltalk.CharacterArray);
 smalltalk.wrapClassName("Symbol", "Kernel", SmalltalkSymbol, smalltalk.CharacterArray, false);

+ 2 - 2
js/init.js

@@ -2,6 +2,6 @@ smalltalk.initialize();
 
 /* Similar to jQuery(document).ready() */
 
-if(this.smalltalkReady) {
-	this.smalltalkReady();
+if(this.amber && this.amber.smalltalkReady) {
+	this.amber.smalltalkReady();
 }

+ 0 - 0
js/lib/es5-shim-2.0.2/.gitignore


+ 0 - 0
js/lib/es5-shim-2.0.2/CHANGES


+ 0 - 0
js/lib/es5-shim-2.0.2/CONTRIBUTORS.md


+ 0 - 0
js/lib/es5-shim-2.0.2/LICENSE


+ 0 - 0
js/lib/es5-shim-2.0.2/README.md


+ 0 - 0
js/lib/es5-shim-2.0.2/es5-sham.js


+ 0 - 0
js/lib/es5-shim-2.0.2/es5-sham.min.js


+ 0 - 0
js/lib/es5-shim-2.0.2/es5-shim.js


+ 0 - 0
js/lib/es5-shim-2.0.2/es5-shim.min.js


+ 0 - 0
js/lib/es5-shim-2.0.2/package.json


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/helpers/h-kill.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/helpers/h-matchers.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/helpers/h.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/index.html


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/lib/jasmine-html.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/lib/jasmine.css


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/lib/jasmine.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/lib/jasmine_favicon.png


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/lib/json2.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/spec/s-array.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/spec/s-date.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/spec/s-function.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/spec/s-object.js


+ 0 - 0
js/lib/es5-shim-2.0.2/tests/spec/s-string.js


+ 0 - 419
js/lib/showdown.js

@@ -1,419 +0,0 @@
-/*
-   A A L        Source code at:
-   T C A   <http://www.attacklab.net/>
-   T K B
-*/
-
-var Showdown={};
-Showdown.converter=function(){
-var _1;
-var _2;
-var _3;
-var _4=0;
-this.makeHtml=function(_5){
-_1=new Array();
-_2=new Array();
-_3=new Array();
-_5=_5.replace(/~/g,"~T");
-_5=_5.replace(/\$/g,"~D");
-_5=_5.replace(/\r\n/g,"\n");
-_5=_5.replace(/\r/g,"\n");
-_5="\n\n"+_5+"\n\n";
-_5=_6(_5);
-_5=_5.replace(/^[ \t]+$/mg,"");
-_5=_7(_5);
-_5=_8(_5);
-_5=_9(_5);
-_5=_a(_5);
-_5=_5.replace(/~D/g,"$$");
-_5=_5.replace(/~T/g,"~");
-return _5;
-};
-var _8=function(_b){
-var _b=_b.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,function(_c,m1,m2,m3,m4){
-m1=m1.toLowerCase();
-_1[m1]=_11(m2);
-if(m3){
-return m3+m4;
-}else{
-if(m4){
-_2[m1]=m4.replace(/"/g,"&quot;");
-}
-}
-return "";
-});
-return _b;
-};
-var _7=function(_12){
-_12=_12.replace(/\n/g,"\n\n");
-var _13="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del";
-var _14="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math";
-_12=_12.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,_15);
-_12=_12.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,_15);
-_12=_12.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,_15);
-_12=_12.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,_15);
-_12=_12.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,_15);
-_12=_12.replace(/\n\n/g,"\n");
-return _12;
-};
-var _15=function(_16,m1){
-var _18=m1;
-_18=_18.replace(/\n\n/g,"\n");
-_18=_18.replace(/^\n/,"");
-_18=_18.replace(/\n+$/g,"");
-_18="\n\n~K"+(_3.push(_18)-1)+"K\n\n";
-return _18;
-};
-var _9=function(_19){
-_19=_1a(_19);
-var key=_1c("<hr />");
-_19=_19.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key);
-_19=_19.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key);
-_19=_19.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key);
-_19=_1d(_19);
-_19=_1e(_19);
-_19=_1f(_19);
-_19=_7(_19);
-_19=_20(_19);
-return _19;
-};
-var _21=function(_22){
-_22=_23(_22);
-_22=_24(_22);
-_22=_25(_22);
-_22=_26(_22);
-_22=_27(_22);
-_22=_28(_22);
-_22=_11(_22);
-_22=_29(_22);
-_22=_22.replace(/  +\n/g," <br />\n");
-return _22;
-};
-var _24=function(_2a){
-var _2b=/(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;
-_2a=_2a.replace(_2b,function(_2c){
-var tag=_2c.replace(/(.)<\/?code>(?=.)/g,"$1`");
-tag=_2e(tag,"\\`*_");
-return tag;
-});
-return _2a;
-};
-var _27=function(_2f){
-_2f=_2f.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,_30);
-_2f=_2f.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,_30);
-_2f=_2f.replace(/(\[([^\[\]]+)\])()()()()()/g,_30);
-return _2f;
-};
-var _30=function(_31,m1,m2,m3,m4,m5,m6,m7){
-if(m7==undefined){
-m7="";
-}
-var _39=m1;
-var _3a=m2;
-var _3b=m3.toLowerCase();
-var url=m4;
-var _3d=m7;
-if(url==""){
-if(_3b==""){
-_3b=_3a.toLowerCase().replace(/ ?\n/g," ");
-}
-url="#"+_3b;
-if(_1[_3b]!=undefined){
-url=_1[_3b];
-if(_2[_3b]!=undefined){
-_3d=_2[_3b];
-}
-}else{
-if(_39.search(/\(\s*\)$/m)>-1){
-url="";
-}else{
-return _39;
-}
-}
-}
-url=_2e(url,"*_");
-var _3e="<a href=\""+url+"\"";
-if(_3d!=""){
-_3d=_3d.replace(/"/g,"&quot;");
-_3d=_2e(_3d,"*_");
-_3e+=" title=\""+_3d+"\"";
-}
-_3e+=">"+_3a+"</a>";
-return _3e;
-};
-var _26=function(_3f){
-_3f=_3f.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,_40);
-_3f=_3f.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,_40);
-return _3f;
-};
-var _40=function(_41,m1,m2,m3,m4,m5,m6,m7){
-var _49=m1;
-var _4a=m2;
-var _4b=m3.toLowerCase();
-var url=m4;
-var _4d=m7;
-if(!_4d){
-_4d="";
-}
-if(url==""){
-if(_4b==""){
-_4b=_4a.toLowerCase().replace(/ ?\n/g," ");
-}
-url="#"+_4b;
-if(_1[_4b]!=undefined){
-url=_1[_4b];
-if(_2[_4b]!=undefined){
-_4d=_2[_4b];
-}
-}else{
-return _49;
-}
-}
-_4a=_4a.replace(/"/g,"&quot;");
-url=_2e(url,"*_");
-var _4e="<img src=\""+url+"\" alt=\""+_4a+"\"";
-_4d=_4d.replace(/"/g,"&quot;");
-_4d=_2e(_4d,"*_");
-_4e+=" title=\""+_4d+"\"";
-_4e+=" />";
-return _4e;
-};
-var _1a=function(_4f){
-_4f=_4f.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,function(_50,m1){
-return _1c("<h1>"+_21(m1)+"</h1>");
-});
-_4f=_4f.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,function(_52,m1){
-return _1c("<h2>"+_21(m1)+"</h2>");
-});
-_4f=_4f.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,function(_54,m1,m2){
-var _57=m1.length;
-return _1c("<h"+_57+">"+_21(m2)+"</h"+_57+">");
-});
-return _4f;
-};
-var _58;
-var _1d=function(_59){
-_59+="~0";
-var _5a=/^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
-if(_4){
-_59=_59.replace(_5a,function(_5b,m1,m2){
-var _5e=m1;
-var _5f=(m2.search(/[*+-]/g)>-1)?"ul":"ol";
-_5e=_5e.replace(/\n{2,}/g,"\n\n\n");
-var _60=_58(_5e);
-_60=_60.replace(/\s+$/,"");
-_60="<"+_5f+">"+_60+"</"+_5f+">\n";
-return _60;
-});
-}else{
-_5a=/(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
-_59=_59.replace(_5a,function(_61,m1,m2,m3){
-var _65=m1;
-var _66=m2;
-var _67=(m3.search(/[*+-]/g)>-1)?"ul":"ol";
-var _66=_66.replace(/\n{2,}/g,"\n\n\n");
-var _68=_58(_66);
-_68=_65+"<"+_67+">\n"+_68+"</"+_67+">\n";
-return _68;
-});
-}
-_59=_59.replace(/~0/,"");
-return _59;
-};
-_58=function(_69){
-_4++;
-_69=_69.replace(/\n{2,}$/,"\n");
-_69+="~0";
-_69=_69.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,function(_6a,m1,m2,m3,m4){
-var _6f=m4;
-var _70=m1;
-var _71=m2;
-if(_70||(_6f.search(/\n{2,}/)>-1)){
-_6f=_9(_72(_6f));
-}else{
-_6f=_1d(_72(_6f));
-_6f=_6f.replace(/\n$/,"");
-_6f=_21(_6f);
-}
-return "<li>"+_6f+"</li>\n";
-});
-_69=_69.replace(/~0/g,"");
-_4--;
-return _69;
-};
-var _1e=function(_73){
-_73+="~0";
-_73=_73.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,function(_74,m1,m2){
-var _77=m1;
-var _78=m2;
-_77=_79(_72(_77));
-_77=_6(_77);
-_77=_77.replace(/^\n+/g,"");
-_77=_77.replace(/\n+$/g,"");
-_77="<pre><code>"+_77+"\n</code></pre>";
-return _1c(_77)+_78;
-});
-_73=_73.replace(/~0/,"");
-return _73;
-};
-var _1c=function(_7a){
-_7a=_7a.replace(/(^\n+|\n+$)/g,"");
-return "\n\n~K"+(_3.push(_7a)-1)+"K\n\n";
-};
-var _23=function(_7b){
-_7b=_7b.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(_7c,m1,m2,m3,m4){
-var c=m3;
-c=c.replace(/^([ \t]*)/g,"");
-c=c.replace(/[ \t]*$/g,"");
-c=_79(c);
-return m1+"<code>"+c+"</code>";
-});
-return _7b;
-};
-var _79=function(_82){
-_82=_82.replace(/&/g,"&amp;");
-_82=_82.replace(/</g,"&lt;");
-_82=_82.replace(/>/g,"&gt;");
-_82=_2e(_82,"*_{}[]\\",false);
-return _82;
-};
-var _29=function(_83){
-_83=_83.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,"<strong>$2</strong>");
-_83=_83.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,"<em>$2</em>");
-return _83;
-};
-var _1f=function(_84){
-_84=_84.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,function(_85,m1){
-var bq=m1;
-bq=bq.replace(/^[ \t]*>[ \t]?/gm,"~0");
-bq=bq.replace(/~0/g,"");
-bq=bq.replace(/^[ \t]+$/gm,"");
-bq=_9(bq);
-bq=bq.replace(/(^|\n)/g,"$1  ");
-bq=bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm,function(_88,m1){
-var pre=m1;
-pre=pre.replace(/^  /mg,"~0");
-pre=pre.replace(/~0/g,"");
-return pre;
-});
-return _1c("<blockquote>\n"+bq+"\n</blockquote>");
-});
-return _84;
-};
-var _20=function(_8b){
-_8b=_8b.replace(/^\n+/g,"");
-_8b=_8b.replace(/\n+$/g,"");
-var _8c=_8b.split(/\n{2,}/g);
-var _8d=new Array();
-var end=_8c.length;
-for(var i=0;i<end;i++){
-var str=_8c[i];
-if(str.search(/~K(\d+)K/g)>=0){
-_8d.push(str);
-}else{
-if(str.search(/\S/)>=0){
-str=_21(str);
-str=str.replace(/^([ \t]*)/g,"<p>");
-str+="</p>";
-_8d.push(str);
-}
-}
-}
-end=_8d.length;
-for(var i=0;i<end;i++){
-while(_8d[i].search(/~K(\d+)K/)>=0){
-var _91=_3[RegExp.$1];
-_91=_91.replace(/\$/g,"$$$$");
-_8d[i]=_8d[i].replace(/~K\d+K/,_91);
-}
-}
-return _8d.join("\n\n");
-};
-var _11=function(_92){
-_92=_92.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&amp;");
-_92=_92.replace(/<(?![a-z\/?\$!])/gi,"&lt;");
-return _92;
-};
-var _25=function(_93){
-_93=_93.replace(/\\(\\)/g,_94);
-_93=_93.replace(/\\([`*_{}\[\]()>#+-.!])/g,_94);
-return _93;
-};
-var _28=function(_95){
-_95=_95.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
-_95=_95.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,function(_96,m1){
-return _98(_a(m1));
-});
-return _95;
-};
-var _98=function(_99){
-function char2hex(ch){
-var _9b="0123456789ABCDEF";
-var dec=ch.charCodeAt(0);
-return (_9b.charAt(dec>>4)+_9b.charAt(dec&15));
-}
-var _9d=[function(ch){
-return "&#"+ch.charCodeAt(0)+";";
-},function(ch){
-return "&#x"+char2hex(ch)+";";
-},function(ch){
-return ch;
-}];
-_99="mailto:"+_99;
-_99=_99.replace(/./g,function(ch){
-if(ch=="@"){
-ch=_9d[Math.floor(Math.random()*2)](ch);
-}else{
-if(ch!=":"){
-var r=Math.random();
-ch=(r>0.9?_9d[2](ch):r>0.45?_9d[1](ch):_9d[0](ch));
-}
-}
-return ch;
-});
-_99="<a href=\""+_99+"\">"+_99+"</a>";
-_99=_99.replace(/">.+:/g,"\">");
-return _99;
-};
-var _a=function(_a3){
-_a3=_a3.replace(/~E(\d+)E/g,function(_a4,m1){
-var _a6=parseInt(m1);
-return String.fromCharCode(_a6);
-});
-return _a3;
-};
-var _72=function(_a7){
-_a7=_a7.replace(/^(\t|[ ]{1,4})/gm,"~0");
-_a7=_a7.replace(/~0/g,"");
-return _a7;
-};
-var _6=function(_a8){
-_a8=_a8.replace(/\t(?=\t)/g,"    ");
-_a8=_a8.replace(/\t/g,"~A~B");
-_a8=_a8.replace(/~B(.+?)~A/g,function(_a9,m1,m2){
-var _ac=m1;
-var _ad=4-_ac.length%4;
-for(var i=0;i<_ad;i++){
-_ac+=" ";
-}
-return _ac;
-});
-_a8=_a8.replace(/~A/g,"    ");
-_a8=_a8.replace(/~B/g,"");
-return _a8;
-};
-var _2e=function(_af,_b0,_b1){
-var _b2="(["+_b0.replace(/([\[\]\\])/g,"\\$1")+"])";
-if(_b1){
-_b2="\\\\"+_b2;
-}
-var _b3=new RegExp(_b2,"g");
-_af=_af.replace(_b3,_94);
-return _af;
-};
-var _94=function(_b4,m1){
-var _b6=m1.charCodeAt(0);
-return "~E"+_b6+"E";
-};
-};
-if(typeof exports!='undefined')exports.Showdown=Showdown;

+ 0 - 40
learn.html

@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-    <title>Learn Smalltalk with ProfStef</title>
-    <link href='http://fonts.googleapis.com/css?family=Istok+Web' rel='stylesheet' type='text/css'> 
-    <meta name="author" content="Nicolas Petton">
-    <link rel="stylesheet" type="text/css" href="css/profstef.css">
-    <script type="text/javascript" src="js/amber.js"></script>
-  </head>
-  <body>
-
-    <div class="main">
-      <a id="back" href="./index.html"> &larr; back to main page </a>
-      <img src="images/profstef.png"/>
-      <h1>Hey there! Got 5 minutes? I'm prof Stef and I want to teach you Smalltalk. I promise, it won't take long!</h1> 
-      
-      <div id="tutorial"><h2>Loading...</h2></div>
-      <script> 
-	function loadTutorial() {
-		jQuery('#tutorial').empty();
-		smalltalk.TrySmalltalkWidget._new()._appendToJQuery_(jQuery('#tutorial'));
-	}
-      </script>
-    </div>
-    
-    <div id="footer">
-      <div class="main">
-	<p>Copyright © 2011 <a href="http://www.nicolas-petton.fr/">Nicolas Petton</a>. The content of this website in licensed under <a href="http://creativecommons.org/licenses/by-nc/3.0/">CC-BY-NC 3.0</a>.</p>
-	<p>Amber is an opensource project sponsored by <a href="http://www.objectfusion.fr/">objectfusion</a>.</p>
-      </div> 
-    </div>
-
-    <script type="text/javascript">
-      loadAmber({files: ['TrySmalltalk.js'], prefix: 'examples/trysmalltalk/js', ready: loadTutorial});
-    </script>    
-
-
-  </body>
-</html>

+ 34 - 34
repl/REPL.js

@@ -7,8 +7,8 @@ selector: "close",
 category: 'actions',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(process,"_stdin",[]),"_destroy",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(process)._stdin())._destroy();
+return self}, function($ctx1) {$ctx1.fill(self,"close",{}, smalltalk.Repl)})},
 args: [],
 source: "close\x0a\x09process stdin destroy",
 messageSends: ["destroy", "stdin"],
@@ -23,16 +23,16 @@ selector: "createInterface",
 category: 'actions',
 fn: function (){
 var self=this;
-self["@interface"]=smalltalk.send(self["@readline"],"_createInterface_stdout_",[smalltalk.send(process,"_stdin",[]),smalltalk.send(process,"_stdout",[])]);
-smalltalk.send(self["@interface"],"_on_do_",["line",(function(buffer){
-return smalltalk.send(self,"_eval_",[buffer]);
-})]);
-smalltalk.send(self["@interface"],"_on_do_",["close",(function(){
-return smalltalk.send(self,"_close",[]);
-})]);
-smalltalk.send(self,"_setPrompt",[]);
-smalltalk.send(self["@interface"],"_prompt",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@interface"]=_st(self["@readline"])._createInterface_stdout_(_st(process)._stdin(),_st(process)._stdout());
+_st(self["@interface"])._on_do_("line",(function(buffer){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._eval_(buffer);
+}, function($ctx2) {$ctx2.fillBlock({buffer:buffer},$ctx1)})}));
+_st(self["@interface"])._on_do_("close",(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._close();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(self)._setPrompt();
+_st(self["@interface"])._prompt();
+return self}, function($ctx1) {$ctx1.fill(self,"createInterface",{}, smalltalk.Repl)})},
 args: [],
 source: "createInterface\x0a\x09\x22No completion for now\x22\x0a\x09interface := readline createInterface: process stdin stdout: process stdout.\x0a\x09interface on: 'line' do: [:buffer  | self eval: buffer].\x0a\x09interface on: 'close' do: [self close].\x0a\x09self setPrompt.\x0a\x09interface prompt",
 messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "eval:", "close", "setPrompt", "prompt"],
@@ -47,25 +47,25 @@ selector: "eval:",
 category: 'actions',
 fn: function (buffer){
 var self=this;
-var $1,$2;
 var result;
-$1=smalltalk.send(buffer,"_isEmpty",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(buffer)._isEmpty();
 if(! smalltalk.assert($1)){
-smalltalk.send(self,"_try_catch_",[(function(){
-result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler),"_new",[]),"_evaluateExpression_",[buffer]);
+_st(self)._try_catch_((function(){
+return smalltalk.withContext(function($ctx2) {
result=_st(_st((smalltalk.Compiler || Compiler))._new())._evaluateExpression_(buffer);
 result;
-return smalltalk.send((smalltalk.Transcript || Transcript),"_show_",[result]);
-}),(function(e){
-$2=smalltalk.send(e,"_isSmalltalkError",[]);
+return _st((smalltalk.Transcript || Transcript))._show_(result);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(function(e){
+return smalltalk.withContext(function($ctx2) {
$2=_st(e)._isSmalltalkError();
 if(smalltalk.assert($2)){
-return smalltalk.send(smalltalk.send((smalltalk.ErrorHandler || ErrorHandler),"_new",[]),"_handleError_",[e]);
+return _st(_st((smalltalk.ErrorHandler || ErrorHandler))._new())._handleError_(e);
 } else {
-return smalltalk.send(smalltalk.send(process,"_stdout",[]),"_write_",[smalltalk.send(e,"_jsStack",[])]);
+return _st(_st(process)._stdout())._write_(_st(e)._jsStack());
 };
-})]);
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
 };
-smalltalk.send(self["@interface"],"_prompt",[]);
-return self},
+_st(self["@interface"])._prompt();
+return self}, function($ctx1) {$ctx1.fill(self,"eval:",{buffer:buffer,result:result}, smalltalk.Repl)})},
 args: ["buffer"],
 source: "eval: buffer\x0a\x09| result |\x0a\x09buffer isEmpty ifFalse: [\x0a\x09\x09self try: [\x0a\x09\x09\x09result := Compiler new evaluateExpression: buffer.\x0a\x09\x09\x09Transcript show: result]\x0a\x09\x09catch: [:e |\x0a\x09\x09\x09e isSmalltalkError\x0a\x09\x09\x09    ifTrue: [ErrorHandler new handleError: e]\x0a\x09\x09\x09    ifFalse: [process stdout write: e jsStack]]].\x0a\x09interface prompt",
 messageSends: ["ifFalse:", "try:catch:", "evaluateExpression:", "new", "show:", "ifTrue:ifFalse:", "handleError:", "write:", "jsStack", "stdout", "isSmalltalkError", "isEmpty", "prompt"],
@@ -80,10 +80,10 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_initialize",[],smalltalk.Object);
-self["@readline"]=smalltalk.send(require,"_value_",["readline"]);
-self["@util"]=smalltalk.send(require,"_value_",["util"]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@readline"]=_st(require)._value_("readline");
+self["@util"]=_st(require)._value_("util");
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.Repl)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a\x09readline := require value: 'readline'.\x0a\x09util := require value: 'util'",
 messageSends: ["initialize", "value:"],
@@ -98,8 +98,8 @@ selector: "prompt",
 category: 'accessing',
 fn: function (){
 var self=this;
-return "amber >> ";
-},
+return smalltalk.withContext(function($ctx1) { 
return "amber >> ";
+}, function($ctx1) {$ctx1.fill(self,"prompt",{}, smalltalk.Repl)})},
 args: [],
 source: "prompt\x0a\x09^'amber >> '",
 messageSends: [],
@@ -114,8 +114,8 @@ selector: "setPrompt",
 category: 'actions',
 fn: function (){
 var self=this;
-smalltalk.send(self["@interface"],"_setPrompt_",[smalltalk.send(self,"_prompt",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self["@interface"])._setPrompt_(_st(self)._prompt());
+return self}, function($ctx1) {$ctx1.fill(self,"setPrompt",{}, smalltalk.Repl)})},
 args: [],
 source: "setPrompt\x0a\x09interface setPrompt: self prompt",
 messageSends: ["setPrompt:", "prompt"],
@@ -131,8 +131,8 @@ selector: "main",
 category: 'not yet classified',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_new",[]),"_createInterface",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._new())._createInterface();
+return self}, function($ctx1) {$ctx1.fill(self,"main",{}, smalltalk.Repl.klass)})},
 args: [],
 source: "main\x0a\x09self new createInterface",
 messageSends: ["createInterface", "new"],

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 436 - 258
repl/amber.js


+ 8 - 4
server/FileServer.st

@@ -67,7 +67,11 @@ writeData: data toFileNamed: aFilename
 	console log: aFilename
 !
 
-isAuthenticated: aRequest response: aResponse
+base64Decode: aString
+	<return (new Buffer(aString, 'base64').toString())>
+!
+
+isAuthenticated: aRequest
 	"Basic HTTP Auth: http://stackoverflow.com/a/5957629/293175
 	 and https://gist.github.com/1686663"
 	| header token auth parts|
@@ -82,7 +86,7 @@ isAuthenticated: aRequest response: aResponse
 		"get authentication token"
 		token := (header tokenize: ' ') ifNil:[''].
 		"convert back from base64"
-		<auth = new Buffer(token[1], 'base64').toString()>.
+		auth := self base64Decode: (token at: 2).
 		"split token at colon"
 		parts := auth tokenize: ':'.
 
@@ -115,8 +119,8 @@ handleGETRequest: aRequest respondTo: aResponse
 
 handlePUTRequest: aRequest respondTo: aResponse
 	| file stream |
-	(self isAuthenticated: aRequest response: aResponse)
-		ifFalse: [self respondAuthenticationRequiredTo: aResponse].
+	(self isAuthenticated: aRequest)
+		ifFalse: [self respondAuthenticationRequiredTo: aResponse. ^nil].
 
 	file := '.', aRequest url.
 	stream := fs createWriteStream: file.

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 437 - 259
server/server.js


+ 1 - 1
st/Benchfib.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Benchfib' properties: #{}!
+Smalltalk current createPackage: 'Benchfib'!
 Object subclass: #Benchfib
 	instanceVariableNames: ''
 	package: 'Benchfib'!

+ 1 - 1
st/Canvas.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Canvas' properties: #{}!
+Smalltalk current createPackage: 'Canvas'!
 Object subclass: #HTMLCanvas
 	instanceVariableNames: 'root'
 	package: 'Canvas'!

+ 1 - 1
st/Compiler-AST.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-AST' properties: #{}!
+Smalltalk current createPackage: 'Compiler-AST'!
 Object subclass: #Node
 	instanceVariableNames: 'position nodes shouldBeInlined shouldBeAliased'
 	package: 'Compiler-AST'!

+ 1 - 1
st/Compiler-Core.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Core' properties: #{}!
+Smalltalk current createPackage: 'Compiler-Core'!
 Object subclass: #Compiler
 	instanceVariableNames: 'currentClass source unknownVariables codeGeneratorClass'
 	package: 'Compiler-Core'!

+ 1 - 1
st/Compiler-Exceptions.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Exceptions' properties: #{}!
+Smalltalk current createPackage: 'Compiler-Exceptions'!
 Error subclass: #CompilerError
 	instanceVariableNames: ''
 	package: 'Compiler-Exceptions'!

+ 1 - 1
st/Compiler-IR.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-IR' properties: #{}!
+Smalltalk current createPackage: 'Compiler-IR'!
 NodeVisitor subclass: #IRASTTranslator
 	instanceVariableNames: 'source theClass method sequence nextAlias'
 	package: 'Compiler-IR'!

+ 1 - 1
st/Compiler-Inlining.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Inlining' properties: #{}!
+Smalltalk current createPackage: 'Compiler-Inlining'!
 IRAssignment subclass: #IRInlinedAssignment
 	instanceVariableNames: ''
 	package: 'Compiler-Inlining'!

+ 1 - 1
st/Compiler-Interpreter.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Interpreter' properties: #{}!
+Smalltalk current createPackage: 'Compiler-Interpreter'!
 NodeVisitor subclass: #AIContext
 	instanceVariableNames: 'outerContext pc locals method'
 	package: 'Compiler-Interpreter'!

+ 1 - 1
st/Compiler-Semantic.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Semantic' properties: #{}!
+Smalltalk current createPackage: 'Compiler-Semantic'!
 Object subclass: #LexicalScope
 	instanceVariableNames: 'node instruction temps args outerScope'
 	package: 'Compiler-Semantic'!

+ 1 - 1
st/Compiler-Tests.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Tests' properties: #{}!
+Smalltalk current createPackage: 'Compiler-Tests'!
 TestCase subclass: #AbstractASTInterpreterTest
 	instanceVariableNames: ''
 	package: 'Compiler-Tests'!

+ 652 - 118
st/Compiler.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler' properties: #{}!
+Smalltalk current createPackage: 'Compiler'!
 Object subclass: #ChunkParser
 	instanceVariableNames: 'stream'
 	package:'Compiler'!
@@ -155,8 +155,8 @@ exportMethodsOf: aClass on: aStream
 exportPackageDefinitionOf: package on: aStream
 	aStream 
 	    nextPutAll: 'smalltalk.addPackage(';
-	    nextPutAll: '''', package name, ''', ', package propertiesAsJSON , ');'.
-	aStream lf
+	    nextPutAll: '''', package name, ''');';
+        lf
 !
 
 exportPackageExtensionsOf: package on: aStream
@@ -262,8 +262,8 @@ exportPackageDefinitionOf: package on: aStream
 	"Chunk format."
 
 	aStream 
-	    nextPutAll: 'Smalltalk current createPackage: ''', package name,
-		''' properties: ', package properties storeString, '!!'; lf.
+		nextPutAll: 'Smalltalk current createPackage: ''', package name, '''!!';
+		lf
 !
 
 exportPackageExtensionsOf: package on: aStream
@@ -313,7 +313,8 @@ exportMethod: aMethod of: aClass on: aStream
 		nextPutAll: aMethod selector asSelector asJavascript, ',';lf;
 		nextPutAll: 'smalltalk.method({';lf;
 		nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;
-		nextPutAll: 'fn: ', aMethod fn compiledSource;lf;
+		nextPutAll: 'fn: ', aMethod fn compiledSource, ',';lf;
+		nextPutAll: 'messageSends: ', aMethod messageSends asJavascript;
 		nextPutAll: '}),';lf;
 		nextPutAll: 'smalltalk.', (self classNameFor: aClass);
 		nextPutAll: ');';lf;lf
@@ -459,6 +460,10 @@ The default behavior is to allow it, as this is how Amber currently is able to s
 
 !UnknownVariableError methodsFor: '*Compiler'!
 
+messageText
+	^ 'Unknown Variable error: ', self variableName, ' is not defined'
+!
+
 variableName
 	^ variableName
 !
@@ -467,6 +472,25 @@ variableName: aString
 	variableName := aString
 ! !
 
+ErrorHandler subclass: #RethrowErrorHandler
+	instanceVariableNames: ''
+	package:'Compiler'!
+!RethrowErrorHandler commentStamp!
+This class is used in the commandline version of the compiler.
+It uses the handleError: message of ErrorHandler for printing the stacktrace and throws the error again as JS exception.
+As a result Smalltalk errors are not swallowd by the Amber runtime and compilation can be aborted.!
+
+!RethrowErrorHandler methodsFor: '*Compiler'!
+
+basicSignal: anError
+	<throw anError>
+!
+
+handleError: anError
+	super handleError: anError.
+    self basicSignal: anError
+! !
+
 Object subclass: #Compiler
 	instanceVariableNames: 'currentClass source unknownVariables codeGeneratorClass'
 	package:'Compiler'!
@@ -553,12 +577,10 @@ evaluateExpression: aString
 !
 
 install: aString forClass: aBehavior category: anotherString
-	| compiled |
-	compiled := self eval: (self compile: aString forClass: aBehavior).
-	compiled category: anotherString.
-	aBehavior addCompiledMethod: compiled.
-    self setupClass: aBehavior.
-	^compiled
+   	^ ClassBuilder new
+    	installMethod: (self eval: (self compile: aString forClass: aBehavior))
+        forClass: aBehavior
+        category: anotherString
 !
 
 parse: aString
@@ -573,7 +595,7 @@ recompile: aClass
 	aClass methodDictionary do: [:each |
 		console log: aClass name, ' >> ', each selector.
 		self install: each source forClass: aClass category: each category].
-	self setupClass: aClass.
+	"self setupClass: aClass."
 	aClass isMetaclass ifFalse: [self recompile: aClass class]
 !
 
@@ -581,10 +603,6 @@ recompileAll
 	Smalltalk current classes do: [:each |
 		Transcript show: each; cr.
 		[self recompile: each] valueWithTimeout: 100]
-!
-
-setupClass: aClass
-	<smalltalk.init(aClass)>
 ! !
 
 !Compiler class methodsFor: '*Compiler'!
@@ -617,7 +635,7 @@ visit: aNode
 !
 
 visitAll: aCollection
-	^ aCollection do: [ :each | self visit: each ]
+	^ aCollection collect: [ :each | self visit: each ]
 !
 
 visitAssignmentNode: aNode
@@ -828,6 +846,10 @@ isImmutable
 	^false
 !
 
+isNode
+	^ true
+!
+
 isReturnNode
 	^false
 !
@@ -915,6 +937,10 @@ scope: aLexicalScope
 
 isBlockNode
 	^true
+!
+
+subtreeNeedsAliasing
+    ^ self shouldBeAliased or: [ self shouldBeInlined ]
 ! !
 
 !BlockNode methodsFor: '*Compiler'!
@@ -1303,6 +1329,12 @@ accept: aVisitor
 	^ aVisitor visitClassReferenceNode: self
 ! !
 
+!Object methodsFor: '*Compiler'!
+
+isNode
+	^ false
+! !
+
 Object subclass: #LexicalScope
 	instanceVariableNames: 'node instruction temps args outerScope'
 	package:'Compiler'!
@@ -1663,12 +1695,6 @@ I am an temporary variable of a method or block.!
 
 !TempVar methodsFor: '*Compiler'!
 
-alias
-	^ self scope alias, '.locals.', super alias
-! !
-
-!TempVar methodsFor: '*Compiler'!
-
 isTempVar
 	^ true
 ! !
@@ -1722,16 +1748,24 @@ errorShadowingVariable: aString
 !
 
 errorUnknownVariable: aNode
-	"Throw an error if the variable is undeclared in the global JS scope (i.e. window)"
+	"Throw an error if the variable is undeclared in the global JS scope (i.e. window).
+    We allow four variable names in addition: `jQuery`, `window`, `process` and `global` 
+    for nodejs and browser environments. 
+    
+    This is only to make sure compilation works on both browser-based and nodejs environments.
+    The ideal solution would be to use a pragma instead"
 
 	| identifier |
     identifier := aNode value.
-	((#('jQuery' 'window' 'process' 'global') includes: identifier) not and: [ self isVariableGloballyUndefined: identifier ]) ifTrue: [
-			UnknownVariableError new
-				variableName: aNode value;
-				signal ]
-		ifFalse: [
-			currentScope methodScope unknownVariables add: aNode value. ]
+    
+	((#('jQuery' 'window' 'document' 'process' 'global') includes: identifier) not 
+        and: [ self isVariableGloballyUndefined: identifier ]) 
+        	ifTrue: [
+				UnknownVariableError new
+					variableName: aNode value;
+					signal ]
+			ifFalse: [
+				currentScope methodScope unknownVariables add: aNode value ]
 ! !
 
 !SemanticAnalyzer methodsFor: '*Compiler'!
@@ -2148,6 +2182,10 @@ instructions
 	^ instructions ifNil: [ instructions := OrderedCollection new ]
 !
 
+method
+	^ self parent method
+!
+
 parent
 	^ parent
 !
@@ -2200,6 +2238,10 @@ isLocalReturn
 	^ false
 !
 
+isMethod
+	^ false
+!
+
 isReturn
 	^ false
 !
@@ -2278,11 +2320,11 @@ scope: aScope
 	scope := aScope
 ! !
 
-IRScopedInstruction subclass: #IRClosure
+IRScopedInstruction subclass: #IRClosureInstruction
 	instanceVariableNames: 'arguments'
 	package:'Compiler'!
 
-!IRClosure methodsFor: '*Compiler'!
+!IRClosureInstruction methodsFor: '*Compiler'!
 
 arguments
 	^ arguments ifNil: [ #() ]
@@ -2292,11 +2334,28 @@ arguments: aCollection
 	arguments := aCollection
 !
 
+locals
+	^ self arguments copy
+    	addAll: (self tempDeclarations collect: [ :each | each name ]); 
+        yourself
+!
+
 scope: aScope
 	super scope: aScope.
 	aScope instruction: self
 !
 
+tempDeclarations
+	^ self instructions select: [ :each | 
+    	each isTempDeclaration ]
+! !
+
+IRClosureInstruction subclass: #IRClosure
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRClosure methodsFor: '*Compiler'!
+
 sequence
 	^ self instructions last
 ! !
@@ -2313,22 +2372,14 @@ accept: aVisitor
 	^ aVisitor visitIRClosure: self
 ! !
 
-IRScopedInstruction subclass: #IRMethod
-	instanceVariableNames: 'theClass source selector classReferences messageSends superSends arguments internalVariables'
+IRClosureInstruction subclass: #IRMethod
+	instanceVariableNames: 'theClass source selector classReferences messageSends superSends internalVariables'
 	package:'Compiler'!
 !IRMethod commentStamp!
 I am a method instruction!
 
 !IRMethod methodsFor: '*Compiler'!
 
-arguments
-	^ arguments
-!
-
-arguments: aCollection
-	arguments := aCollection
-!
-
 classReferences
 	^ classReferences
 !
@@ -2341,6 +2392,10 @@ internalVariables
 	^ internalVariables ifNil: [ internalVariables := Set new ]
 !
 
+isMethod
+	^ true
+!
+
 messageSends
 	^ messageSends
 !
@@ -2349,9 +2404,8 @@ messageSends: aCollection
 	messageSends := aCollection
 !
 
-scope: aScope
-	super scope: aScope.
-	aScope instruction: self
+method
+	^ self
 !
 
 selector
@@ -2481,6 +2535,12 @@ name: aString
 
 !IRTempDeclaration methodsFor: '*Compiler'!
 
+isTempDeclaration
+	^ true
+! !
+
+!IRTempDeclaration methodsFor: '*Compiler'!
+
 accept: aVisitor
 	^ aVisitor visitIRTempDeclaration: self
 ! !
@@ -2754,6 +2814,8 @@ visitIRAssignment: anIRAssignment
 visitIRClosure: anIRClosure
 	self stream 
 		nextPutClosureWith: [ 
+        	self stream nextPutVars: (anIRClosure tempDeclarations collect: [ :each |
+    				each name asVariableName ]).
         	self stream 
             	nextPutBlockContextFor: anIRClosure
                 during: [ super visitIRClosure: anIRClosure ] ]
@@ -2777,10 +2839,13 @@ visitIRDynamicDictionary: anIRDynamicDictionary
 !
 
 visitIRMethod: anIRMethod
+
 	self stream
 		nextPutMethodDeclaration: anIRMethod 
 		with: [ self stream 
 			nextPutFunctionWith: [ 
+            	self stream nextPutVars: (anIRMethod tempDeclarations collect: [ :each |
+    				each name asVariableName ]).
             	self stream nextPutContextFor: anIRMethod during: [
 				anIRMethod internalVariables notEmpty ifTrue: [
 					self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |
@@ -2833,9 +2898,9 @@ visitIRSequence: anIRSequence
 !
 
 visitIRTempDeclaration: anIRTempDeclaration
-	self stream 
-    	nextPutAll: anIRTempDeclaration scope alias, '.locals.', anIRTempDeclaration name, '=nil;'; 
-        lf
+	"self stream 
+    	nextPutAll: 'var ', anIRTempDeclaration name asVariableName, ';'; 
+        lf"
 !
 
 visitIRValue: anIRValue
@@ -2890,10 +2955,26 @@ nextPutAssignment
 
 nextPutBlockContextFor: anIRClosure during: aBlock
 	self 
-    	nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') { '; 
+    	nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') {'; 
         nextPutAll: String cr.
+    
     aBlock value.
-    self nextPutAll: '})'
+    
+    self 
+    	nextPutAll: '}, function(', anIRClosure scope alias, ') {';
+        nextPutAll: anIRClosure scope alias, '.fillBlock({'.
+    
+    anIRClosure locals 
+    	do: [ :each |
+    		self 
+        		nextPutAll: each asVariableName;
+           	 	nextPutAll: ':';
+        		nextPutAll: each asVariableName]
+		separatedBy: [ self nextPutAll: ',' ].
+    
+    self
+    	nextPutAll: '},';
+        nextPutAll:  anIRClosure method scope alias, ')})'
 !
 
 nextPutClosureWith: aBlock arguments: anArray
@@ -2911,15 +2992,23 @@ nextPutContextFor: aMethod during: aBlock
     	nextPutAll: 'return smalltalk.withContext(function(', aMethod scope alias, ') { '; 
         nextPutAll: String cr.
     aBlock value.
+    
     self 
-    	nextPutAll: '}, self, ';
-        nextPutAll: aMethod selector asJavascript, ', ['.
-    aMethod arguments 
-    	do: [ :each | self nextPutAll: each asVariableName ]
-      	separatedBy: [ self nextPutAll: ','  ].
-    self nextPutAll: '], ';
+    	nextPutAll: '}, function(', aMethod scope alias, ') {', aMethod scope alias; 
+        nextPutAll: '.fill(self,', aMethod selector asJavascript, ',{'.
+
+    aMethod locals 
+    	do: [ :each |
+    		self 
+        		nextPutAll: each asVariableName;
+           	 	nextPutAll: ':';
+        		nextPutAll: each asVariableName]
+		separatedBy: [ self nextPutAll: ',' ].
+    
+    self
+    	nextPutAll: '}, ';
         nextPutAll: aMethod theClass asJavascript;
-        nextPutAll: ')'
+        nextPutAll: ')})'
 !
 
 nextPutFunctionWith: aBlock arguments: anArray
@@ -3019,6 +3108,8 @@ nextPutVar: aString
 !
 
 nextPutVars: aCollection
+	aCollection ifEmpty: [ ^self ].
+    
 	stream nextPutAll: 'var '.
 	aCollection 
 		do: [ :each | stream nextPutAll: each ]
@@ -3690,25 +3781,36 @@ irTranslator
 ! !
 
 NodeVisitor subclass: #AIContext
-	instanceVariableNames: 'outerContext pc locals receiver selector'
+	instanceVariableNames: 'outerContext pc locals method'
 	package:'Compiler'!
+!AIContext commentStamp!
+AIContext is like a `MethodContext`, used by the `ASTInterpreter`.
+Unlike a `MethodContext`, it is not read-only.
+
+When debugging, `AIContext` instances are created by copying the current `MethodContext` (thisContext)!
 
 !AIContext methodsFor: '*Compiler'!
 
-initializeFromMethodContext: aMethodContext
-	self pc: aMethodContext pc.
-    self receiver: aMethodContext receiver.
-    self selector: aMethodContext selector.
-    aMethodContext outerContext ifNotNil: [
-		self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].
-    aMethodContext locals keysAndValuesDo: [ :key :value |
-    	self locals at: key put: value ]
+localAt: aString
+	^ self locals at: aString ifAbsent: [ nil ]
+!
+
+localAt: aString put: anObject
+	self locals at: aString put: anObject
 !
 
 locals
 	^ locals ifNil: [ locals := Dictionary new ]
 !
 
+method
+	^ method
+!
+
+method: aCompiledMethod
+	method := aCompiledMethod
+!
+
 outerContext
 	^ outerContext
 !
@@ -3726,41 +3828,177 @@ pc: anInteger
 !
 
 receiver
-	^ receiver
+	^ self localAt: 'self'
 !
 
 receiver: anObject
-	receiver := anObject
+	self localAt: 'self' put: anObject
 !
 
 selector
-	^ selector
-!
+	^ self metod
+    	ifNotNil: [ self method selector ]
+! !
 
-selector: aString
-	selector := aString
+!AIContext methodsFor: '*Compiler'!
+
+initializeFromMethodContext: aMethodContext
+	self pc: aMethodContext pc.
+    self receiver: aMethodContext receiver.
+    self method: aMethodContext method.
+    aMethodContext outerContext ifNotNil: [
+		self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].
+    aMethodContext locals keysAndValuesDo: [ :key :value |
+    	self locals at: key put: value ]
 ! !
 
 !AIContext class methodsFor: '*Compiler'!
 
 fromMethodContext: aMethodContext
-	^ self new 
+	^ self new
     	initializeFromMethodContext: aMethodContext;
         yourself
 ! !
 
-NodeVisitor subclass: #ASTInterpreter
-	instanceVariableNames: 'currentNode context shouldReturn'
+Object subclass: #ASTDebugger
+	instanceVariableNames: 'interpreter context'
 	package:'Compiler'!
+!ASTDebugger commentStamp!
+ASTDebugger is a debugger to Amber.
+It uses an AST interpreter to step through the code.
 
-!ASTInterpreter methodsFor: '*Compiler'!
+ASTDebugger instances are created from a `MethodContext` with `ASTDebugger class >> context:`.
+They hold an `AIContext` instance internally, recursive copy of the `MethodContext`.
+
+Use the methods of the 'stepping' protocol to do stepping.!
+
+!ASTDebugger methodsFor: '*Compiler'!
 
 context
 	^ context
 !
 
+context: aContext
+	context := AIContext new.
+!
+
+interpreter
+	^ interpreter ifNil: [ interpreter := self defaultInterpreterClass new ]
+!
+
+interpreter: anInterpreter
+	interpreter := anInterpreter
+!
+
+method
+	^ self context method
+! !
+
+!ASTDebugger methodsFor: '*Compiler'!
+
+defaultInterpreterClass
+	^ ASTSteppingInterpreter
+! !
+
+!ASTDebugger methodsFor: '*Compiler'!
+
+buildAST
+	"Build the AST tree from the method source code.
+    The AST is annotated with a SemanticAnalyzer, 
+    to know the semantics and bindings of each node needed for later debugging"
+    
+    | ast |
+    
+    ast := Smalltalk current parse: self method source.
+    (SemanticAnalyzer on: self context receiver class)
+    	visit: ast.    
+    
+    ^ ast
+!
+
+initializeInterpreter
+	self interpreter interpret: self buildAST nodes first
+!
+
+initializeWithContext: aMethodContext
+	"TODO: do we need to handle block contexts?"
+    
+    self context: (AIContext fromMethodContext: aMethodContext).
+    self initializeInterpreter
+! !
+
+!ASTDebugger methodsFor: '*Compiler'!
+
+restart
+	self shouldBeImplemented
+!
+
+resume
+	self shouldBeImplemented
+!
+
+step
+	"The ASTSteppingInterpreter stops at each node interpretation. 
+    One step will interpret nodes until:
+    - we get at the end
+    - the next node is a stepping node (send, assignment, etc.)"
+    
+	[ (self interpreter nextNode notNil and: [ self interpreter nextNode stopOnStepping ])
+		or: [ self interpreter atEnd not ] ] 
+ 			whileFalse: [
+				self interpreter step. 
+                self step ]
+!
+
+stepInto
+	self shouldBeImplemented
+!
+
+stepOver
+	self step
+! !
+
+!ASTDebugger class methodsFor: '*Compiler'!
+
+context: aMethodContext
+	^ self new
+    	initializeWithContext: aMethodContext;
+        yourself
+! !
+
+Object subclass: #ASTInterpreter
+	instanceVariableNames: 'currentNode context shouldReturn result'
+	package:'Compiler'!
+!ASTInterpreter commentStamp!
+ASTIntepreter is like a `NodeVisitor`, interpreting nodes one after each other.
+It is built using Continuation Passing Style for stepping purposes.
+
+Usage example:
+
+    | ast interpreter |
+    ast := Smalltalk current parse: 'foo 1+2+4'.
+    (SemanticAnalyzer on: Object) visit: ast.
+
+    ASTInterpreter new
+        interpret: ast nodes first;
+        result "Answers 7"!
+
+!ASTInterpreter methodsFor: '*Compiler'!
+
+context
+	^ context ifNil: [ context := AIContext new ]
+!
+
 context: anAIContext
 	context := anAIContext
+!
+
+currentNode
+	^ currentNode
+!
+
+result
+	^ result
 ! !
 
 !ASTInterpreter methodsFor: '*Compiler'!
@@ -3774,71 +4012,367 @@ initialize
 
 interpret: aNode
 	shouldReturn := false.
-    ^ self interpretNode: aNode
+    self interpret: aNode continue: [ :value |
+    	result := value ]
 !
 
-interpretNode: aNode
-	currentNode := aNode.
-    ^ self visit: aNode
+interpret: aNode continue: aBlock
+	shouldReturn ifTrue: [ ^ self ].
+
+	aNode isNode 
+    	ifTrue: [ 	
+        	currentNode := aNode.
+            self interpretNode: aNode continue: [ :value |
+  				self continue: aBlock value: value ] ]
+        ifFalse: [ self continue: aBlock value: aNode ]
 !
 
-messageFromSendNode: aSendNode
-	^ Message new
-    	selector: aSendNode selector;
-        arguments: (aSendNode arguments collect: [ :each |
-        	self interpretNode: each ]);
-        yourself
-! !
+interpretAssignmentNode: aNode continue: aBlock
+	self interpret: aNode right continue: [ :value |
+    	self 
+        	continue: aBlock
+            value: (self assign: aNode left to: value) ]
+!
 
-!ASTInterpreter methodsFor: '*Compiler'!
+interpretBlockNode: aNode continue: aBlock
+	"TODO: Context should be set"
+    
+    self 
+    	continue: aBlock 
+        value: [ self interpret: aNode nodes first; result ]
+!
 
-visitBlockNode: aNode
-    ^ [ self interpretNode: aNode nodes first ]
+interpretBlockSequenceNode: aNode continue: aBlock
+	self interpretSequenceNode: aNode continue: aBlock
 !
 
-visitCascadeNode: aNode
+interpretCascadeNode: aNode continue: aBlock
 	"TODO: Handle super sends"
-	| receiver |
-    
-    receiver := self interpretNode: aNode receiver.
-
-    aNode nodes allButLast
-    	do: [ :each | 
-        	(self messageFromSendNode: each)
-            	sendTo: receiver ].
+	
+    self interpret: aNode receiver continue: [ :receiver |
+		"Only interpret the receiver once"
+        aNode nodes do: [ :each | each receiver: receiver ].
+  
+    	self 
+        	interpretAll: aNode nodes allButLast
+    		continue: [
+              	self 
+                	interpret: aNode nodes last
+                	continue: [ :val | self continue: aBlock value: val ] ] ]
+!
 
-    ^ (self messageFromSendNode: aNode nodes last)
-            	sendTo: receiver
+interpretClassReferenceNode: aNode continue: aBlock
+	self continue: aBlock value: (Smalltalk current at: aNode value)
 !
 
-visitClassReferenceNode: aNode
-	^ Smalltalk current at: aNode value
+interpretDynamicArrayNode: aNode continue: aBlock
+	self interpretAll: aNode nodes continue: [ :array |
+    	self 
+        	continue: aBlock
+			value: array ]
 !
 
-visitJSStatementNode: aNode
-	self halt
+interpretDynamicDictionaryNode: aNode continue: aBlock
+    self interpretAll: aNode nodes continue: [ :array | | hashedCollection |
+    	hashedCollection := HashedCollection new.
+        array do: [ :each | hashedCollection add: each ].
+        self 	
+        	continue: aBlock
+            value: hashedCollection ]
 !
 
-visitReturnNode: aNode
+interpretJSStatementNode: aNode continue: aBlock
 	shouldReturn := true.
-    ^ self interpretNode: aNode nodes first
+	self continue: aBlock value: (self eval: aNode source)
 !
 
-visitSendNode: aNode
+interpretMethodNode: aNode continue: aBlock
+	self interpretAll: aNode nodes continue: [ :array |
+    	self continue: aBlock value: array first ]
+!
+
+interpretNode: aNode continue: aBlock
+    aNode interpreter: self continue: aBlock
+!
+
+interpretReturnNode: aNode continue: aBlock
+    self interpret: aNode nodes first continue: [ :value |
+    	shouldReturn := true.
+		self continue: aBlock value: value ]
+!
+
+interpretSendNode: aNode continue: aBlock
 	"TODO: Handle super sends"
     
-    ^ (self messageFromSendNode: aNode)
-    	sendTo: (self interpretNode: aNode receiver)
+    self interpret: aNode receiver continue: [ :receiver |
+    	self interpretAll: aNode arguments continue: [ :args |
+    		self 
+            	messageFromSendNode: aNode 
+                arguments: args
+                do: [ :message |
+        			self context pc: self context pc + 1.
+        			self 
+            			continue: aBlock 
+                		value: (message sendTo: receiver) ] ] ]
 !
 
-visitSequenceNode: aNode
-	aNode nodes allButLast do: [ :each | | value |
-        value := self interpretNode: each.
-		shouldReturn ifTrue: [ ^ value ] ].
-    ^ self interpretNode: aNode nodes last
+interpretSequenceNode: aNode continue: aBlock
+	self interpretAll: aNode nodes continue: [ :array |
+    	self continue: aBlock value: array last ]
 !
 
-visitValueNode: aNode
-	^ aNode value
+interpretValueNode: aNode continue: aBlock
+	self continue: aBlock value: aNode value
+!
+
+interpretVariableNode: aNode continue: aBlock
+    self 
+    	continue: aBlock
+        value: (aNode binding isInstanceVar
+			ifTrue: [ self context receiver instVarAt: aNode value ]
+			ifFalse: [ self context localAt: aNode value ])
+! !
+
+!ASTInterpreter methodsFor: '*Compiler'!
+
+assign: aNode to: anObject
+	^ aNode binding isInstanceVar 
+    	ifTrue: [ self context receiver instVarAt: aNode value put: anObject ]
+      	ifFalse: [ self context localAt: aNode value put: anObject ]
+!
+
+continue: aBlock value: anObject
+	result := anObject.
+    aBlock value: anObject
+!
+
+eval: aString
+	"Evaluate aString as JS source inside an JS function. 
+    aString is not sandboxed."
+    
+    | source function |
+    
+    source := String streamContents: [ :str |
+    	str nextPutAll: '(function('.
+        self context locals keys 
+        	do: [ :each | str nextPutAll: each ]
+          	separatedBy: [ str nextPutAll: ',' ].
+        str 
+        	nextPutAll: '){ return (function() {';
+        	nextPutAll: aString;
+            nextPutAll: '})() })' ].
+            
+	function := Compiler new eval: source.
+    
+	^ function valueWithPossibleArguments: self context locals values
+!
+
+interpretAll: aCollection continue: aBlock
+	self 
+    	interpretAll: aCollection 
+        continue: aBlock 
+        result: OrderedCollection new
+!
+
+interpretAll: nodes continue: aBlock result: aCollection
+	nodes isEmpty 
+    	ifTrue: [ self continue: aBlock value: aCollection ]
+    	ifFalse: [
+    		self interpret: nodes first continue: [:value |
+    			self 
+                	interpretAll: nodes allButFirst 
+                    continue: aBlock
+  					result: aCollection, { value } ] ]
+!
+
+messageFromSendNode: aSendNode arguments: aCollection do: aBlock
+    self 
+        continue: aBlock
+        value: (Message new
+    		selector: aSendNode selector;
+        	arguments: aCollection;
+        	yourself)
+! !
+
+!ASTInterpreter methodsFor: '*Compiler'!
+
+shouldReturn
+	^ shouldReturn ifNil: [ false ]
+! !
+
+ASTInterpreter subclass: #ASTSteppingInterpreter
+	instanceVariableNames: 'continuation nextNode'
+	package:'Compiler'!
+!ASTSteppingInterpreter commentStamp!
+ASTSteppingInterpreter is an interpreter with stepping capabilities.
+Use `#step` to actually interpret the next node.
+
+Usage example:
+
+    | ast interpreter |
+    ast := Smalltalk current parse: 'foo 1+2+4'.
+    (SemanticAnalyzer on: Object) visit: ast.
+
+    interpreter := ASTSteppingInterpreter new
+        interpret: ast nodes first;
+        yourself.
+        
+    debugger step; step.
+    debugger step; step.
+    debugger result."Answers 1"
+    debugger step.
+    debugger result. "Answers 3"
+    debugger step.
+    debugger result. "Answers 7"!
+
+!ASTSteppingInterpreter methodsFor: '*Compiler'!
+
+nextNode
+	^ nextNode
+! !
+
+!ASTSteppingInterpreter methodsFor: '*Compiler'!
+
+initialize
+	super initialize.
+    continuation := [  ]
+! !
+
+!ASTSteppingInterpreter methodsFor: '*Compiler'!
+
+interpret: aNode continue: aBlock
+	nextNode := aNode.
+	continuation := [ 
+    	super interpret: aNode continue: aBlock ]
+! !
+
+!ASTSteppingInterpreter methodsFor: '*Compiler'!
+
+step
+	continuation value
+! !
+
+!ASTSteppingInterpreter methodsFor: '*Compiler'!
+
+atEnd
+	^ self shouldReturn or: [ self nextNode == self currentNode ]
+! !
+
+!Node methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretNode: self continue: aBlock
+!
+
+isSteppingNode
+	^ false
+! !
+
+!AssignmentNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretAssignmentNode: self continue: aBlock
+!
+
+isSteppingNode
+	^ true
+! !
+
+!BlockNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretBlockNode: self continue: aBlock
+!
+
+isSteppingNode
+	^ true
+! !
+
+!CascadeNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretCascadeNode: self continue: aBlock
+! !
+
+!DynamicArrayNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretDynamicArrayNode: self continue: aBlock
+!
+
+isSteppingNode
+	^ true
+! !
+
+!DynamicDictionaryNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretDynamicDictionaryNode: self continue: aBlock
+!
+
+isSteppingNode
+	^ true
+! !
+
+!JSStatementNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretJSStatementNode: self continue: aBlock
+!
+
+isSteppingNode
+	^ true
+! !
+
+!MethodNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretMethodNode: self continue: aBlock
+! !
+
+!ReturnNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretReturnNode: self continue: aBlock
+! !
+
+!SendNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretSendNode: self continue: aBlock
+!
+
+isSteppingNode
+	^ true
+! !
+
+!SequenceNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretSequenceNode: self continue: aBlock
+! !
+
+!BlockSequenceNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretBlockSequenceNode: self continue: aBlock
+! !
+
+!ValueNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretValueNode: self continue: aBlock
+! !
+
+!VariableNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretVariableNode: self continue: aBlock
+! !
+
+!ClassReferenceNode methodsFor: '*Compiler'!
+
+interpreter: anInterpreter continue: aBlock
+	^ anInterpreter interpretClassReferenceNode: self continue: aBlock
 ! !
 

+ 0 - 758
st/Documentation.st

@@ -1,758 +0,0 @@
-Smalltalk current createPackage: 'Documentation' properties: #{}!
-Object subclass: #ChapterSelectionAnnouncement
-	instanceVariableNames: 'id'
-	package: 'Documentation'!
-
-!ChapterSelectionAnnouncement methodsFor: 'accessing'!
-
-id
-	^id
-!
-
-id: aString
-	id := aString
-! !
-
-Object subclass: #ClassSelectionAnnouncement
-	instanceVariableNames: 'theClass'
-	package: 'Documentation'!
-
-!ClassSelectionAnnouncement methodsFor: 'accessing'!
-
-theClass
-	^theClass
-!
-
-theClass: aClass
-	theClass := aClass
-! !
-
-!ClassSelectionAnnouncement class methodsFor: 'instance creation'!
-
-on: aClass
-	^self new
-		theClass: aClass;
-		yourself
-! !
-
-Widget subclass: #DocChapter
-	instanceVariableNames: 'title contents parent level'
-	package: 'Documentation'!
-
-!DocChapter methodsFor: 'accessing'!
-
-announcer
-	^DocumentationBuilder current announcer
-!
-
-chapters
-	"A doc chapter can contain sub chapters"
-	^#()
-!
-
-contents
-	^contents ifNil: ['']
-!
-
-contents: aString
-	contents := aString
-!
-
-cssClass
-	^'doc_chapter'
-!
-
-htmlContents
-	^(Showdown at: #converter) new makeHtml: self contents
-!
-
-id
-	"The id is used in url fragments. 
-	It must be unique amoung all chapters"
-	^self title replace: ' ' with: '-'
-!
-
-level
-	^self parent ifNil: [1] ifNotNil: [self parent level +1]
-!
-
-level: anInteger
-	level := anInteger
-!
-
-parent
-	^parent
-!
-
-parent: aChapter
-	parent := aChapter
-!
-
-title
-	^title ifNil: ['']
-!
-
-title: aString
-	title := aString
-! !
-
-!DocChapter methodsFor: 'actions'!
-
-displayChapter: aChapter
-	DocumentationBuilder current widget displayChapter: aChapter
-!
-
-selectChapter: aChapter
-	document location hash: aChapter id
-!
-
-selectClass: aClass
-	DocumentationBuilder current announcer announce: (ClassSelectionAnnouncement on: aClass)
-! !
-
-!DocChapter methodsFor: 'initialization'!
-
-initialize
-	super initialize.
-	self subscribe
-! !
-
-!DocChapter methodsFor: 'rendering'!
-
-renderDocOn: html
-	| div |
-	html h1 with: self title.
-	self renderNavigationOn: html.
-	div := html div class: 'contents'.
-	div asJQuery html: self htmlContents
-!
-
-renderLinksOn: html
-	html ul 
-		class: 'links';
-		with: [
-			self chapters do: [:each |
-				html li with: [
-					html a
-						with: each title;
-						onClick: [self selectChapter: each]]]]
-!
-
-renderNavigationOn: html
-	self parent ifNotNil: [
-		html div 
-			class: 'navigation'; with: [
-				html a
-					with: '← back to ', self parent title;
-					onClick: [self selectChapter: self parent]]]
-!
-
-renderOn: html
-	html div 
-		class: self cssClass;
-		with: [
-			self renderDocOn: html.
-			self renderLinksOn: html]
-! !
-
-!DocChapter methodsFor: 'subscriptions'!
-
-subscribe
-	self announcer on: ChapterSelectionAnnouncement do: [:ann |
-		ann id = self id ifTrue: [self displayChapter: self]]
-! !
-
-DocChapter subclass: #ClassDocChapter
-	instanceVariableNames: 'theClass'
-	package: 'Documentation'!
-
-!ClassDocChapter methodsFor: 'accessing'!
-
-contents
-	^self theClass comment isEmpty
-		ifTrue: [self theClass name, ' is not documented yet.']
-		ifFalse: [self theClass comment]
-!
-
-cssClass
-	^'doc_class ', super cssClass
-!
-
-initializeWithClass: aClass
-	theClass := aClass
-!
-
-theClass
-	^theClass
-!
-
-title
-	^self theClass name
-! !
-
-!ClassDocChapter methodsFor: 'rendering'!
-
-renderLinksOn: html
-	html ul 
-		class: 'links';
-		with: [
-			html li with: [html a
-				with: 'Browse this class';
-				onClick: [Browser openOn: self theClass]]]
-! !
-
-!ClassDocChapter methodsFor: 'subscriptions'!
-
-subscribe
-	super subscribe.
-	self announcer 
-		on: ClassSelectionAnnouncement do: [:ann |
-			ann theClass = self theClass ifTrue: [
-				self selectChapter: self]]
-! !
-
-!ClassDocChapter class methodsFor: 'accessing'!
-
-on: aClass
-	^self basicNew
-		initializeWithClass: aClass;
-		initialize;
-		yourself
-! !
-
-DocChapter subclass: #ClassesIndexChapter
-	instanceVariableNames: ''
-	package: 'Documentation'!
-
-!ClassesIndexChapter methodsFor: 'accessing'!
-
-alphabet
-	^'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-!
-
-cssClass
-	^'index_doc ', super cssClass
-!
-
-title
-	^'Smalltalk classes by index'
-! !
-
-!ClassesIndexChapter methodsFor: 'rendering'!
-
-renderDocOn: html
-	html h1 with: self title.
-	self alphabet do: [:letter || classes |
-		classes := Smalltalk current classes select: [:each | each name first = letter].
-		classes ifNotEmpty: [html h2 with: letter].
-		html ul with: [
-			(classes sorted: [:a :b | a name < b name]) 
-				do: [:each |
-					html li with: [html a 
-						with: each name;
-						onClick: [self selectClass: each]]]]]
-! !
-
-DocChapter subclass: #PackageDocChapter
-	instanceVariableNames: 'package chapters'
-	package: 'Documentation'!
-
-!PackageDocChapter methodsFor: 'accessing'!
-
-chapters
-	^chapters
-!
-
-contents
-	^'Classes in package ', self package name, ':'
-!
-
-package
-	^package
-!
-
-title
-	^'Package ', self package name
-! !
-
-!PackageDocChapter methodsFor: 'initialization'!
-
-initializeWithPackage: aPackage
-	package := aPackage.
-	chapters := (aPackage classes sorted: [:a :b | a name < b name]) collect: [:each |
-		(ClassDocChapter on: each)
-			parent: self;
-			yourself]
-! !
-
-!PackageDocChapter class methodsFor: 'instance creation'!
-
-on: aPackage
-	^self basicNew
-		initializeWithPackage: aPackage;
-		initialize;
-		yourself
-! !
-
-DocChapter subclass: #TutorialsChapter
-	instanceVariableNames: ''
-	package: 'Documentation'!
-
-!TutorialsChapter methodsFor: 'accessing'!
-
-chapters
-	^{ self firstAppChapter. self counterChapter }
-!
-
-contents
-	^'Here''s a serie of tutorials. If you are new to Smalltalk, you can also learn Amber online with [ProfStef](http://www.amber-lang.net/learn.html)'
-!
-
-counterChapter
-	^DocChapter new
-		title: 'The counter application';
-		contents: '
-
-This tutorial will teach you how to build HTML with Amber using jQuery and the HTMLCanvas API. It is freely adapted from 
-the [Seaside counter example](http://www.seaside.st/about/examples/counter)
-
-##The counter widget
-
-The counter is the most basic example of a widget. It allows to increment and decrement a number by clicking a button.
-
-Amber already comes with a counter example in the `Examples` package. To avoid class name conflict, we''ll name our counter class `TCounter`.
-
-    Widget subclass: #TCounter
-        instanceVariableNames: ''count header''
-        package: ''Tutorials''
-
-The first method is used to initialize the component with the default state, in this case we set the counter to 0:
-
-    initialize
-        super initialize.
-        count := 0
-
-The method used for rendering a widget is `#renderOn:`. It takes an instance of HTMLCanvas as parameter. 
-The `header` h1 kept as an instance variable, so when the count value change, we can update it''s contents accordingly.
-
-    renderOn: html
-        header := html h1 
-            with: count asString;
-            yourself.
-        html button
-            with: ''++'';
-            onClick: [self increase].
-        html button
-            with: ''--'';
-            onClick: [self decrease]
-
-The counter is almost ready. All we need now is to implement the two action methods `#increase` and `#decrease` to change the state 
-of our counter and update its header.
-
-    increase
-        count := count + 1.
-        header contents: [:html | html with: count asString]
-
-    decrease
-        count := count - 1.
-        header contents: [:html | html with: count asString]
-
-
-That''s it!! We can now display an instance of TCounter by rendering it on the page using jQuery:
-
-    TCounter new appendToJQuery: ''body'' asJQuery
-
-'
-!
-
-firstAppChapter
-	^DocChapter new
-		title: 'A first application';
-		contents: '
-
-Let''s make Hello World in Amber.
-
-First, you need a place for your new project. I made a new directory under amber:
-
-    amber/projects/hello
-
-This will store your project files. To get started, add a new index.html file to this folder, as well as empty js and st folders.
-
-Your index.html can be really basic. The most important thing it does is include amber.js and run loadAmber. Here is a basic index.html you can use:
-
-
-    <!!DOCTYPE html>
-    <html>
-      <head>
-        <title>My First Amber Project</title>
-        <script src="../../js/amber.js" type="text/javascript"></script>
-        <script type="text/javascript">
-          loadAmber({
-            files: [],
-            prefix: ''projects/hello/js'',
-            ready: function() {
-              
-            }}); 
-        </script>
-      </head>
-      <body>
-        <article>
-          <h1>My First Amber Project</h1>
-          <button onclick="smalltalk.Browser._open()">class browser</button>
-          <button id="sayHello">say hello</button>
-        </article>
-      </body>
-    </html>
-
-Now start up amber with node.js and navigate to  http://localhost:4000/projects/hello/index.html
-
-It''s boring so far, so lets write some code. Click the button to open the class browser. Find an existing class and change its name to Hello and its package to HelloApp. 
-Then click save. This creates a new class and leaves the old one intact, it doesn''t overwrite it. Your class will look like this:
-
-    Object subclass: #Hello
-        instanceVariableNames: ''''
-        package: ''HelloApp''
-
-Now click save and navigate to your new class in its new package.
- Then click ''commit package''. You just created a new class and saved your work. 
-On your file system check out your js and st folders. Your new class is now saved in both JavaScript and Smalltalk.
-
-Now, refresh your browser page and reopen the class browser. Oh no, your new class is gone!! To load your new class automatically, you have to add it in index.html. Make your JavaScript look like this:
-
-
-    loadAmber({
-        files: [''HelloApp.js''],
-        prefix: ''projects/hello/js'',
-        ready: function() {      
-    }}); 
-
-Save and refresh again. Now your class is loaded and shows up in the class browser.
-
-Now, let''s make this class do something. Create a new message in the class browser by navigating to your class, then clicking ''not yet classified'' and fill in a simple message. Try this for example:
-
-    begin
-	"Makes me say hello to the user."
-
-	| msg button |
-	msg := ''Hello world!!''.
-	button := ''#sayHello'' asJQuery.
-	button click: [button after: ''<p>'' , msg , ''</p>''].
-
-Your message isn''t too helpful if it doesn''t get called. Save it, commit the package, then edit index.html again. You can write JavaScript code that sends a message to Smalltalk:
-
-    loadAmber({
-        files: [''HelloApp.js''],
-        prefix: ''projects/hello/js'', // path for js files i think
-        ready: function() {
-          $(function() {
-            smalltalk.Hello._new()._begin();
-          });
-    }}); 
-
-From there, you can create new Smalltalk classes and messages to build up your app. Enjoy!!
-'
-!
-
-title
-	^'Tutorials'
-! !
-
-Object subclass: #DocumentationBuilder
-	instanceVariableNames: 'chapters announcer widget'
-	package: 'Documentation'!
-
-!DocumentationBuilder methodsFor: 'accessing'!
-
-announcer
-	^announcer ifNil: [announcer := Announcer new]
-!
-
-chapters
-	^chapters ifNil: [chapters := self buildChapters]
-!
-
-widget
-	^widget ifNil: [widget := DocumentationWidget on: self]
-! !
-
-!DocumentationBuilder methodsFor: 'building'!
-
-build
-	self buildOnJQuery: ('body' asJQuery)
-!
-
-buildChapters
-	^((self class methodDictionary values sorted: [:a :b | a selector < b selector])
-		select: [:each | each category = 'chapters'])
-		collect: [:each | self perform: each selector]
-!
-
-buildOn: aCanvas
-	aCanvas with: self widget.
-	self 
-		checkHashChange;
-		checkHash
-!
-
-buildOnJQuery: aJQuery
-	self buildOn: (HTMLCanvas onJQuery: aJQuery)
-! !
-
-!DocumentationBuilder methodsFor: 'chapters'!
-
-ch1introduction
-	^DocChapter new
-		title: 'Introduction';
-		contents: '
-
-##Amber Smalltalk in a nutshell
-
-Amber is an implementation of the Smalltalk-80 language. It is designed to make client-side web development **faster, easier and more fun** as it allows developers to write HTML5 applications in a live Smalltalk environment!!
-
-Amber is written in itself, including the IDE and the compiler and it runs **directly inside your browser**. The IDE is fairly complete with a class browser, workspace, transcript, unit test runner, object inspectors, cross reference tools and even a debugger.
-
-Noteworthy features:
-
-- Amber is semantically and syntactically very close to [Pharo Smalltalk](http://www.pharo-project.org). Pharo is considered the reference implementation.
-- Amber **seamlessly interacts with JavaScript** and can use its full eco system of libraries without any glue code needed.
-- Amber **has no dependencies** and can be used in any JavaScript runtime, not only inside browsers. An important example is [Node.js](http://nodejs.org).
-- Amber is a live Smalltalk that **compiles incrementally into efficient JavaScript** often mapping one-to-one with JavaScript equivalents.
-- Amber has a **Seaside influenced canvas library** to dynamically generate HTML.
-
-## Arguments for using Amber
-In our humble opinion the main arguments for using Amber are:
-
-- JavaScript is quite a broken language with lots of traps and odd quirks. It is the assembler of the Internet which is cool, but we don''t want to write in it.
-- Smalltalk as a language is immensely cleaner and more mature, both syntactically and semantically.
-- Smalltalk has a simple class model with a lightweight syntax for closures, it is in many ways a perfect match for the Good Parts of JavaScript.
-- Having a true live interactive incremental development environment where you can build your application directly in the browser is unbeatable.
-
-## Disclaimer
-
-This documentation doesn''t aim to teach Smalltalk. 
-Knowledge of Smalltalk is needed to understand the topics covered in this documentation. 
-If you want to learn the Smalltalk language, you can read the excellent [Pharo By Example](http://www.pharobyexample.org) book.
-'
-!
-
-ch2differencesWithOtherSmalltalks
-	^DocChapter new
-		title: 'Differences with other Smalltalks';
-		contents: '
-Amber has some differences with other Smalltalk implementations. This makes porting code a non-trivial thing, but still quite manageable.
-Because it maps Smalltalk constructs one-to-one with the JavaScript equivalent, including Smalltalk classes to JavaScript constructors, the core class library is simplified compared to Pharo Smalltalk.
-And since we want Amber to be useful in building lean browser apps we can''t let it bloat too much.
-
-But apart from missing things other Smalltalks may have, there are also things that are plain different:
-
-- The collection class hierarchy is much simpler compared to most Smalltalk implementations. In part this is because we want to map reasonably well with JavaScript counter parts.
-- As of today, there is no SortedCollection. The size of arrays is dynamic, and they behave like an ordered collection. They can also be sorted with the `#sort*` methods.
-- The `Date` class behaves like the `Date` and `TimeStamp` classes in Pharo Smalltalk. Therefore both `Date today` and `Date now` are valid in Amber.
-- Amber does not have class Character, but `String` does implement some of Character behavior so a single character String can work as a Character.
-- Amber does support **class instance variables**, but not class variables.
-- Amber only has global classes and packages, but not arbitrary objects. Use classes instead like `Smalltalk current` instead of `Smalltalk` etc.
-- Amber does not support pool dictionaries.
-- Amber uses **< ...javascript code... >** to inline JavaScript code and does not have pragmas.
-- Amber does not have class categories. The left side in the browser lists real Packages, but they feel much the same.
-'
-!
-
-ch3GettingStarted
-	^DocChapter new
-		title: 'Getting started';
-		contents: '
-To get started hacking in Amber you can basically take three routes, independent of your platform:
-
-1. Just **try it out directly** at [www.amber-lang.net](http://www.amber-lang.net) - click the **Class browser** button there. But you will **not be able to save any code you write**!! 
-    Still, it works fine for looking at the IDE and playing around. Just **don''t press F5/reload** - it will lose any code you have written.
-2. Download an Amber zip-ball, install [Nodejs](http://www.nodejs.org), fire up the Amber server and then open Amber from localhost - then you **can save code**. Detailed instructions are below!!
-3. Same as above but install git first and get a proper clone from [http://github.com/NicolasPetton/amber](http://github.com/NicolasPetton/amber) instead of a zip/tar-ball. 
-    If you want to **contribute to Amber itself** this is really what you want to do. In fact, in most cases this is what you want to do. It requires installing git first, but it is quite simple - although we leave this bit as an "exercise to the reader" :)
-
-**PLEASE NOTE:** Amber core developers use Linux. 
-We do not want to introduce dependencies that aren''t cross platform - but currently amberc (the command line compiler) is a bash script and we also use Makefiles 
-(for building Amber itself and server side examples) written on Linux/Unix. So using Windows is currently a bit limited - you can''t run "make" in the .st directory to rebuild whole of Amber for example.
- BUT... if you only want to use Amber to build web client apps and not really get involved in hacking Amber itself - then you should be fine!!
-
-## Downloading Amber
-Currently you can download in zip or tar-ball format, either cutting edge or a release. [Downloads are available here](https://github.com/NicolasPetton/amber/archives/amber). 
-
-Unpack wherever you like, but I would rename the directory that is unpacked to something slightly shorter - like say "amber". :)
-And yes, at this point you can double click the index.html file in the amber directory to get the IDE up, but again, **you will not be able to save code**. So please continue below :)
-
-## Installing Node.js
-[Node](http://www.nodejs.org) (for short) is simply the V8 Javascript VM from Google (used in Chrome) hooked together with some hard core C-libraries for doing "evented I/O".
-Basically it''s JavaScript for the server - on asynch steroids. Amber runs fine in Node and we use it for several Amber tools, like amberc (the command line Amber compiler) or the Amber server (see below). 
-There are also several Amber-Node examples to look at if you want to play with running Amber programs server side. **In short - you really want to install Nodejs. :)**
-
-- Installing Node on Linux can be done using your package tool of choice (`apt-get install nodejs` for example) or any other way described at [the download page](http://nodejs.org/#download).
-- Installing Node on MacOS or Windows is probably done best by using the [installers available at Nodejs.org](http://nodejs.org/#download).
-
-## Starting Amber server
-Nicolas has written a minimal webDAV server that is the easiest way to get up and running Amber with the ability to save code. This little server is written in... Amber!! 
-And it runs on top of Node. So to start it up serving your brand new directory tree of sweet Amber you do:
-
-	cd amber	(or whatever you called the directory you unpackaged)
-	./bin/server	(in windows you type `node server\server.js` instead)
-
-It should say it is listening on port 4000. If it does, hooray!! That means both Node and Amber are good. In Windows you might get a question about opening that port in the local firewall - yep, do it!!
-
-## Firing up Amber
-The Amber IDE is written in... Amber. It uses [jQuery](http://jquery.com) and runs right in your browser as a ... well, a web page. 
-We could open it up just using a file url - but the reason we performed the previous steps is so that we can load the IDE web page from a server that can handle PUTs (webDAV) of source code. 
-According to web security Amber can only do PUT back to the same server it was loaded from. Thus we instead want to open it [through our little server now listening on port 4000](http://localhost:4000/index.html).
-Clicking that link and then pressing the **Class browser** should get your Amber IDE running with the ability to commit modified packages locally.
-
-To verify that you can indeed commit now - just select a Package in the browser, like say "Examples" and press the **Commit** button below. **If all goes well nothing happens :)**. 
-So in order to really know if it worked we can check the modified date on the files **amber/st/Examples.st**, **amber/js/Examples.js** and **amber/js/Examples.deploy.js** - they should be brand new.
-
-NOTE: We can use any webDAV server and Apache2 has been used earlier and works fine. But the Amber server is smaller and simpler to start.
-'
-!
-
-ch4Tutorials
-	^TutorialsChapter new
-!
-
-ch5Index
-	^ClassesIndexChapter new
-!
-
-ch6KernelObjects
-	^PackageDocChapter on: (Package named: 'Kernel-Objects')
-!
-
-ch7KernelClasses
-	^PackageDocChapter on: (Package named: 'Kernel-Classes')
-!
-
-ch8KernelCollection
-	^PackageDocChapter on: (Package named: 'Kernel-Collections')
-!
-
-ch9KernelMethods
-	^PackageDocChapter on: (Package named: 'Kernel-Methods')
-! !
-
-!DocumentationBuilder methodsFor: 'routing'!
-
-checkHash
-	| hash presentation |
-	hash := document location hash  replace: '^#' with: ''.
-	self announcer announce: (ChapterSelectionAnnouncement new 
-		id: hash; 
-		yourself)
-!
-
-checkHashChange
-	(window jQuery: window) bind: 'hashchange' do: [self checkHash]
-! !
-
-!DocumentationBuilder methodsFor: 'updating'!
-
-update
-	chapters := nil.
-	announcer := nil.
-	widget := nil.
-	(window jQuery: '.documentation') remove.
-	self build
-! !
-
-DocumentationBuilder class instanceVariableNames: 'current'!
-
-!DocumentationBuilder class methodsFor: 'accessing'!
-
-current
-	^current ifNil: [current := self new]
-! !
-
-!DocumentationBuilder class methodsFor: 'initialization'!
-
-initialize
-	self current build
-! !
-
-Widget subclass: #DocumentationWidget
-	instanceVariableNames: 'builder selectedChapter chapterDiv'
-	package: 'Documentation'!
-
-!DocumentationWidget methodsFor: 'accessing'!
-
-builder
-	^builder
-!
-
-builder: aDocumentationBuilder
-	builder := aDocumentationBuilder
-!
-
-chapters
-	^self builder chapters
-!
-
-selectedChapter
-	^selectedChapter ifNil: [selectedChapter := self chapters first]
-!
-
-selectedChapter: aChapter
-	^selectedChapter := aChapter
-! !
-
-!DocumentationWidget methodsFor: 'actions'!
-
-displayChapter: aChapter
-	self selectedChapter: aChapter.
-	self updateChapterDiv
-!
-
-selectChapter: aChapter
-	document location hash: aChapter id
-! !
-
-!DocumentationWidget methodsFor: 'rendering'!
-
-renderChapterMenu: aChapter on: html
-	html a
-		with: aChapter title;
-		onClick: [
-			self selectChapter: aChapter].
-	html ol with: [
-			aChapter chapters do: [:each |
-				html li with: [
-					self renderChapterMenu: each on: html]]]
-!
-
-renderMenuOn: html
-	html div 
-		class: 'menu';
-		with: [
-			html ol with: [
-				self chapters do: [:each |
-					html li with: [
-						self renderChapterMenu: each on: html]]]]
-!
-
-renderOn: html
-	html div 
-		class: 'documentation';
-		with: [
-			self renderMenuOn: html.
-			chapterDiv := html div.
-			self updateChapterDiv]
-! !
-
-!DocumentationWidget methodsFor: 'updating'!
-
-updateChapterDiv
-	chapterDiv contents: [:html |
-		html with: self selectedChapter]
-! !
-
-!DocumentationWidget class methodsFor: 'instance creation'!
-
-on: aBuilder
-	^self new
-		builder: aBuilder;
-		yourself
-! !
-

+ 1 - 1
st/Examples.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Examples' properties: #{}!
+Smalltalk current createPackage: 'Examples'!
 Widget subclass: #Counter
 	instanceVariableNames: 'count header'
 	package: 'Examples'!

+ 12 - 1
st/IDE.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'IDE' properties: #{}!
+Smalltalk current createPackage: 'IDE'!
 Widget subclass: #ClassesList
 	instanceVariableNames: 'browser ul nodes'
 	package: 'IDE'!
@@ -519,6 +519,17 @@ update
 
 TabManager class instanceVariableNames: 'current'!
 
+!TabManager class methodsFor: 'actions'!
+
+toggleAmberIDE
+	(window jQuery: '#amber') length = 0
+		ifTrue: [ Browser open ]
+      	ifFalse: [ 
+			((window jQuery: '#amber') is: ':visible')
+				ifTrue: [ TabManager current close ] 
+				ifFalse: [ TabManager current open ] ]
+! !
+
 !TabManager class methodsFor: 'instance creation'!
 
 current

+ 5 - 5
st/Importer-Exporter.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Importer-Exporter' properties: #{}!
+Smalltalk current createPackage: 'Importer-Exporter'!
 Object subclass: #ChunkParser
 	instanceVariableNames: 'stream'
 	package: 'Importer-Exporter'!
@@ -155,8 +155,8 @@ exportMethodsOf: aClass on: aStream
 exportPackageDefinitionOf: package on: aStream
 	aStream 
 	    nextPutAll: 'smalltalk.addPackage(';
-	    nextPutAll: '''', package name, ''', ', package propertiesAsJSON , ');'.
-	aStream lf
+	    nextPutAll: '''', package name, ''');';
+        lf
 !
 
 exportPackageExtensionsOf: package on: aStream
@@ -262,8 +262,8 @@ exportPackageDefinitionOf: package on: aStream
 	"Chunk format."
 
 	aStream 
-	    nextPutAll: 'Smalltalk current createPackage: ''', package name,
-		''' properties: ', package properties storeString, '!!'; lf.
+		nextPutAll: 'Smalltalk current createPackage: ''', package name, '''!!';
+		lf
 !
 
 exportPackageExtensionsOf: package on: aStream

+ 1 - 1
st/Kernel-Announcements.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Kernel-Announcements' properties: #{}!
+Smalltalk current createPackage: 'Kernel-Announcements'!
 Object subclass: #AnnouncementSubscription
 	instanceVariableNames: 'block announcementClass'
 	package: 'Kernel-Announcements'!

+ 123 - 95
st/Kernel-Classes.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Kernel-Classes' properties: #{}!
+Smalltalk current createPackage: 'Kernel-Classes'!
 Object subclass: #Behavior
 	instanceVariableNames: ''
 	package: 'Kernel-Classes'!
@@ -394,38 +394,44 @@ ClassBuilder is responsible for compiling new classes or modifying existing clas
 
 Rather than using ClassBuilder directly to compile a class, use `Class >> subclass:instanceVariableNames:package:`.!
 
-!ClassBuilder methodsFor: 'api'!
+!ClassBuilder methodsFor: 'accessing'!
 
-class: aClass instanceVariableNames: aString
-	self basicClass: aClass instanceVariableNames: aString.
-    self setupClass: aClass.
+instanceVariableNamesFor: aString
+	^(aString tokenize: ' ') reject: [ :each | each isEmpty ]
+! !
+
+!ClassBuilder methodsFor: 'class definition'!
+
+addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
+    | theClass |
     
-    SystemAnnouncer current
-    	announce: (ClassDefinitionChanged new
-        	theClass: aClass;
-            yourself)
-!
+    theClass := Smalltalk current at: aString.
+    
+   	theClass ifNotNil: [ 
+    	theClass superclass == aClass ifFalse: [
+    		^ self 
+        		migrateClassNamed: aString 
+           	 	superclass: aClass 
+           	 	instanceVariableNames: aCollection 
+            	package: packageName ] ].
 
-installMethod: aCompiledMethod forClass: aBehavior category: aString
-	aCompiledMethod category: aString.
-	aBehavior addCompiledMethod: aCompiledMethod.
-    self setupClass: aBehavior.
-	^aCompiledMethod
+	^ self 
+    	basicAddSubclassOf: aClass 
+        named: aString 
+        instanceVariableNames: aCollection 
+        package: packageName
 !
 
-renameClass: aClass to: aString
-	self basicRenameClass: aClass to: aString.
+class: aClass instanceVariableNames: aString
+	self basicClass: aClass instanceVariableNames: aString.
+    self setupClass: aClass.
     
     SystemAnnouncer current
-    	announce: (ClassRenamed new
+    	announce: (ClassDefinitionChanged new
         	theClass: aClass;
             yourself)
 !
 
-setupClass: aClass
-	<smalltalk.init(aClass);>
-!
-
 superclass: aClass subclass: aString
 	^self superclass: aClass subclass: aString instanceVariableNames: '' package: nil
 !
@@ -446,56 +452,60 @@ superclass: aClass subclass: aString instanceVariableNames: aString2 package: aS
 	^newClass
 ! !
 
-!ClassBuilder methodsFor: 'private'!
+!ClassBuilder methodsFor: 'class migration'!
 
-addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
-    | theClass |
+migrateClass: aClass superclass: anotherClass
+	console log: aClass name.
+	self 
+    	migrateClassNamed: aClass name
+        superclass: anotherClass
+        instanceVariableNames: aClass instanceVariableNames
+        package: aClass package name
+!
+
+migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName
+	| oldClass newClass tmp |
     
-    theClass := Smalltalk current at: aString.
+    tmp := 'new*', aString.
+    oldClass := Smalltalk current at: aString.
     
-   	theClass ifNotNil: [ 
-    	theClass superclass == aClass ifFalse: [
-    		^ self 
-        		migrateClassNamed: aString 
-           	 	superclass: aClass 
-           	 	instanceVariableNames: aCollection 
-            	package: packageName ] ].
+    newClass := self 
+		addSubclassOf: aClass
+		named: tmp
+		instanceVariableNames: aCollection
+		package: packageName.
 
-	^ self 
-    	basicAddSubclassOf: aClass 
-        named: aString 
-        instanceVariableNames: aCollection 
-        package: packageName
-!
+	self basicSwapClassNames: oldClass with: newClass.
 
-basicAddSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
-	<
-		smalltalk.addClass(aString, aClass, aCollection, packageName);
-		return smalltalk[aString]
-	>
-!
+	[ self copyClass: oldClass to: newClass ]
+		on: Error
+		do: [ :exception |
+			self
+            	basicSwapClassNames: oldClass with: newClass;
+            	basicRemoveClass: newClass.
+            exception signal ].
 
-basicClass: aClass instanceVariableNames: aString
-	self basicClass: aClass instanceVariables: (self instanceVariableNamesFor: aString)
-!
+	self
+		rawRenameClass: oldClass to: tmp;
+        rawRenameClass: newClass to: aString.
 
-basicClass: aClass instanceVariables: aCollection
+	oldClass subclasses do: [ :each |
+    	self migrateClass: each superclass: newClass ].
 
-	aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
-	aClass basicAt: 'iVarNames' put: aCollection
+    self basicRemoveClass: oldClass.
+	^newClass
 !
 
-basicRemoveClass: aClass
-	<smalltalk.removeClass(aClass)>
-!
+renameClass: aClass to: aString
+	self basicRenameClass: aClass to: aString.
+    
+    SystemAnnouncer current
+    	announce: (ClassRenamed new
+        	theClass: aClass;
+            yourself)
+! !
 
-basicRenameClass: aClass to: aString
-	<
-		smalltalk[aString] = aClass;
-		delete smalltalk[aClass.className];
-		aClass.className = aString;
-	>
-!
+!ClassBuilder methodsFor: 'copying'!
 
 copyClass: aClass named: aString
 	| newClass |
@@ -524,48 +534,66 @@ copyClass: aClass to: anotherClass
 		Compiler new install: each source forClass: anotherClass class category: each category ].
 
 	self setupClass: anotherClass
+! !
+
+!ClassBuilder methodsFor: 'method definition'!
+
+installMethod: aCompiledMethod forClass: aBehavior category: aString
+	aCompiledMethod category: aString.
+	aBehavior addCompiledMethod: aCompiledMethod.
+    self setupClass: aBehavior.
+	^aCompiledMethod
+! !
+
+!ClassBuilder methodsFor: 'private'!
+
+basicAddSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
+	<
+		smalltalk.addClass(aString, aClass, aCollection, packageName);
+		return smalltalk[aString]
+	>
 !
 
-instanceVariableNamesFor: aString
-	^(aString tokenize: ' ') reject: [ :each | each isEmpty ]
+basicClass: aClass instanceVariableNames: aString
+	self basicClass: aClass instanceVariables: (self instanceVariableNamesFor: aString)
 !
 
-migrateClass: aClass superclass: anotherClass
-	console log: aClass name.
-	self 
-    	migrateClassNamed: aClass name
-        superclass: anotherClass
-        instanceVariableNames: aClass instanceVariableNames
-        package: aClass package name
+basicClass: aClass instanceVariables: aCollection
+
+	aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
+	aClass basicAt: 'iVarNames' put: aCollection
 !
 
-migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName
-	| oldClass newClass |
-    
-    oldClass := Smalltalk current at: aString.
-    
-    "Rename the old class for existing instances"
-	self basicRenameClass: oldClass to: 'Old', aString.
-    
-    newClass := self 
-		addSubclassOf: aClass
-		named: aString 
-		instanceVariableNames: aCollection
-		package: packageName.
+basicRemoveClass: aClass
+	<smalltalk.removeClass(aClass)>
+!
 
-	oldClass subclasses do: [ :each |
-    	self migrateClass: each superclass: newClass ].
+basicRenameClass: aClass to: aString
+	<
+		smalltalk[aString] = aClass;
+		delete smalltalk[aClass.className];
+		aClass.className = aString;
+	>
+!
 
-    [ self copyClass: oldClass to: newClass ] 
-    	on: Error
-        do: [ :exception |
-        	self 
-            	basicRemoveClass: newClass;
-            	basicRenameClass: oldClass to: aString.
-            exception signal ].
-            
-    self basicRemoveClass: oldClass.
-	^newClass
+basicSwapClassNames: aClass with: anotherClass
+	<
+		var tmp = aClass.className;
+		aClass.className = anotherClass.className;
+        anotherClass.className = tmp;
+	>
+!
+
+rawRenameClass: aClass to: aString
+	<
+		smalltalk[aString] = aClass;
+	>
+! !
+
+!ClassBuilder methodsFor: 'public'!
+
+setupClass: aClass
+	<smalltalk.init(aClass);>
 ! !
 
 Object subclass: #ClassCategoryReader

+ 228 - 98
st/Kernel-Collections.st

@@ -1,7 +1,11 @@
-Smalltalk current createPackage: 'Kernel-Collections' properties: #{}!
+Smalltalk current createPackage: 'Kernel-Collections'!
 Object subclass: #Association
 	instanceVariableNames: 'key value'
 	package: 'Kernel-Collections'!
+!Association commentStamp!
+I represent a pair of associated objects, a key and a value. My instances can serve as entries in a dictionary.
+
+Instances can be created with the class-side method `#key:value:`!
 
 !Association methodsFor: 'accessing'!
 
@@ -57,6 +61,10 @@ key: aKey value: aValue
 Object subclass: #Collection
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
+!Collection commentStamp!
+I am the abstract superclass of all classes that represent a group of elements.
+
+I provide a set of useful methods to the Collectiohn hierarchy such as enumerating and converting methods.!
 
 !Collection methodsFor: 'accessing'!
 
@@ -165,25 +173,18 @@ detect: aBlock
 !
 
 detect: aBlock ifNone: anotherBlock
-	<
-		for(var i = 0; i < self.length; i++)
-			if(aBlock(self[i]))
-				return self[i];
-		return anotherBlock();
-	>
+	self subclassResponsibility
 !
 
 do: aBlock
-	<for(var i=0;i<self.length;i++){aBlock(self[i]);}>
+	self subclassResponsibility
 !
 
 do: aBlock separatedBy: anotherBlock
-	| first |
-	first := true.
+	| actionBeforeElement |
+	actionBeforeElement := [actionBeforeElement := anotherBlock].
 	self do: [:each |
-	    first
-		ifTrue: [first := false]
-		ifFalse: [anotherBlock value].
+    	actionBeforeElement value.
 	    aBlock value: each]
 !
 
@@ -309,28 +310,104 @@ withAll: aCollection
 		yourself
 ! !
 
-Collection subclass: #HashedCollection
+Collection subclass: #IndexableCollection
+	instanceVariableNames: ''
+	package: 'Kernel-Collections'!
+!IndexableCollection commentStamp!
+I am a key-value store, that is,
+it stores values under indexes.
+
+As a rule of thumb, if a collection has at: and at:put:,
+it is an IndexableCollection.!
+
+!IndexableCollection methodsFor: 'accessing'!
+
+at: anIndex
+	"Lookup the given index in the receiver. 
+	If it is present, answer the value stored at anIndex. 
+	Otherwise, raise an error."
+
+	^self at: anIndex ifAbsent: [ self errorNotFound ]
+!
+
+at: anIndex ifAbsent: aBlock
+	"Lookup the given index in the receiver. 
+	If it is present, answer the value stored at anIndex. 
+	Otherwise, answer the value of aBlock."
+
+	self subclassReponsibility
+!
+
+at: anIndex ifPresent: aBlock
+	"Lookup the given index in the receiver. 
+	If it is present, answer the value of evaluating aBlock with the value stored at anIndex. 
+	Otherwise, answer nil."
+
+	^self at: anIndex ifPresent: aBlock ifAbsent: [ nil ]
+!
+
+at: anIndex ifPresent: aBlock ifAbsent: anotherBlock
+	"Lookup the given index in the receiver. 
+	If it is present, answer the value of evaluating aBlock with the value stored at anIndex.
+	Otherwise, answer the value of anotherBlock."
+
+	self subclassReponsibility
+!
+
+at: anIndex put: anObject
+	"Store anObject under the given index in the receiver."
+
+	self subclassReponsibility
+!
+
+indexOf: anObject
+	"Lookup index at which anObject is stored in the receiver.
+	If not present, raise an error."
+
+	^self indexOf: anObject ifAbsent: [ self errorNotFound ]
+!
+
+indexOf: anObject ifAbsent: aBlock
+	"Lookup index at which anObject is stored in the receiver.
+	If not present, return value of executing aBlock."
+
+	self subclassResponsibility
+! !
+
+!IndexableCollection methodsFor: 'enumeration'!
+
+with: anotherCollection do: aBlock
+	"Calls aBlock with every value from self
+	and with indetically-indexed value from anotherCollection"
+
+	self withIndexDo: [ :each :index |
+		aBlock value: each value: (anotherCollection at: index) ]
+!
+
+withIndexDo: aBlock
+	"Calls aBlock with every value from self
+	and with its index as the second argument"
+
+	self subclassReponsibility
+! !
+
+IndexableCollection subclass: #HashedCollection
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
 !HashedCollection commentStamp!
-A HashedCollection is a traditional JavaScript object, or a Smalltalk Dictionary.
+I am a traditional JavaScript object, or a Smalltalk `Dictionary`.
 
-Unlike a Dictionary, it can only have strings as keys.!
+Unlike a `Dictionary`, it can only have strings as keys.!
 
 !HashedCollection methodsFor: 'accessing'!
 
 associations
 	| associations |
 	associations := #().
-	self keys do: [:each |
-	    associations add: (Association key: each value: (self at: each))].
+	self associationsDo: [:each |  associations add: each].
 	^associations
 !
 
-at: aKey
-	^self at: aKey ifAbsent: [self errorNotFound]
-!
-
 at: aKey ifAbsent: aBlock
 	^(self includesKey: aKey)
 		ifTrue: [self basicAt: aKey]
@@ -342,15 +419,6 @@ at: aKey ifAbsentPut: aBlock
 	    self at: aKey put: aBlock value]
 !
 
-at: aKey ifPresent: aBlock
-	"Lookup the given key in the receiver. 
-	If it is present, answer the value of evaluating the given block with the value associated with the key. 
-	Otherwise, answer nil."
-	^(self includesKey: aKey)
-		ifTrue: [ aBlock value: (self at: aKey) ]
-		ifFalse: [ nil ]
-!
-
 at: aKey ifPresent: aBlock ifAbsent: anotherBlock
 	"Lookup the given key in the receiver. 
 	If it is present, answer the value of evaluating the oneArgBlock with the value associated with the key, 
@@ -364,6 +432,11 @@ at: aKey put: aValue
 	^self basicAt: aKey put: aValue
 !
 
+indexOf: anObject ifAbsent: aBlock
+
+	^ self keys detect: [ :each | (self at: each) = anObject ] ifNone: aBlock
+!
+
 keys
 	<
 		if ('function'===typeof Object.keys) return Object.keys(self);
@@ -438,30 +511,27 @@ asJSON
 	self shouldNotImplement
 !
 
-copyFrom: anIndex to: anotherIndex
-	self shouldNotImplement
-!
-
 deepCopy
 	| copy |
 	copy := self class new.
-	self associationsDo: [:each |
-	    copy at: each key  put: each value deepCopy].
+	self keysAndValuesDo: [:key :value |
+	    copy at: key  put: value deepCopy].
 	^copy
 !
 
 shallowCopy
 	| copy |
 	copy := self class new.
-	self associationsDo: [:each |
-	    copy at: each key  put: each value].
+	self keysAndValuesDo: [:key :value |
+	    copy at: key  put: value].
 	^copy
 ! !
 
 !HashedCollection methodsFor: 'enumerating'!
 
 associationsDo: aBlock
-	self associations do: aBlock
+	self keysAndValuesDo: [:key :value |
+	    aBlock value: (Association key: key value: value)]
 !
 
 collect: aBlock
@@ -477,7 +547,7 @@ detect: aBlock ifNone: anotherBlock
 !
 
 do: aBlock
-	self values do: aBlock
+	self valuesDo: aBlock
 !
 
 includes: anObject
@@ -485,8 +555,12 @@ includes: anObject
 !
 
 keysAndValuesDo: aBlock
-	self associationsDo: [:each |
-	    aBlock value: each key value: each value]
+	self keysDo: [:each |
+	    aBlock value: each value: (self at: each)]
+!
+
+keysDo: aBlock
+	self keys do: aBlock
 !
 
 select: aBlock
@@ -495,6 +569,14 @@ select: aBlock
 	self keysAndValuesDo: [:key :value |
 	    (aBlock value: value) ifTrue: [newDict at: key put: value]].
 	^newDict
+!
+
+valuesDo: aBlock
+	self keysAndValuesDo: [ :key :value | aBlock value: value ]
+!
+
+withIndexDo: aBlock
+	self keysAndValuesDo: [ :key :value | aBlock value: value value: key ]
 ! !
 
 !HashedCollection methodsFor: 'printing'!
@@ -535,53 +617,45 @@ fromPairs: aCollection
 HashedCollection subclass: #Dictionary
 	instanceVariableNames: 'keys values'
 	package: 'Kernel-Collections'!
+!Dictionary commentStamp!
+I represent a set of elements that can be viewed from one of two perspectives: a set of associations, 
+or a container of values that are externally named where the name can be any object that responds to `=`. 
+
+The external name is referred to as the key.!
 
 !Dictionary methodsFor: 'accessing'!
 
 at: aKey ifAbsent: aBlock
 	<
-		var index;
-		for(var i=0;i<self['@keys'].length;i++){
-			if(self['@keys'][i].__eq(aKey)) {index = i;}
-		};
-		if(typeof index === 'undefined') {
-			return aBlock();
-		} else {
-			return self['@values'][index];
-		}
+		var index = self._positionOfKey_(aKey);
+		return index >>=0 ? self['@values'][index] : aBlock();
 	>
 !
 
 at: aKey put: aValue
 	<
-		var index = self['@keys'].indexOf(aKey);
+		var index = self._positionOfKey_(aKey);
 		if(index === -1) {
-			self['@values'].push(aValue);
-			self['@keys'].push(aKey);
-		} else {
-			self['@values'][index] = aValue;
-		};
+			var keys = self['@keys'];
+			index = keys.length;
+			keys.push(aKey);
+		}
 
-		return aValue;
+		return self['@values'][index] = aValue;
 	>
 !
 
-keyAtValue: anObject
+indexOf: anObject ifAbsent: aBlock
 
-	^ (self associations 
-    	detect:[:k :v| v == anObject] 
-    	ifNone:[self error: 'Not found']) key
+	| index |
+    index := values indexOf: anObject ifAbsent: [0].
+    ^ index = 0 ifTrue: [ aBlock value ] ifFalse: [ keys at: index ]
 !
 
 keys
 	^keys copy
 !
 
-valueAt: anObject
-
-	^ self associationsDo:2
-!
-
 values
 	^values copy
 ! !
@@ -589,17 +663,20 @@ values
 !Dictionary methodsFor: 'adding/removing'!
 
 removeKey: aKey ifAbsent: aBlock
-    <
-            var index = self['@keys'].indexOf(aKey);
-            if(index === -1) {
-                return aBlock()
-            } else {
-                var value;
-                self['@keys'].splice(index, 1);
-                value = self['@values'].splice(index, 1);
-                return value[0];
-            };
-    >
+	<
+		var index = self._positionOfKey_(aKey);
+		if(index === -1) {
+			return aBlock()
+		} else {
+			var keys = self['@keys'], values = self['@values'];
+			var value = values[index], l = keys.length;
+			keys[index] = keys[l-1];
+			keys.pop();
+			values[index] = values[l-1];
+			values.pop();
+			return value;
+		}
+	>
 ! !
 
 !Dictionary methodsFor: 'converting'!
@@ -612,6 +689,20 @@ asJSON
 	^self asHashedCollection asJSON
 ! !
 
+!Dictionary methodsFor: 'enumerating'!
+
+keysAndValuesDo: aBlock
+	^keys with: values do: aBlock
+!
+
+keysDo: aBlock
+	^keys do: aBlock
+!
+
+valuesDo: aBlock
+	^values do: aBlock
+! !
+
 !Dictionary methodsFor: 'initialization'!
 
 initialize
@@ -620,15 +711,30 @@ initialize
 	values := #()
 ! !
 
+!Dictionary methodsFor: 'private'!
+
+positionOfKey: anObject
+	<
+		var keys = self['@keys'];
+		for(var i=0;i<keys.length;i++){
+			if(keys[i].__eq(anObject)) { return i;}
+		}
+		return -1;
+	>
+! !
+
 !Dictionary methodsFor: 'testing'!
 
 includesKey: aKey
-	^keys includes: aKey
+	< return self._positionOfKey_(aKey) >>= 0; >
 ! !
 
-Collection subclass: #SequenceableCollection
+IndexableCollection subclass: #SequenceableCollection
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
+!SequenceableCollection commentStamp!
+I am an IndexableCollection
+with numeric indexes starting with 1.!
 
 !SequenceableCollection methodsFor: 'accessing'!
 
@@ -640,19 +746,6 @@ allButLast
 	^self copyFrom: 1 to: self size - 1
 !
 
-at: anIndex
-	^self at: anIndex ifAbsent: [
-	    self errorNotFound]
-!
-
-at: anIndex ifAbsent: aBlock
-	self subclassResponsibility
-!
-
-at: anIndex put: anObject
-	self subclassResponsibility
-!
-
 atRandom
 	^ self at: self size atRandom
 !
@@ -672,10 +765,6 @@ fourth
 	^self at: 4
 !
 
-indexOf: anObject
-	^self indexOf: anObject ifAbsent: [self errorNotFound]
-!
-
 indexOf: anObject ifAbsent: aBlock
 	<
 		for(var i=0;i<self.length;i++) {
@@ -768,6 +857,23 @@ shallowCopy
 
 !SequenceableCollection methodsFor: 'enumerating'!
 
+detect: aBlock ifNone: anotherBlock
+	<
+		for(var i = 0; i < self.length; i++)
+			if(aBlock(self[i]))
+				return self[i];
+		return anotherBlock();
+	>
+!
+
+do: aBlock
+	<for(var i=0;i<self.length;i++){aBlock(self[i]);}>
+!
+
+with: anotherCollection do: aBlock
+	<for(var i=0;i<self.length;i++){aBlock(self[i], anotherCollection[i]);}>
+!
+
 withIndexDo: aBlock
 	<for(var i=0;i<self.length;i++){aBlock(self[i], i+1);}>
 ! !
@@ -781,6 +887,9 @@ includes: anObject
 SequenceableCollection subclass: #Array
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
+!Array commentStamp!
+I represent a collection of objects ordered by the collector. The size of arrays is dynamic.
+In Amber, OrderedCollection is an alias for Array.!
 
 !Array methodsFor: 'accessing'!
 
@@ -897,6 +1006,8 @@ withAll: aCollection
 SequenceableCollection subclass: #CharacterArray
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
+!CharacterArray commentStamp!
+I am the abstract superclass of string-like collections.!
 
 !CharacterArray methodsFor: 'accessing'!
 
@@ -963,6 +1074,11 @@ fromString: aString
 CharacterArray subclass: #String
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
+!String commentStamp!
+I am an indexed collection of Characters. Unlike most Smalltalk dialects, Amber doesn't provide the Character class. Instead, elements of a String are single character strings.
+
+String inherits many useful methods from its hierarchy, such as
+	`Collection >> #,`!
 
 !String methodsFor: 'accessing'!
 
@@ -1287,6 +1403,11 @@ value: aUTFCharCode
 CharacterArray subclass: #Symbol
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
+!Symbol commentStamp!
+I represent Strings that are created uniquely. 
+Symbols are unique through the system.
+
+Thus, someString asSymbol == someString asSymbol.!
 
 !Symbol methodsFor: 'accessing'!
 
@@ -1416,6 +1537,8 @@ lookup: aString
 Collection subclass: #Set
 	instanceVariableNames: 'elements'
 	package: 'Kernel-Collections'!
+!Set commentStamp!
+I represent an unordered set of objects without duplicates.!
 
 !Set methodsFor: 'accessing'!
 
@@ -1544,6 +1667,8 @@ initialize
 Object subclass: #RegularExpression
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
+!RegularExpression commentStamp!
+I represent a regular expression object. My instances are JavaScript `RegExp` object.!
 
 !RegularExpression methodsFor: 'evaluating'!
 
@@ -1572,6 +1697,9 @@ fromString: aString flag: anotherString
 Object subclass: #Stream
 	instanceVariableNames: 'collection position streamSize'
 	package: 'Kernel-Collections'!
+!Stream commentStamp!
+I represent an accessor for a sequence of objects. This sequence is referred to as my "contents".
+My instances are read/write streams to the contents sequence collection.!
 
 !Stream methodsFor: 'accessing'!
 
@@ -1705,6 +1833,8 @@ on: aCollection
 Stream subclass: #StringStream
 	instanceVariableNames: ''
 	package: 'Kernel-Collections'!
+!StringStream commentStamp!
+I am a Stream specific to `String` objects.!
 
 !StringStream methodsFor: 'reading'!
 

+ 1 - 1
st/Kernel-Exceptions.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Kernel-Exceptions' properties: #{}!
+Smalltalk current createPackage: 'Kernel-Exceptions'!
 Object subclass: #Error
 	instanceVariableNames: 'messageText'
 	package: 'Kernel-Exceptions'!

+ 1 - 1
st/Kernel-Methods.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Kernel-Methods' properties: #{}!
+Smalltalk current createPackage: 'Kernel-Methods'!
 Object subclass: #BlockClosure
 	instanceVariableNames: ''
 	package: 'Kernel-Methods'!

+ 13 - 7
st/Kernel-Objects.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Kernel-Objects' properties: #{}!
+Smalltalk current createPackage: 'Kernel-Objects'!
 nil subclass: #Object
 	instanceVariableNames: ''
 	package: 'Kernel-Objects'!
@@ -1199,12 +1199,12 @@ named: aPackageName ifAbsent: aBlock
 !Package class methodsFor: 'commit paths'!
 
 commitPathsFromLoader
-    <
-    var cp = smalltalk['@@commitPath'];
-    if (!!cp) return;
-    if (cp.js) self._defaultCommitPathJs_(cp.js);
-    if (cp.st) self._defaultCommitPathSt_(cp.st);
-    >
+<
+	var cp = typeof amber !!== 'undefined' && amber.commitPath;
+	if (!!cp) return;
+	if (cp.js) self._defaultCommitPathJs_(cp.js);
+	if (cp.st) self._defaultCommitPathSt_(cp.st);
+>
 !
 
 defaultCommitPathJs
@@ -1458,6 +1458,12 @@ readJSObject: anObject
 reservedWords
 	"JavaScript reserved words"
 	<return self.reservedWords>
+!
+
+version
+	"Answer the version string of Amber"
+    
+    ^ '0.10'
 ! !
 
 !Smalltalk methodsFor: 'classes'!

+ 36 - 6
st/Kernel-Tests.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Kernel-Tests' properties: #{}!
+Smalltalk current createPackage: 'Kernel-Tests'!
 TestCase subclass: #BlockClosureTest
 	instanceVariableNames: ''
 	package: 'Kernel-Tests'!
@@ -260,9 +260,10 @@ testClassMigration
     self assert: ObjectMock2 package name equals: 'Kernel-Tests'.
     
 	self deny: instance class == ObjectMock2.
-    self assert: instance class name equals: 'OldObjectMock2'.
+    "Commeting this out. Tests implementation detail."
+    "self assert: instance class name equals: 'OldObjectMock2'."
     
-    self assert: (Smalltalk current at: 'OldObjectMock2') isNil.
+	self assert: (Smalltalk current at: instance class name) isNil.
     
     Smalltalk current removeClass: ObjectMock2
 !
@@ -427,11 +428,20 @@ CollectionTest subclass: #HashedCollectionTest
 !HashedCollectionTest methodsFor: 'accessing'!
 
 collection
-	^ #{ 'a' -> 1. 'b' -> 2. 'c' -> 3. 'd' -> -4 }
+	^ #{ 'b' -> 1. 'a' -> 2. 'c' -> 3. 'd' -> -4 }
 !
 
 collectionWithDuplicates
-	^ #{ 'a' -> 1. 'b' -> 2. 'c' -> 3. 'd' -> -4. 'e' -> 1. 'f' -> 2. 'g' -> 10 }
+	^ #{ 'b' -> 1. 'a' -> 2. 'c' -> 3. 'd' -> -4. 'e' -> 1. 'f' -> 2. 'g' -> 10 }
+! !
+
+!HashedCollectionTest methodsFor: 'tests'!
+
+testIndexOf
+
+	self assert: (self collection indexOf: 2) equals: 'a'.
+	self should: [ self collection indexOf: 999 ] raise: Error.
+	self assert: (self collection indexOf: 999 ifAbsent: [ 'sentinel' ]) equals: 'sentinel'
 ! !
 
 !HashedCollectionTest class methodsFor: 'accessing'!
@@ -479,11 +489,17 @@ testAccessing
 	self assert: (d at: 'hello' ifAbsent: [nil]) equals: 'world'.
 	self deny: (d at: 'foo' ifAbsent: [nil]) = 'world'.
 
+	self assert: (d includesKey: 'hello').
+	self deny: (d includesKey: 'foo').
+
 	d at: 1 put: 2.
 	self assert: (d at: 1) equals: 2.
 
 	d at: 1@3 put: 3.
-	self assert: (d at: 1@3) equals: 3
+	self assert: (d at: 1@3) equals: 3.
+
+	self assert: (d includesKey: 1@3).
+	self deny: (d includesKey: 3@1)
 !
 
 testDynamicDictionaries
@@ -558,6 +574,20 @@ testKeys
 	self assert: d keys equals: #(1 2 3)
 !
 
+testPointKey
+	| d |
+
+	d := Dictionary new.
+    
+    d at: 1@1 put: 'foo'.
+	self assert: (d at: 1@1) equals: 'foo'.
+    d at: 1@1 put: 'bar'.
+	self assert: (d at: 1@1) equals: 'bar'.
+    d removeKey: 1@1.
+    self assert: (d at: 1@1 ifAbsent: [ 'baz' ]) equals: 'baz'.
+    self deny: (d includesKey: 1@1)
+!
+
 testPrintString
 	self
 		assert: (Dictionary new 

+ 1 - 1
st/Kernel-Transcript.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Kernel-Transcript' properties: #{}!
+Smalltalk current createPackage: 'Kernel-Transcript'!
 Object subclass: #ConsoleTranscript
 	instanceVariableNames: 'textarea'
 	package: 'Kernel-Transcript'!

+ 1 - 1
st/SUnit-Tests.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'SUnit-Tests' properties: #{}!
+Smalltalk current createPackage: 'SUnit-Tests'!
 TestCase subclass: #ExampleSetTest
 	instanceVariableNames: 'empty full'
 	package: 'SUnit-Tests'!

+ 1 - 1
st/SUnit.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'SUnit' properties: #{}!
+Smalltalk current createPackage: 'SUnit'!
 Object subclass: #ResultAnnouncement
 	instanceVariableNames: 'result'
 	package: 'SUnit'!

+ 1 - 1
st/Spaces.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Spaces' properties: #{}!
+Smalltalk current createPackage: 'Spaces'!
 Object subclass: #ObjectSpace
 	instanceVariableNames: 'frame'
 	package: 'Spaces'!

+ 1 - 1
test/Test.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Test' properties: #{}!
+Smalltalk current createPackage: 'Test'!
 Object subclass: #NodeTestRunner
 	instanceVariableNames: ''
 	package: 'Test'!

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels