Bladeren bron

Merge branch 'master' into moka

Conflicts:
	index.html
Nicolas Petton 10 jaren geleden
bovenliggende
commit
9042ad4992
52 gewijzigde bestanden met toevoegingen van 6834 en 6486 verwijderingen
  1. 1 2
      Gruntfile.js
  2. 1 1
      bin/amber
  3. 1 1
      bin/amberc
  4. 3 3
      cli/index.html
  5. 103 114
      cli/js/AmberCli.js
  6. 912 928
      cli/support/amber-cli.js
  7. 5 8
      css/helios.css
  8. 861 865
      css/helios.less
  9. 10 15
      grunt/tasks/grunt-peg.js
  10. 3 3
      helios.html
  11. 4 2
      js/Benchfib.js
  12. 24 12
      js/Canvas.js
  13. 116 59
      js/Compiler-AST.js
  14. 2 1
      js/Compiler-Core.js
  15. 2 1
      js/Compiler-Exceptions.js
  16. 45 114
      js/Compiler-Interpreter.js
  17. 2 1
      js/Compiler-Semantic.js
  18. 42 0
      js/Helios-Browser.js
  19. 89 10
      js/Helios-Commands-Tools.js
  20. 11 5
      js/Helios-Core.js
  21. 189 56
      js/Helios-Debugger.js
  22. 2 1
      js/Helios-Inspector.js
  23. 54 0
      js/Helios-References.js
  24. 6 3
      js/Helios-Workspace.js
  25. 42 38
      js/IDE.js
  26. 36 18
      js/Kernel-Classes.js
  27. 161 80
      js/Kernel-Collections.js
  28. 14 7
      js/Kernel-Exceptions.js
  29. 109 37
      js/Kernel-Infrastructure.js
  30. 66 33
      js/Kernel-Methods.js
  31. 166 83
      js/Kernel-Objects.js
  32. 8 4
      js/Kernel-Tests.js
  33. 2 1
      js/Kernel-Transcript.js
  34. 1 1
      package.json
  35. 32 20
      st/Compiler-AST.st
  36. 15 46
      st/Compiler-Interpreter.st
  37. 13 0
      st/Helios-Browser.st
  38. 34 2
      st/Helios-Commands-Tools.st
  39. 7 1
      st/Helios-Core.st
  40. 71 11
      st/Helios-Debugger.st
  41. 18 0
      st/Helios-References.st
  42. 17 17
      st/IDE.st
  43. 25 9
      st/Kernel-Infrastructure.st
  44. 1 1
      support/boot.js
  45. 0 1
      support/deploy.js
  46. 1 1
      support/devel.js
  47. 1 1
      support/helios.js
  48. 30 6
      support/helpers.js
  49. 1 1
      support/lang.js
  50. 3415 3819
      support/parser.js
  51. 59 42
      support/parser.pegjs
  52. 1 1
      support/smalltalk.js

+ 1 - 2
Gruntfile.js

@@ -16,9 +16,8 @@ module.exports = function(grunt) {
     peg: {
       amber_parser: {
         options: {
-          trackLineAndColumn: true,
           cache: true,
-          export_var: 'smalltalk.parser'
+          export_var: 'globals.SmalltalkParser'
         },
         src: 'support/parser.pegjs',
         dest: 'support/parser.js',

+ 1 - 1
bin/amber

@@ -1,2 +1,2 @@
-#!/bin/bash
+#!/bin/sh
 node `dirname $0`/../cli/support/amber-cli.js $@

+ 1 - 1
bin/amberc

@@ -1,2 +1,2 @@
-#!/bin/bash
+#!/bin/sh
 node `dirname $0`/../cli/support/amberc-cli.js $@

+ 3 - 3
cli/index.html

@@ -22,9 +22,9 @@
         ["amber/devel",
             "amber_cli/AmberCli" ],
         function (smalltalk) {
-            smalltalk.defaultAmdNamespace = 'amber_cli';
-            smalltalk.initialize();
-            smalltalk.Browser._openOn_(smalltalk.AmberCli);
+            smalltalk.vm.defaultAmdNamespace = 'amber_cli';
+            smalltalk.vm.initialize();
+            smalltalk.globals.Browser._openOn_(smalltalk.AmberCli);
         }
     );
     </script> 

File diff suppressed because it is too large
+ 103 - 114
cli/js/AmberCli.js


File diff suppressed because it is too large
+ 912 - 928
cli/support/amber-cli.js


+ 5 - 8
css/helios.css

@@ -38,7 +38,7 @@ html[xmlns] .clearfix {
 }
 #helios .CodeMirror-hints {
   border-radius: 0;
-  font-family: Menlo, Monaco, Consolas, Inconsolata, "Lucida Console", Courier, monospace;
+  font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
   font-size: 11px;
   line-height: 1em;
   padding: 0;
@@ -48,17 +48,15 @@ html[xmlns] .clearfix {
   border-radius: 0;
   padding: 0 10px;
 }
-#helios .CodeMirror pre {
-  font-family: Menlo, Monaco, Consolas, Inconsolata, "Lucida Console", "Ubuntu Mono", Courier, monospace;
+#helios .CodeMirror pre,
+#helios .CodeMirror .CodeMirror-gutter-elt {
+  font-family: Menlo, Monaco, "Lucida Console", "Ubuntu Mono", Courier, monospace;
   line-height: 16px;
   font-size: 13px;
 }
 #helios .CodeMirror-gutter.stops {
   width: 20px;
 }
-#helios .CodeMirror .CodeMirror-gutter-elt {
-  line-height: 1.5em;
-}
 #helios .CodeMirror .highlighted.CodeMirror-linebackground {
   background-color: #ffffaa;
 }
@@ -483,7 +481,6 @@ html[xmlns] .clearfix {
   box-shadow: 0 0 0;
   vertical-align: top;
   /* min-width: 50px; */
-
 }
 #helios .tool_container .panes .pane .pane_actions .btn:hover {
   background-color: #bbb;
@@ -526,7 +523,7 @@ html[xmlns] .clearfix {
 }
 #helios .key_helper .label {
   padding: 1px 4px;
-  font-family: Menlo, Monaco, Consolas, Inconsolata, "Lucida Console", Courier, monospace;
+  font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
   background: transparent;
   color: #08C;
   text-shadow: none;

+ 861 - 865
css/helios.less

@@ -28,882 +28,878 @@ html[xmlns] .clearfix {
 #helios {
 
     a {
-	cursor: pointer;
-    }
-
-    i {
-	opacity: 1;
-    }
-
-    [class^="icon-"], [class*=" icon-"] {
-	margin-top: 0;
-    }
-
-    .CodeMirror {
-	position: absolute;
-	overflow: hidden;
-	height: 100%;
-	width: 100%;
-    }
-
-    .CodeMirror-hints {
-	border-radius: 0;
-	font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
-	font-size: 11px;
-	line-height: 1em;
-	padding: 0;
-	max-height: 120px;
-    }
-
-    .CodeMirror-hint {
-	border-radius: 0;
-	padding: 0 10px;
-    }
-
-    .CodeMirror pre {
-	font-family: Menlo, Monaco, "Lucida Console",  "Ubuntu Mono", Courier, monospace;
-	line-height: 16px;
-	font-size: 13px;
-    }
-
-    .CodeMirror-gutter.stops {
-	width: 20px;
-    }
-
-    .CodeMirror .CodeMirror-gutter-elt {
-	line-height: 1.5em;
-    }
-
-    .CodeMirror .highlighted.CodeMirror-linebackground {
-	background-color: #ffffaa;
-    }
-
-    .CodeMirror .CodeMirror-gutter-elt .stop {
-	width: 16px;
-	height: 16px;
-	background: url('../images/arrowRight.png');
-	margin-left: 2px;
-    }
-
-    .state {
-	position: absolute;
-	right: 15px;
-	top: 10px;
-	width: 16px;
-	height: 16px;
-    }
-
-    .state.modified {
-	background: transparent url('../images/modified.png') 50% 50% no-repeat;
-    }
-
-    .editor {
-	position: absolute;
-	top: 0;
-	bottom: 23px;
-	left: 0;
-	right: 0;
-    }
-
-    .buttons_bar {
-	position: absolute;
-	bottom: 0;
-	right: 0;
-	left: 0;
-	z-index: 2;
-	padding: 0px 25px;
-	height: 21px;
-	line-height: 18px;
-	border-top: 1px solid #999;
-	text-align: right;
+		cursor: pointer;
+	}
 
-	.button {
-	    height: 17px;
-	    font-size: 12px;
-	    min-width: 0;
+	i {
+		opacity: 1;
 	}
-    }
 
-    .btn, .btn-group > .btn, .btn-group > .dropdown-menu {
-	padding: 2px 8px;
-    }
+	[class^="icon-"], [class*=" icon-"] {
+		margin-top: 0;
+	}
 
-    .navbar-fixed-top {
-	font-size: 11px;
-	line-height: 16px;
-    }
+	.CodeMirror {
+		position: absolute;
+		overflow: hidden;
+		height: 100%;
+		width: 100%;
+	}
 
-    .navbar-fixed-top a span,
-    .dialog .nav a span {
-	padding: 1px;
-	padding-left: 18px;
-	background-position: center left;
-	background-repeat: no-repeat;
-	background-position: 0px -1px;
-    }
-
-    .navbar-fixed-top i.close {
-	width: 14px;
-	height: 16px;
-	margin-left: 4px;
-	background-image: url('../images/close.gif');
-	margin-right: 0;
-	background-position: center left;
-	margin-top: 2px;
-    }
-
-    .navbar-fixed-top a,
-    .dialog .nav a {
-
-	span.references {
-	    background-image: url('../images/references.png')
-	}
-
-	span.browser {
-	    background-image: url('../images/browser.png')
-	}
-
-	span.sunit {
-	    background-image: url('../images/sunit.png')
-	}
-
-	span.workspace {
-	    background-image: url('../images/workspace.png')
-	}
-
-	span.debugger {
-	    background-image: url('../images/debugger.png')
-	}
-	span.inspector {
-	    background-image: url('../images/inspector.png')
-	}
-    }
-
-
-    .navbar-fixed-top .navbar-inner {
-	min-height: 20px;
-	background-color: #dbdbdb;
-	border-bottom: 1px solid #666;
-	background-image: linear-gradient(top, #dfdfdf, #d0d0d0);
-	background-image: -webkit-linear-gradient(top, #dfdfdf, #d0d0d0);
-	background-image: -moz-linear-gradient(top, #dfdfdf, #d0d0d0);
-	background-image: -owebkit-linear-gradient(top, #dfdfdf, #d0d0d0);
-	box-shadow: 0 0 0;
-    }
-
-
-    .navbar .nav > li {
-	line-height: 16px;
-    }
-
-
-    .navbar .nav > li > a {
-	line-height: 22px;
-	padding: 0px 8px;
-	font-size: 11px;
-	color: #444;
-	text-shadow: 0 1px 0 #ddd;
-    }
-
-    .nav > li > a:hover {
-	background: transparent;
-    }
-
-    .navbar .nav > .active > a, 
-    .navbar .nav > .active > a:hover, 
-    .navbar .nav > .active > a:focus {
-	background-color: #bababa;
-	background-image: linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -webkit-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -moz-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -o-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	text-shadow: #ddd 0px 1px 0px; 
-	color: #222;
-    }
-
-    .navbar-fixed-top i {
-	opacity: 0.4;
-	margin-right: 5px;
-	height: 12px;
-	margin-top: 0;
-    }
-
-    .navbar-fixed-top .active i {
-	opacity: 0.6;
-    }
-
-    .nav-pills.nav-stacked > li > a {
-	border-radius: 0;
-	-webkit-border-radius: 0;
-	-moz-border-radius: 0;
-	padding: 2px 2px 1px 4px;
-	margin: 0;
-	font-size: 11px;
-	color: #111;
-	white-space: nowrap;
-    }
-
-    [class^="icon-"], [class*=" icon-"] {
-	margin-right: 2px;
-    }
-
-    .dropdown-menu {
-	border-radius: 0;
-	padding: 0;
-	margin: 3px;
-    }
-
-    .nav-pills > .active > a {
-	background-color: #ddd;
-	color: #fff;
-	text-shadow: 0 0 0;
-    }
-
-    .focused .nav-pills {
-	background-color: #f3f7fb;
-    }
-
-    .focused .nav-pills > .active > a, 
-    .nav-pills > .active > a:hover,
-    .dropdown-menu li > a:hover, 
-    .dropdown-menu li > a:focus, 
-    .dropdown-submenu:hover > a,
-    .dropdown-menu .active > a, 
-    .dropdown-menu .active > a:hover,
-    .CodeMirror-hint-active {
-	background: rgba(95, 159, 228, 0.62);
-	color: #fff;
-	text-shadow: 0 0 0;
-    }
-
-
-    .tool_container {
-	position: absolute;
-	top: 23px;
-	bottom: 0;
-	left: 0;
-	right: 0;
-    }
-
-    .transcript textarea {
-	width: 100%;
-	height: 100%;
-	margin: 0;
-	padding: 0;
-	border: 0;
-    }
-
-    .tool_container .panes {
-	position: relative;
-	height: 100%;
-	width: 100%;
-	overflow: hidden;
-    }
-
-    .tool_container .panes .pane {
-	position: absolute;
-	overflow: auto;
-	top: 0;
-	left: 0;
-	right: 0;
-	bottom: 0;
-	background: #fefefe;
-    }
-
-    .tool_container .multi_pane {
-	position: relative;
-	height: 100%;
-	width: auto;
-	overflow-x: auto;
-    }
-
-    .tool_container .multi_pane .pane {
-	height: 100%;
-	max-width: 300px;
-	border-right: 1px solid #888;
-    }
-
-    .tool_container .panes .pane > div {
-	height: 100%;
-	position: relative;
-    }
-
-    .tool_container .panes.horizontal > .pane {
-	min-height: 50px;
-    }
-
-    .tool_container .panes.horizontal > .pane {
-	top: 50%;
-    }
-
-    .tool_container .panes.horizontal > .pane:first-child {
-	top: 0;
-	bottom: 50%;
-    }
-
-    .tool_container .panes.vertical > .pane {
-	left: 50%;
-    }
-
-    .tool_container .panes.vertical > .pane:first-child {
-	left: 0;
-	right: 50%;
-    }
-
-
-    .tool_container .splitter {
-	position: absolute;
-	border-width: 0;
-	z-index: 10;
-    }
-
-    .tool_container .splitter.vertical {
-	width: 5px;
-	left: 50%;
-	margin-left: -1px;
-	border-left: 1px solid #888;
-	height: 100%;
-	float: left;
-	cursor: ew-resize;
-    }
-
-    .tool_container .splitter.horizontal {
-	top: 50%;
-	height: 5px;
-	margin-top: -1px;
-	width: 100%;
-	border-top: 1px solid #888;
-	cursor: ns-resize;
-    }
-
-
-
-    .tool_container .panes .pane .nav-pills {
-	position: absolute;
-	overflow-y: auto;
-	top: 17px;
-	bottom: 17px;
-	width: 100%;
-	margin: 0;
-    }
-
-    .tool_container .pane .nav-pills i {
-	display: inline-block;
-	width: 16px;
-	height: 16px;
-	margin-right: 4px;
-	background-image: none;
-	background-position: top left;
-	line-height: 14px;
-	vertical-align: text-top;
-    }
-
-    .tool_container .pane .nav-pills i.announcement {
-	background-image: url('../images/announcement.png');
-    }
-    .tool_container .pane .nav-pills i.class {
-	background-image: url('../images/class.png');
-    }
-    .tool_container .pane .nav-pills i.collection {
-	background-image: url('../images/collection.png');
-    }
-    .tool_container .pane .nav-pills i.test {
-	background-image: url('../images/test.png');
-    }
-    .tool_container .pane .nav-pills i.exception {
-	background-image: url('../images/exception.png');
-    }
-    .tool_container .pane .nav-pills i.widget {
-	background-image: url('../images/widget.png');
-    }
-    .tool_container .pane .nav-pills i.magnitude {
-	background-image: url('../images/magnitude.png');
-    }
-    .tool_container .pane .nav-pills i.package {
-	background-image: url('../images/package.png');
-    }
-    .tool_container .pane .nav-pills i.private {
-	background-image: url('../images/private.png');
-    }
-    .tool_container .pane .nav-pills i.extension {
-	background-image: url('../images/extension.png');
-    }
-    .tool_container .pane .nav-pills i.initialization {
-	background-image: url('../images/initialization.png');
-    }
-    .tool_container .pane .nav-pills i.package {
-	background-image: url('../images/package.png');
-    }
-    .tool_container .pane .nav-pills i.override {
-	background-image: url('../images/override.png ');
-    }
-    .tool_container .pane .nav-pills i.overridden {
-	background-image: url('../images/overridden.png');
-    }
-    .tool_container .pane .nav-pills i.override-overridden {
-	background-image: url('../images/override-overridden.png');
-    }
-    .tool_container .pane .nav-pills i.warning {
-	background-image: url('../images/warning.gif');
-    }
-    .tool_container .pane .nav-pills i.uncommented {
-	background-image: url('../images/uncommented.png');
-    }
-
-
-
-    .tool_container .list-label {
-	font-size: 11px;
-	border-radius: 0;
-	border-bottom: 1px solid #999;
-	border-top: 1px solid #eee;
-	background-color: #eee;
-	background-image: -webkit-linear-gradient(top, #eee, #ddd);
-	background-image: -moz-linear-gradient(top, #eee, #ddd);
-	background-image: -o-linear-gradient(top, #eee, #ddd);
-	background-image: linear-gradient(top, #eee, #ddd);
-	color: #444;
-	font-weight: bold;
-	text-shadow: 0 0 0;
-	padding-left: 4px;
-	line-height: 14px;
-	height: 15px;
-	text-shadow: 0 1px 0 #eee;
-    }
-
-    .tool_container .list-label .btn-group.cog {
-	position: absolute;
-	top: 0;
-	right: 0;
-	padding: 0;
-	margin: 0;
-    }
-
-    .tool_container .list-label .btn-group.open .dropdown-toggle {
-	box-shadow: 0 0 0;
-	border: 0;
-    }
-
-    .tool_container .list-label .btn-group > .dropdown-menu {
-	padding: 0;
-	font-size: 11px;
-    }
-
-    .tool_container .list-label .btn-group.cog i {
-	margin-top: 1px;
-    }
-
-    .tool_container .list-label .cog .btn.dropdown-toggle {
-	padding: 0;
-	margin: 0;
-	line-height: 12px;
-	border: 0;
-	background: transparent;
-    }
-
-
-    .tool_container .panes .pane .pane_actions {
-	position: absolute;
-	overflow: hidden;
-	width: 100%;
-	height: 16px;
-	bottom: 0;
-	padding: 0;
-	margin: 0;
-    }
-
-    .tool_container .pane_actions, .tool_container .buttons_bar {
-	background: #dadada;
-	border-top: 1px solid #666;
-	background-image: -webkit-linear-gradient(top, #dadada, #bdbdbd);
-	background-image: -moz-linear-gradient(top, #dadada, #bdbdbd);
-	background-image: -o-linear-gradient(top, #dadada, #bdbdbd);
-	background-image: linear-gradient(top, #dadada, #bdbdbd);
-    }
-
-    .tool_container .panes .pane .pane_actions .info {
-	padding: 10px 5px 5px;
-	font-weight: bold;
-	color: #666;
-	line-height: 20px;
-    }
-
-    .tool_container .panes .pane .pane_actions .btn-group {
-	display: inline;
-	margin-left: 5px;
-    }
-
-    .tool_container .panes .pane .pane_actions label {
-	display: inline-block;
-	padding-left: 30px;
-	font-size: 11px;
-	line-height: 16px;
-	vertical-align: top;
-	text-shadow: #ddd 0px 1px 0px; 
-	color: #222;
-
-    }
-
-    .tool_container .panes .pane .pane_actions label input {
-	float: none;
-	vertical-align: top;
-	margin-top: 2px;
-	margin-right: 5px;
-    }
-
-    .tool_container .panes .pane .pane_actions .btn {
-	background: transparent;
-	border: 0;
-	font-size: 11px;
-	line-height: 16px;
-	padding: 0 5px;
-	margin: 0;
-	border-radius: 0;
-	box-shadow: 0 0 0;
-	vertical-align: top;
-    /* min-width: 50px; */
-    }
-
-    .tool_container .panes .pane .pane_actions .btn:hover {
-	background-color: #bbb;
-    }
-
-    .tool_container .panes .pane .pane_actions .btn-group .btn:hover {
-	background-color: transparent;
-    }
-
-    .tool_container .panes .pane .pane_actions .btn-group .btn.active {
-	text-shadow: #ddd 0px 1px 0px; 
-	color: #222;
-	background: #bbb;
-	background-image: linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -webkit-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -moz-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -o-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-    }
-
-    .tool_container .panes .pane .class_side .nav-pills {
-	font-weight: bold;
-	background: #ffd
-    }
-
-    .key_helper {
-	z-index: 20;
-	position: fixed;
-	bottom: 0px;
-	background: #fff;
-	background-image: linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-	background-image: -moz-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-	background-image: -o-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-	background-image: -webkit-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-	width: 100%;
-	border-top: 1px solid #aaa;
-	font-size: 11px;
-	height: 22px;
-
-	.command {
-	    padding: 0 2px;
-	}
-
-	#binding-helper-main {
-	    display: inline;
-	}
-
-	.label {
-	    padding: 1px 4px;
-	    font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
-	    background: transparent;
-	    color: #08C;
-	    text-shadow: none;
-	    border: 0 none;
-	}
-
-	.action {
-	    padding: 0 5px;
-	    color: #666;
-	}
-
-	.selected {
-	    background-image: linear-gradient(top, #ccc, #aaa);
-	    background-image: -moz-linear-gradient(top, #ccc, #aaa);
-	    background-image: -o-linear-gradient(top, #ccc, #aaa);
-	    background-image: -webkit-linear-gradient(top, #ccc, #aaa);
-	    height: 30px;
-	    padding: 0 8px;
-	    color: #333;
-	    font-weight: bold;
-	    text-shadow: 0 1px 0 #fff;
-	    display: inline-block;
-	    border-right: 1px solid #aaa;
-	}
-
-	.close {
-	    font-size: 14px;
-	    line-height: 26px;
-	    opacity: 0.6;
-	}
-
-	.close:hover {
-	    opacity: 0.8;
-	}
-
-	input {
-	    outline: none;
-	    font-size: 11px;
-	    padding: 2px 8px;
-	    background: #fff;
-	    border: 1px solid #a1a1a1;
-	    border-radius: 12px;
-	    box-shadow: inset 0 0px 2px 0px #aaa;
-	    margin: 2px 4px;
-	    line-height: 1em;
-	}
-
-	.error .help-inline,
-	.error input {
-	    color: #B91010;
-	    font-weight: bold;
-	}
-
-	.typeahead.dropdown-menu {
-	    position: fixed !important;
-	    top: auto !important;
-	    bottom: 30px !important;
-	}
-
-	#cog-helper {
-	    position: fixed;
-	    bottom: 2px;
-	    right: 2px;
-	    z-index: 1000;
-	    opacity: 0.6;
-	    transition: all .5s;
-	    -webkit-transition: all .5s;
-	    -moz-transition: all .5s;
-	    -o-transition: all .5s;
-	    -ms-transition: all .5s;
-	}
-
-	#cog-helper:hover {
-	    opacity: 1;
-	}
-
-    }
-
-    #helper {
-	z-index: 300;
-	top: 50%;
-	position: absolute;
-	left: 50%;
-	margin-left: -220px;
-	margin-top: -35px;
-	width: 400px;
-	text-align: center;
-	color: #ddd;
-	font-size: 18px;
-	font-weight: bold;
-	text-shadow: 0 -1px 0 #111;
-	padding: 20px;
-	background: rgba(0,0,0, 0.6);
-	border-radius: 40px;
-    }
-
-    #overlay {
-	z-index: 2000;
-	background: transparent;
-	position: fixed;
-	top: 0;
-	left: 0;
-	right: 0;
-	bottom: 0;
-    }
-
-    .confirmation, .dialog {
-	z-index: 2001;
-	background: rgba(243,243,243,0.9);
-	background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
-	background-image: -moz-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
-	background-image: -o-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
-	background-image: linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
-	padding: 20px;
-	width: 250px;
-	position: fixed;
-	top: -500px;
-	left: 50%;
-	margin-left: -135px;
-	box-shadow: 0 0 6px #333;
-	transition: top .5s;
-	-webkit-transition: top .5s;
-	-moz-transition: top .5s;
-	-o-transition: top .5s;
-
-	.hl_widget {
-	
-	    &:focus {
-		outline: 0 none;
-	    }
-
-	    .form-actions {
+	.CodeMirror-hints {
+		border-radius: 0;
+		font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
+		font-size: 11px;
+		line-height: 1em;
+		padding: 0;
+		max-height: 120px;
+	}
+
+	.CodeMirror-hint {
+		border-radius: 0;
+		padding: 0 10px;
+	}
+
+	.CodeMirror pre, .CodeMirror .CodeMirror-gutter-elt {
+		font-family: Menlo, Monaco, "Lucida Console",  "Ubuntu Mono", Courier, monospace;
+		line-height: 16px;
+		font-size: 13px;
+	}
+
+	.CodeMirror-gutter.stops {
+		width: 20px;
+	}
+
+	.CodeMirror .highlighted.CodeMirror-linebackground {
+		background-color: #ffffaa;
+	}
+
+	.CodeMirror .CodeMirror-gutter-elt .stop {
+		width: 16px;
+		height: 16px;
+		background: url('../images/arrowRight.png');
+		margin-left: 2px;
+	}
+
+	.state {
+		position: absolute;
+		right: 15px;
+		top: 10px;
+		width: 16px;
+		height: 16px;
+	}
+
+	.state.modified {
+		background: transparent url('../images/modified.png') 50% 50% no-repeat;
+	}
+
+	.editor {
+		position: absolute;
+		top: 0;
+		bottom: 23px;
+		left: 0;
+		right: 0;
+	}
+
+	.buttons_bar {
+		position: absolute;
+		bottom: 0;
+		right: 0;
+		left: 0;
+		z-index: 2;
+		padding: 0px 25px;
+		height: 21px;
+		line-height: 18px;
+		border-top: 1px solid #999;
+		text-align: right;
+
+		.button {
+			height: 17px;
+			font-size: 12px;
+			min-width: 0;
+		}
+	}
+
+	.btn, .btn-group > .btn, .btn-group > .dropdown-menu {
+		padding: 2px 8px;
+	}
+
+	.navbar-fixed-top {
+		font-size: 11px;
+		line-height: 16px;
+	}
+
+	.navbar-fixed-top a span,
+	.dialog .nav a span {
+		padding: 1px;
+		padding-left: 18px;
+		background-position: center left;
+		background-repeat: no-repeat;
+		background-position: 0px -1px;
+	}
+
+	.navbar-fixed-top i.close {
+		width: 14px;
+		height: 16px;
+		margin-left: 4px;
+		background-image: url('../images/close.gif');
+		margin-right: 0;
+		background-position: center left;
+		margin-top: 2px;
+	}
+
+	.navbar-fixed-top a,
+	.dialog .nav a {
+
+		span.references {
+			background-image: url('../images/references.png')
+		}
+
+		span.browser {
+			background-image: url('../images/browser.png')
+		}
+
+		span.sunit {
+			background-image: url('../images/sunit.png')
+		}
+
+		span.workspace {
+			background-image: url('../images/workspace.png')
+		}
+
+		span.debugger {
+			background-image: url('../images/debugger.png')
+		}
+		span.inspector {
+			background-image: url('../images/inspector.png')
+		}
+	}
+
+
+	.navbar-fixed-top .navbar-inner {
+		min-height: 20px;
+		background-color: #dbdbdb;
+		border-bottom: 1px solid #666;
+		background-image: linear-gradient(top, #dfdfdf, #d0d0d0);
+		background-image: -webkit-linear-gradient(top, #dfdfdf, #d0d0d0);
+		background-image: -moz-linear-gradient(top, #dfdfdf, #d0d0d0);
+		background-image: -owebkit-linear-gradient(top, #dfdfdf, #d0d0d0);
+		box-shadow: 0 0 0;
+	}
+
+
+	.navbar .nav > li {
+		line-height: 16px;
+	}
+
+
+	.navbar .nav > li > a {
+		line-height: 22px;
+		padding: 0px 8px;
+		font-size: 11px;
+		color: #444;
+		text-shadow: 0 1px 0 #ddd;
+	}
+
+	.nav > li > a:hover {
+		background: transparent;
+	}
+
+	.navbar .nav > .active > a, 
+	.navbar .nav > .active > a:hover, 
+	.navbar .nav > .active > a:focus {
+		background-color: #bababa;
+		background-image: linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -webkit-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -moz-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -o-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		text-shadow: #ddd 0px 1px 0px; 
+		color: #222;
+	}
+
+	.navbar-fixed-top i {
+		opacity: 0.4;
+		margin-right: 5px;
+		height: 12px;
+		margin-top: 0;
+	}
+
+	.navbar-fixed-top .active i {
+		opacity: 0.6;
+	}
+
+	.nav-pills.nav-stacked > li > a {
+		border-radius: 0;
+		-webkit-border-radius: 0;
+		-moz-border-radius: 0;
+		padding: 2px 2px 1px 4px;
+		margin: 0;
+		font-size: 11px;
+		color: #111;
+		white-space: nowrap;
+	}
+
+	[class^="icon-"], [class*=" icon-"] {
+		margin-right: 2px;
+	}
+
+	.dropdown-menu {
+		border-radius: 0;
+		padding: 0;
+		margin: 3px;
+	}
+
+	.nav-pills > .active > a {
+		background-color: #ddd;
+		color: #fff;
+		text-shadow: 0 0 0;
+	}
+
+	.focused .nav-pills {
+		background-color: #f3f7fb;
+	}
+
+	.focused .nav-pills > .active > a, 
+	.nav-pills > .active > a:hover,
+	.dropdown-menu li > a:hover, 
+	.dropdown-menu li > a:focus, 
+	.dropdown-submenu:hover > a,
+	.dropdown-menu .active > a, 
+	.dropdown-menu .active > a:hover,
+	.CodeMirror-hint-active {
+		background: rgba(95, 159, 228, 0.62);
+		color: #fff;
+		text-shadow: 0 0 0;
+	}
+
+
+	.tool_container {
+		position: absolute;
+		top: 23px;
+		bottom: 0;
+		left: 0;
+		right: 0;
+	}
+
+	.transcript textarea {
+		width: 100%;
+		height: 100%;
+		margin: 0;
 		padding: 0;
 		border: 0;
-	    }
 	}
 
-	.nav {
-	    border: 1px solid #999;
+	.tool_container .panes {
+		position: relative;
+		height: 100%;
+		width: 100%;
+		overflow: hidden;
+	}
+
+	.tool_container .panes .pane {
+		position: absolute;
+		overflow: auto;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background: #fefefe;
+	}
+
+	.tool_container .multi_pane {
+		position: relative;
+		height: 100%;
+		width: auto;
+		overflow-x: auto;
+	}
+
+	.tool_container .multi_pane .pane {
+		height: 100%;
+		max-width: 300px;
+		border-right: 1px solid #888;
+	}
+
+	.tool_container .panes .pane > div {
+		height: 100%;
+		position: relative;
+	}
+
+	.tool_container .panes.horizontal > .pane {
+		min-height: 50px;
+	}
+
+	.tool_container .panes.horizontal > .pane {
+		top: 50%;
+	}
+
+	.tool_container .panes.horizontal > .pane:first-child {
+		top: 0;
+		bottom: 50%;
+	}
+
+	.tool_container .panes.vertical > .pane {
+		left: 50%;
+	}
+
+	.tool_container .panes.vertical > .pane:first-child {
+		left: 0;
+		right: 50%;
+	}
+
+
+	.tool_container .splitter {
+		position: absolute;
+		border-width: 0;
+		z-index: 10;
+	}
+
+	.tool_container .splitter.vertical {
+		width: 5px;
+		left: 50%;
+		margin-left: -1px;
+		border-left: 1px solid #888;
+		height: 100%;
+		float: left;
+		cursor: ew-resize;
+	}
+
+	.tool_container .splitter.horizontal {
+		top: 50%;
+		height: 5px;
+		margin-top: -1px;
+		width: 100%;
+		border-top: 1px solid #888;
+		cursor: ns-resize;
+	}
+
+
+
+	.tool_container .panes .pane .nav-pills {
+		position: absolute;
+		overflow-y: auto;
+		top: 17px;
+		bottom: 17px;
+		width: 100%;
+		margin: 0;
+	}
+
+	.tool_container .pane .nav-pills i {
+		display: inline-block;
+		width: 16px;
+		height: 16px;
+		margin-right: 4px;
+		background-image: none;
+		background-position: top left;
+		line-height: 14px;
+		vertical-align: text-top;
+	}
 
-	    span {
+	.tool_container .pane .nav-pills i.announcement {
+		background-image: url('../images/announcement.png');
+	}
+	.tool_container .pane .nav-pills i.class {
+		background-image: url('../images/class.png');
+	}
+	.tool_container .pane .nav-pills i.collection {
+		background-image: url('../images/collection.png');
+	}
+	.tool_container .pane .nav-pills i.test {
+		background-image: url('../images/test.png');
+	}
+	.tool_container .pane .nav-pills i.exception {
+		background-image: url('../images/exception.png');
+	}
+	.tool_container .pane .nav-pills i.widget {
+		background-image: url('../images/widget.png');
+	}
+	.tool_container .pane .nav-pills i.magnitude {
+		background-image: url('../images/magnitude.png');
+	}
+	.tool_container .pane .nav-pills i.package {
+		background-image: url('../images/package.png');
+	}
+	.tool_container .pane .nav-pills i.private {
+		background-image: url('../images/private.png');
+	}
+	.tool_container .pane .nav-pills i.extension {
+		background-image: url('../images/extension.png');
+	}
+	.tool_container .pane .nav-pills i.initialization {
+		background-image: url('../images/initialization.png');
+	}
+	.tool_container .pane .nav-pills i.package {
+		background-image: url('../images/package.png');
+	}
+	.tool_container .pane .nav-pills i.override {
+		background-image: url('../images/override.png ');
+	}
+	.tool_container .pane .nav-pills i.overridden {
+		background-image: url('../images/overridden.png');
+	}
+	.tool_container .pane .nav-pills i.override-overridden {
+		background-image: url('../images/override-overridden.png');
+	}
+	.tool_container .pane .nav-pills i.warning {
+		background-image: url('../images/warning.gif');
+	}
+	.tool_container .pane .nav-pills i.uncommented {
+		background-image: url('../images/uncommented.png');
+	}
+
+
+
+	.tool_container .list-label {
+		font-size: 11px;
+		border-radius: 0;
+		border-bottom: 1px solid #999;
+		border-top: 1px solid #eee;
+		background-color: #eee;
+		background-image: -webkit-linear-gradient(top, #eee, #ddd);
+		background-image: -moz-linear-gradient(top, #eee, #ddd);
+		background-image: -o-linear-gradient(top, #eee, #ddd);
+		background-image: linear-gradient(top, #eee, #ddd);
+		color: #444;
+		font-weight: bold;
+		text-shadow: 0 0 0;
+		padding-left: 4px;
+		line-height: 14px;
+		height: 15px;
+		text-shadow: 0 1px 0 #eee;
+	}
+
+	.tool_container .list-label .btn-group.cog {
+		position: absolute;
+		top: 0;
+		right: 0;
+		padding: 0;
+		margin: 0;
+	}
+
+	.tool_container .list-label .btn-group.open .dropdown-toggle {
+		box-shadow: 0 0 0;
+		border: 0;
+	}
+
+	.tool_container .list-label .btn-group > .dropdown-menu {
+		padding: 0;
+		font-size: 11px;
+	}
+
+	.tool_container .list-label .btn-group.cog i {
+		margin-top: 1px;
+	}
+
+	.tool_container .list-label .cog .btn.dropdown-toggle {
+		padding: 0;
+		margin: 0;
+		line-height: 12px;
+		border: 0;
+		background: transparent;
+	}
+
+
+	.tool_container .panes .pane .pane_actions {
+		position: absolute;
+		overflow: hidden;
+		width: 100%;
+		height: 16px;
+		bottom: 0;
+		padding: 0;
+		margin: 0;
+	}
+
+	.tool_container .pane_actions, .tool_container .buttons_bar {
+		background: #dadada;
+		border-top: 1px solid #666;
+		background-image: -webkit-linear-gradient(top, #dadada, #bdbdbd);
+		background-image: -moz-linear-gradient(top, #dadada, #bdbdbd);
+		background-image: -o-linear-gradient(top, #dadada, #bdbdbd);
+		background-image: linear-gradient(top, #dadada, #bdbdbd);
+	}
+
+	.tool_container .panes .pane .pane_actions .info {
+		padding: 10px 5px 5px;
+		font-weight: bold;
+		color: #666;
+		line-height: 20px;
+	}
+
+	.tool_container .panes .pane .pane_actions .btn-group {
+		display: inline;
+		margin-left: 5px;
+	}
+
+	.tool_container .panes .pane .pane_actions label {
+		display: inline-block;
+		padding-left: 30px;
+		font-size: 11px;
+		line-height: 16px;
+		vertical-align: top;
+		text-shadow: #ddd 0px 1px 0px; 
+		color: #222;
+
+	}
+
+	.tool_container .panes .pane .pane_actions label input {
+		float: none;
+		vertical-align: top;
+		margin-top: 2px;
+		margin-right: 5px;
+	}
+
+	.tool_container .panes .pane .pane_actions .btn {
+		background: transparent;
+		border: 0;
+		font-size: 11px;
+		line-height: 16px;
+		padding: 0 5px;
+		margin: 0;
+		border-radius: 0;
+		box-shadow: 0 0 0;
+		vertical-align: top;
+	/* min-width: 50px; */
+	}
+
+	.tool_container .panes .pane .pane_actions .btn:hover {
+		background-color: #bbb;
+	}
+
+	.tool_container .panes .pane .pane_actions .btn-group .btn:hover {
+		background-color: transparent;
+	}
+
+	.tool_container .panes .pane .pane_actions .btn-group .btn.active {
+		text-shadow: #ddd 0px 1px 0px; 
+		color: #222;
+		background: #bbb;
+		background-image: linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -webkit-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -moz-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -o-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+	}
+
+	.tool_container .panes .pane .class_side .nav-pills {
+		font-weight: bold;
+		background: #ffd
+	}
+
+	.key_helper {
+		z-index: 20;
+		position: fixed;
+		bottom: 0px;
+		background: #fff;
+		background-image: linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
+		background-image: -moz-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
+		background-image: -o-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
+		background-image: -webkit-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
+		width: 100%;
+		border-top: 1px solid #aaa;
+		font-size: 11px;
+		height: 22px;
+
+		.command {
+			padding: 0 2px;
+		}
+
+		#binding-helper-main {
+			display: inline;
+		}
+
+		.label {
+			padding: 1px 4px;
+			font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
+			background: transparent;
+			color: #08C;
+			text-shadow: none;
+			border: 0 none;
+		}
+
+		.action {
+			padding: 0 5px;
+			color: #666;
+		}
+
+		.selected {
+			background-image: linear-gradient(top, #ccc, #aaa);
+			background-image: -moz-linear-gradient(top, #ccc, #aaa);
+			background-image: -o-linear-gradient(top, #ccc, #aaa);
+			background-image: -webkit-linear-gradient(top, #ccc, #aaa);
+			height: 30px;
+			padding: 0 8px;
+			color: #333;
+			font-weight: bold;
+			text-shadow: 0 1px 0 #fff;
+			display: inline-block;
+			border-right: 1px solid #aaa;
+		}
+
+		.close {
+			font-size: 14px;
+			line-height: 26px;
+			opacity: 0.6;
+		}
+
+		.close:hover {
+			opacity: 0.8;
+		}
+
+		input {
+			outline: none;
+			font-size: 11px;
+			padding: 2px 8px;
+			background: #fff;
+			border: 1px solid #a1a1a1;
+			border-radius: 12px;
+			box-shadow: inset 0 0px 2px 0px #aaa;
+			margin: 2px 4px;
+			line-height: 1em;
+		}
+
+		.error .help-inline,
+		.error input {
+			color: #B91010;
+			font-weight: bold;
+		}
+
+		.typeahead.dropdown-menu {
+			position: fixed !important;
+			top: auto !important;
+			bottom: 30px !important;
+		}
+
+		#cog-helper {
+			position: fixed;
+			bottom: 2px;
+			right: 2px;
+			z-index: 1000;
+			opacity: 0.6;
+			transition: all .5s;
+			-webkit-transition: all .5s;
+			-moz-transition: all .5s;
+			-o-transition: all .5s;
+			-ms-transition: all .5s;
+		}
+
+		#cog-helper:hover {
+			opacity: 1;
+		}
+
+	}
+
+	#helper {
+		z-index: 300;
+		top: 50%;
+		position: absolute;
+		left: 50%;
+		margin-left: -220px;
+		margin-top: -35px;
+		width: 400px;
+		text-align: center;
+		color: #ddd;
+		font-size: 18px;
+		font-weight: bold;
+		text-shadow: 0 -1px 0 #111;
+		padding: 20px;
+		background: rgba(0,0,0, 0.6);
+		border-radius: 40px;
+	}
+
+	#overlay {
+		z-index: 2000;
+		background: transparent;
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+	}
+
+	.confirmation, .dialog {
+		z-index: 2001;
+		background: rgba(243,243,243,0.9);
+		background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
+		background-image: -moz-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
+		background-image: -o-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
+		background-image: linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
+		padding: 20px;
+		width: 250px;
+		position: fixed;
+		top: -500px;
+		left: 50%;
+		margin-left: -135px;
+		box-shadow: 0 0 6px #333;
+		transition: top .5s;
+		-webkit-transition: top .5s;
+		-moz-transition: top .5s;
+		-o-transition: top .5s;
+
+		.hl_widget {
+			
+			&:focus {
+				outline: 0 none;
+			}
+
+			.form-actions {
+				padding: 0;
+				border: 0;
+			}
+		}
+
+		.nav {
+			border: 1px solid #999;
+
+			span {
+				font-size: 11px;
+				font-weight: normal;
+			}
+		}
+
+		.title {
+			font-size: 16px;
+			margin-bottom: 15px;
+		}
+
+		.large {
+			width: 400px;
+			margin-left: -220px;
+
+			textarea {
+				width: 385px;
+				height: 200px;
+			}
+		}
+
+		textarea {
+			display: block;
+			width: 235px;
+		}
+
+		.progress {
+			height: 5px;
+
+			.bar {
+				background-color: #e9eaf5;
+				background-image: -webkit-linear-gradient(top, #B1BDD5, #8999b8);
+				background-image: -moz-linear-gradient(top, #B1BDD5, #8999b8);
+				background-image: -o-linear-gradient(top, #B1BDD5, #8999b8);
+				background-image: linear-gradient(top, #B1BDD5, #8999b8);
+			}
+		}
+
+		span {
+			font-size: 13px;
+			font-weight: bold;
+		}
+
+		.buttons {
+			text-align: right;
+			margin-top: 20px;
+		}
+
+		&.active {
+			top: 0;
+		}
+	}
+
+	.button {
+		border-radius: 3px !important;
+		background: #ccc;
+		border: 1px solid #9B9B9B;
+		height: 20px;
+		border-radius: 5px;
+		min-width: 68px;
+		padding: 0 10px;
+		text-align: center;
+		margin: 0;
+		margin-left: 10px;
+		background: -webkit-linear-gradient(bottom, rgba(0,0,0,.09) 0%, rgba(0,0,0, 0.02) 50%, rgba(0,0,0,.04) 50.5%, rgba(0,0,0,.04) 100%) #fff;
+		font: 13px "Lucida Grande", Lucida, Verdana, sans-serif;
+	}
+
+	.button.default { 
+		border-top: 1px solid #535273;
+		border: 1px solid #4F4D67;
+		border-bottom: 1px solid #4B4B58;	 
+		background: -webkit-linear-gradient(bottom, rgba(255,255,255,.5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255,255,255,.3) 50.5%, rgba(255,255,255,.45) 95%, rgba(255,255,255,.8) 100%) #b1bdd5;
+		background: -moz-linear-gradient(bottom, rgba(255,255,255,.5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255,255,255,.3) 50.5%, rgba(255,255,255,.45) 95%, rgba(255,255,255,.8) 100%) #b1bdd5;
+		-moz-box-shadow: 0 0 3px rgba(69, 113, 184, 0.8);
+		-webkit-box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
+		box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
+	}
+
+
+	.button:hover {
+		cursor: pointer;
+		border: 1px solid rgba(0,0,0,.6);
+	}
+
+	.button:active {
+		-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,.5);
+		-moz-box-shadow: inset 0 0 5px rgba(0,0,0,.5);
+		box-shadow: inset 0 0 5px rgba(0,0,0,.5);
+	}
+
+	.button:focus {
+		outline: 0;
+	}
+
+	.doc {
+		background: white;
+	}
+
+	.doc code .doc pre {
 		font-size: 11px;
-		font-weight: normal;
-	    }
 	}
 
-	.title {
-	    font-size: 16px;
-	    margin-bottom: 15px;
-	}
-
-	.large {
-	    width: 400px;
-	    margin-left: -220px;
-
-	    textarea {
-		width: 385px;
-		height: 200px;
-	    }
-	}
-
-	textarea {
-	    display: block;
-	    width: 235px;
-	}
-
-	.progress {
-	    height: 5px;
-
-	    .bar {
-		background-color: #e9eaf5;
-		background-image: -webkit-linear-gradient(top, #B1BDD5, #8999b8);
-		background-image: -moz-linear-gradient(top, #B1BDD5, #8999b8);
-		background-image: -o-linear-gradient(top, #B1BDD5, #8999b8);
-		background-image: linear-gradient(top, #B1BDD5, #8999b8);
-	    }
-	}
-
-	span {
-	    font-size: 13px;
-	    font-weight: bold;
-	}
-
-	.buttons {
-	    text-align: right;
-	    margin-top: 20px;
-	}
-
-	&.active {
-	    top: 0;
-	}
-    }
-
-    .button {
-	border-radius: 3px !important;
-	background: #ccc;
-	border: 1px solid #9B9B9B;
-	height: 20px;
-	border-radius: 5px;
-	min-width: 68px;
-	padding: 0 10px;
-	text-align: center;
-	margin: 0;
-	margin-left: 10px;
-	background: -webkit-linear-gradient(bottom, rgba(0,0,0,.09) 0%, rgba(0,0,0, 0.02) 50%, rgba(0,0,0,.04) 50.5%, rgba(0,0,0,.04) 100%) #fff;
-	font: 13px "Lucida Grande", Lucida, Verdana, sans-serif;
-    }
-
-    .button.default { 
-	border-top: 1px solid #535273;
-	border: 1px solid #4F4D67;
-	border-bottom: 1px solid #4B4B58;    
-	background: -webkit-linear-gradient(bottom, rgba(255,255,255,.5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255,255,255,.3) 50.5%, rgba(255,255,255,.45) 95%, rgba(255,255,255,.8) 100%) #b1bdd5;
-	background: -moz-linear-gradient(bottom, rgba(255,255,255,.5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255,255,255,.3) 50.5%, rgba(255,255,255,.45) 95%, rgba(255,255,255,.8) 100%) #b1bdd5;
-	-moz-box-shadow: 0 0 3px rgba(69, 113, 184, 0.8);
-	-webkit-box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
-	box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
-    }
-
-
-    .button:hover {
-	cursor: pointer;
-	border: 1px solid rgba(0,0,0,.6);
-    }
-
-    .button:active {
-	-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,.5);
-	-moz-box-shadow: inset 0 0 5px rgba(0,0,0,.5);
-	box-shadow: inset 0 0 5px rgba(0,0,0,.5);
-    }
-
-    .button:focus {
-	outline: 0;
-    }
-
-    .doc {
-	background: white;
-    }
-
-    .doc code .doc pre {
-	font-size: 11px;
-    }
-
-    .doc code {
-	padding: 1px 4px;
-    }
-    .doc .head {
-	background: #08C;
-	padding: 10px;
-	font-size: 22px;
-	color: white;
-    }
-
-    .doc .button {
-	float: right;
-    }
-    .doc .markdown,
-    .doc .inheritance {
-	padding: 10px;
-    }
-
-    .doc h1 {
-	font-size: 22px;
-	margin: 0 10px;
-	border-bottom: 1px solid #666;
-    }
-
-    .doc h2 {
-	font-size: 16px;
-    }
-
-    .transcript_container .list-label {
-	height: 16px;
-	position: absolute;
-	top: 0;
-	right: 0;
-	left: 0;
-    }
-
-    .transcript {
-	position: absolute;
-	top: 17px;
-	bottom: 0;
-	left: 0;
-	right: 0;
-    }
-
-    .transcript textarea {
-	width: 100%;
-	height: 100%;
-	margin: 0;
-	padding: 0;
-	border: 0;
-    }
+	.doc code {
+		padding: 1px 4px;
+	}
+	.doc .head {
+		background: #08C;
+		padding: 10px;
+		font-size: 22px;
+		color: white;
+	}
+
+	.doc .button {
+		float: right;
+	}
+	.doc .markdown,
+	.doc .inheritance {
+		padding: 10px;
+	}
+
+	.doc h1 {
+		font-size: 22px;
+		margin: 0 10px;
+		border-bottom: 1px solid #666;
+	}
+
+	.doc h2 {
+		font-size: 16px;
+	}
+
+	.transcript_container .list-label {
+		height: 16px;
+		position: absolute;
+		top: 0;
+		right: 0;
+		left: 0;
+	}
+
+	.transcript {
+		position: absolute;
+		top: 17px;
+		bottom: 0;
+		left: 0;
+		right: 0;
+	}
+
+	.transcript textarea {
+		width: 100%;
+		height: 100%;
+		margin: 0;
+		padding: 0;
+		border: 0;
+	}
 }

+ 10 - 15
grunt/tasks/grunt-peg.js

@@ -1,29 +1,24 @@
 module.exports = function(grunt) {
 
-  var PEG = require('pegjs');
+	var PEG = require('pegjs');
 
-  /**
-    Full config looks like this:
-    pegjs: {
-       my_parser: {
-         options: {                       // optional
-           trackLineAndColumn: true,      // default: false
-           cache: true,                   // default: false
-           export_var: 'smalltalk.parser' // default: module.exports
-         },
-         src: 'parser.pegjs',
-         dest: 'parser.js',
-       }
+	/**
+     Full config looks like this:
+     pegjs: {
+     my_parser: {
+     options: {                       // optional
+     cache: true,                   // default: false
+     export_var: 'smalltalk.parser' // default: module.exports
      },
    */
   grunt.registerMultiTask('peg', 'Generate JavaScript parser from PEG.js grammar description', function() {
     var options = this.options({
       cache: false,
-      trackLineAndColumn: false,
+      output: 'source',
       export_var: 'module.exports'
     });
     var parser = PEG.buildParser(grunt.file.read(this.data.src), options);
-    var content = 'define("amber_vm/parser", ["./smalltalk", "./nil"], function(smalltalk, nil) {\n'+options.export_var + ' = ' + parser.toSource() + ';\n});';
+    var content = 'define("amber_vm/parser", ["./globals", "./nil"], function(globals, nil) {\n'+options.export_var + ' = ' + parser + ';\n});';
     grunt.file.write(this.data.dest, content);
   });
 };

+ 3 - 3
helios.html

@@ -20,9 +20,9 @@
                           return 'Do you want to close Amber? All uncommitted changes will be lost.';
                       };
 
-                      smalltalk.defaultAmdNamespace = "amber_core";
-                      smalltalk.initialize();
-					  smalltalk.HLManager._setup();
+                      smalltalk.vm.defaultAmdNamespace = "amber_core";
+                      smalltalk.vm.initialize();
+					  smalltalk.globals.HLManager._setup();
                   }
           );
       </script>

+ 4 - 2
js/Benchfib.js

@@ -114,11 +114,12 @@ selector: "jsbenchFib",
 protocol: '*Benchfib',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 if (this < 2) {
 return 1;
 } else {
 return (this-1)._jsbenchFib() + (this-2)._jsbenchFib() + 1;};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"jsbenchFib",{},globals.Number)})},
 args: [],
 source: "jsbenchFib\x0a\x0a\x09<if (this < 2) {\x0areturn 1;\x0a} else {\x0areturn (this-1)._jsbenchFib() + (this-2)._jsbenchFib() + 1;}>",
 messageSends: [],
@@ -132,6 +133,7 @@ selector: "jsbenchmark",
 protocol: '*Benchfib',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 var size = 8190;
 var count;
@@ -154,7 +156,7 @@ for (var z=0;z<this;z++) {
 	}
 }
 return count;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"jsbenchmark",{},globals.Number)})},
 args: [],
 source: "jsbenchmark\x0a\x0a<\x0avar size = 8190;\x0avar count;\x0afor (var z=0;z<this;z++) {\x0a\x09count = 0;\x0a\x09var flags = new Array();\x0a\x09for (var p=0; p<size; p++) {\x0a\x09flags[p] = true;\x0a\x09}\x0a\x09for (var i=1;i<=size;i++) {\x0a\x09\x09if (flags[i-1]) {\x0a\x09\x09\x09var prime = i+1;\x0a\x09\x09\x09var k = i + prime;\x0a\x09\x09\x09while (k <= size) {\x0a\x09\x09\x09\x09flags[k-1] = false;\x0a\x09\x09\x09\x09k = k + prime;\x0a\x09\x09\x09}\x0a\x09\x09\x09count = count + 1;\x0a\x09\x09}\x0a\x09}\x0a}\x0areturn count>",
 messageSends: [],

+ 24 - 12
js/Canvas.js

@@ -64,8 +64,9 @@ selector: "isAvailable",
 protocol: 'testing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return typeof window !== "undefined" && typeof jQuery !== "undefined";
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"isAvailable",{},globals.BrowserInterface)})},
 args: [],
 source: "isAvailable\x0a<return typeof window !== \x22undefined\x22 && typeof jQuery !== \x22undefined\x22>",
 messageSends: [],
@@ -2437,8 +2438,9 @@ selector: "isDOMAvailable",
 protocol: 'instance creation',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  return typeof document !== 'undefined' ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"isDOMAvailable",{},globals.HTMLSnippet.klass)})},
 args: [],
 source: "isDOMAvailable\x0a\x09< return typeof document !== 'undefined' >",
 messageSends: [],
@@ -2589,13 +2591,14 @@ selector: "appendChild:",
 protocol: 'adding',
 fn: function (anElement){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 var element=self['@element'];
 	if (null == element.canHaveChildren || element.canHaveChildren) {
 		element.appendChild(anElement);
 	} else {
 		element.text = String(element.text) + anElement.innerHTML;
 	} ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"appendChild:",{anElement:anElement},globals.TagBrush)})},
 args: ["anElement"],
 source: "appendChild: anElement\x0a\x09\x22In IE7 and IE8 appendChild fails on several node types. So we need to check\x22\x0a\x09<var element=self['@element'];\x0a\x09if (null == element.canHaveChildren || element.canHaveChildren) {\x0a\x09\x09element.appendChild(anElement);\x0a\x09} else {\x0a\x09\x09element.text = String(element.text) + anElement.innerHTML;\x0a\x09} >",
 messageSends: [],
@@ -2609,8 +2612,9 @@ selector: "appendDocumentFragment:",
 protocol: 'private',
 fn: function (anElement){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 var element=self['@element'].appendChild(anElement["@element"]);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"appendDocumentFragment:",{anElement:anElement},globals.TagBrush)})},
 args: ["anElement"],
 source: "appendDocumentFragment: anElement\x0a\x09<var element=self['@element'].appendChild(anElement[\x22@element\x22])>",
 messageSends: [],
@@ -2696,8 +2700,9 @@ selector: "at:ifAbsent:",
 protocol: 'attributes',
 fn: function (aString,aBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self['@element'].hasAttribute(aString) ? self['@element'].getAttribute(aString) : aBlock._value();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"at:ifAbsent:",{aString:aString,aBlock:aBlock},globals.TagBrush)})},
 args: ["aString", "aBlock"],
 source: "at: aString ifAbsent: aBlock\x0a\x09<return self['@element'].hasAttribute(aString) ? self['@element'].getAttribute(aString) : aBlock._value()>",
 messageSends: [],
@@ -2711,8 +2716,9 @@ selector: "at:put:",
 protocol: 'attributes',
 fn: function (aString,aValue){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self['@element'].setAttribute(aString, aValue); return aValue;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"at:put:",{aString:aString,aValue:aValue},globals.TagBrush)})},
 args: ["aString", "aValue"],
 source: "at: aString put: aValue\x0a\x09<self['@element'].setAttribute(aString, aValue); return aValue>",
 messageSends: [],
@@ -2726,8 +2732,9 @@ selector: "class:",
 protocol: 'attributes',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self['@element'].className = aString;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"class:",{aString:aString},globals.TagBrush)})},
 args: ["aString"],
 source: "class: aString\x0a\x09<self['@element'].className = aString>",
 messageSends: [],
@@ -2807,8 +2814,9 @@ selector: "createElementFor:",
 protocol: 'private',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return document.createElement(String(aString));
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"createElementFor:",{aString:aString},globals.TagBrush)})},
 args: ["aString"],
 source: "createElementFor: aString\x0a\x09<return document.createElement(String(aString))>",
 messageSends: [],
@@ -2822,8 +2830,9 @@ selector: "createTextNodeFor:",
 protocol: 'private',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return document.createTextNode(String(aString));
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"createTextNodeFor:",{aString:aString},globals.TagBrush)})},
 args: ["aString"],
 source: "createTextNodeFor: aString\x0a\x09<return document.createTextNode(String(aString))>",
 messageSends: [],
@@ -3416,8 +3425,9 @@ selector: "removeAt:",
 protocol: 'attributes',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self['@element'].removeAttribute(aString);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"removeAt:",{aString:aString},globals.TagBrush)})},
 args: ["aString"],
 source: "removeAt: aString\x0a\x09<self['@element'].removeAttribute(aString)>",
 messageSends: [],
@@ -3832,8 +3842,9 @@ selector: "asJQuery",
 protocol: '*Canvas',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return jQuery(String(self));
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asJQuery",{},globals.String)})},
 args: [],
 source: "asJQuery\x0a\x09<return jQuery(String(self))>",
 messageSends: [],
@@ -3847,8 +3858,9 @@ selector: "asJQuery",
 protocol: '*Canvas',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return jQuery(self['@jsObject']);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asJQuery",{},globals.JSObjectProxy)})},
 args: [],
 source: "asJQuery\x0a\x09<return jQuery(self['@jsObject'])>",
 messageSends: [],

+ 116 - 59
js/Compiler-AST.js

@@ -2,7 +2,7 @@ define("amber_core/Compiler-AST", ["amber_vm/smalltalk", "amber_vm/nil", "amber_
 smalltalk.addPackage('Compiler-AST');
 smalltalk.packages["Compiler-AST"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('Node', globals.Object, ['parent', 'position', 'nodes', 'shouldBeInlined', 'shouldBeAliased'], 'Compiler-AST');
+smalltalk.addClass('Node', globals.Object, ['parent', 'position', 'source', 'nodes', 'shouldBeInlined', 'shouldBeAliased'], 'Compiler-AST');
 globals.Node.comment="I am the abstract root class of the abstract syntax tree.\x0a\x0aConcrete classes should implement `#accept:` to allow visiting.\x0a\x0a`position` holds a point containing line and column number of the symbol location in the original source file.";
 smalltalk.addMethod(
 smalltalk.method({
@@ -476,7 +476,7 @@ globals.Node);
 smalltalk.addMethod(
 smalltalk.method({
 selector: "position:",
-protocol: 'building',
+protocol: 'accessing',
 fn: function (aPosition){
 var self=this;
 self["@position"]=aPosition;
@@ -488,6 +488,52 @@ referencedClasses: []
 }),
 globals.Node);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "positionEnd",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$7,$6,$5,$4,$3,$1;
+$2=self._positionStart();
+$7=self._source();
+$ctx1.sendIdx["source"]=1;
+$6=_st($7)._lines();
+$ctx1.sendIdx["lines"]=1;
+$5=_st($6)._size();
+$ctx1.sendIdx["size"]=1;
+$4=_st($5).__minus((1));
+$ctx1.sendIdx["-"]=1;
+$3=_st($4).__at(_st(_st(_st(_st(self._source())._lines())._last())._size()).__minus((1)));
+$1=_st($2).__plus($3);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"positionEnd",{},globals.Node)})},
+args: [],
+source: "positionEnd\x0a\x09^ self positionStart + ((self source lines size - 1) @ (self source lines last size - 1))",
+messageSends: ["+", "positionStart", "@", "-", "size", "lines", "source", "last"],
+referencedClasses: []
+}),
+globals.Node);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "positionStart",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._position();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"positionStart",{},globals.Node)})},
+args: [],
+source: "positionStart\x0a\x09^ self position",
+messageSends: ["position"],
+referencedClasses: []
+}),
+globals.Node);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "postCopy",
@@ -608,6 +654,62 @@ referencedClasses: []
 }),
 globals.Node);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "size",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._source())._size();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"size",{},globals.Node)})},
+args: [],
+source: "size\x0a\x09^ self source size",
+messageSends: ["size", "source"],
+referencedClasses: []
+}),
+globals.Node);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "source",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@source"];
+if(($receiver = $2) == nil || $receiver == null){
+$1="";
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"source",{},globals.Node)})},
+args: [],
+source: "source\x0a\x09^ source ifNil: [ '' ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+globals.Node);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "source:",
+protocol: 'accessing',
+fn: function (aString){
+var self=this;
+self["@source"]=aString;
+return self},
+args: ["aString"],
+source: "source: aString\x0a\x09source := aString",
+messageSends: [],
+referencedClasses: []
+}),
+globals.Node);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "stopOnStepping",
@@ -1071,7 +1173,7 @@ globals.DynamicDictionaryNode);
 
 
 
-smalltalk.addClass('JSStatementNode', globals.Node, ['source'], 'Compiler-AST');
+smalltalk.addClass('JSStatementNode', globals.Node, [], 'Compiler-AST');
 globals.JSStatementNode.comment="I represent an JavaScript statement node.";
 smalltalk.addMethod(
 smalltalk.method({
@@ -1108,37 +1210,14 @@ globals.JSStatementNode);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "source",
-protocol: 'accessing',
+selector: "requiresSmalltalkContext",
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2=self["@source"];
-if(($receiver = $2) == nil || $receiver == null){
-$1="";
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"source",{},globals.JSStatementNode)})},
+return true;
+},
 args: [],
-source: "source\x0a\x09^ source ifNil: [ '' ]",
-messageSends: ["ifNil:"],
-referencedClasses: []
-}),
-globals.JSStatementNode);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "source:",
-protocol: 'accessing',
-fn: function (aString){
-var self=this;
-self["@source"]=aString;
-return self},
-args: ["aString"],
-source: "source: aString\x0a\x09source := aString",
+source: "requiresSmalltalkContext\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
@@ -1236,30 +1315,6 @@ referencedClasses: []
 }),
 globals.MethodNode);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "extent",
-protocol: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $4,$3,$2,$1;
-$4=self._source();
-$ctx1.sendIdx["source"]=1;
-$3=_st($4)._lines();
-$ctx1.sendIdx["lines"]=1;
-$2=_st($3)._size();
-$ctx1.sendIdx["size"]=1;
-$1=_st($2).__at(_st(_st(_st(_st(self._source())._lines())._last())._size()).__plus((1)));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"extent",{},globals.MethodNode)})},
-args: [],
-source: "extent\x0a\x09^ self source lines size @ (self source lines last size + 1)",
-messageSends: ["@", "size", "lines", "source", "+", "last"],
-referencedClasses: []
-}),
-globals.MethodNode);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageSends",
@@ -1915,6 +1970,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$3,$5,$4,$6,$1;
 $2=_st($SendNode())._new();
 _st($2)._position_(self._position());
+_st($2)._source_(self._source());
 $3=$2;
 $5=self._receiver();
 $ctx1.sendIdx["receiver"]=1;
@@ -1931,8 +1987,8 @@ $1=$6;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"valueForReceiver:",{anObject:anObject},globals.SendNode)})},
 args: ["anObject"],
-source: "valueForReceiver: anObject\x0a\x09^ SendNode new\x0a\x09\x09position: self position;\x0a\x09\x09receiver: (self receiver\x0a\x09\x09ifNil: [ anObject ] \x0a\x09\x09ifNotNil: [ self receiver valueForReceiver: anObject ]);\x0a\x09\x09selector: self selector;\x0a\x09\x09arguments: self arguments;\x0a\x09\x09yourself",
-messageSends: ["position:", "new", "position", "receiver:", "ifNil:ifNotNil:", "receiver", "valueForReceiver:", "selector:", "selector", "arguments:", "arguments", "yourself"],
+source: "valueForReceiver: anObject\x0a\x09^ SendNode new\x0a\x09\x09position: self position;\x0a\x09\x09source: self source;\x0a\x09\x09receiver: (self receiver\x0a\x09\x09ifNil: [ anObject ] \x0a\x09\x09ifNotNil: [ self receiver valueForReceiver: anObject ]);\x0a\x09\x09selector: self selector;\x0a\x09\x09arguments: self arguments;\x0a\x09\x09yourself",
+messageSends: ["position:", "new", "position", "source:", "source", "receiver:", "ifNil:ifNotNil:", "receiver", "valueForReceiver:", "selector:", "selector", "arguments:", "arguments", "yourself"],
 referencedClasses: ["SendNode"]
 }),
 globals.SendNode);
@@ -1970,6 +2026,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$3,$1;
 $2=_st($BlockSequenceNode())._new();
 _st($2)._position_(self._position());
+_st($2)._source_(self._source());
 _st($2)._nodes_(self._nodes());
 _st($2)._temps_(self._temps());
 $3=_st($2)._yourself();
@@ -1977,8 +2034,8 @@ $1=$3;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asBlockSequenceNode",{},globals.SequenceNode)})},
 args: [],
-source: "asBlockSequenceNode\x0a\x09^ BlockSequenceNode new\x0a\x09\x09position: self position;\x0a\x09\x09nodes: self nodes;\x0a\x09\x09temps: self temps;\x0a\x09\x09yourself",
-messageSends: ["position:", "new", "position", "nodes:", "nodes", "temps:", "temps", "yourself"],
+source: "asBlockSequenceNode\x0a\x09^ BlockSequenceNode new\x0a\x09\x09position: self position;\x0a\x09\x09source: self source;\x0a\x09\x09nodes: self nodes;\x0a\x09\x09temps: self temps;\x0a\x09\x09yourself",
+messageSends: ["position:", "new", "position", "source:", "source", "nodes:", "nodes", "temps:", "temps", "yourself"],
 referencedClasses: ["BlockSequenceNode"]
 }),
 globals.SequenceNode);

+ 2 - 1
js/Compiler-Core.js

@@ -420,8 +420,9 @@ selector: "eval:",
 protocol: 'compiling',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return eval(aString);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString},globals.Compiler)})},
 args: ["aString"],
 source: "eval: aString\x0a\x09<return eval(aString)>",
 messageSends: [],

+ 2 - 1
js/Compiler-Exceptions.js

@@ -190,8 +190,9 @@ selector: "basicSignal:",
 protocol: 'error handling',
 fn: function (anError){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 throw anError;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicSignal:",{anError:anError},globals.RethrowErrorHandler)})},
 args: ["anError"],
 source: "basicSignal: anError\x0a        <throw anError>",
 messageSends: [],

+ 45 - 114
js/Compiler-Interpreter.js

@@ -294,6 +294,30 @@ referencedClasses: []
 }),
 globals.AIContext);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "evaluateNode:",
+protocol: 'evaluating',
+fn: function (aNode){
+var self=this;
+function $ASTInterpreter(){return globals.ASTInterpreter||(typeof ASTInterpreter=="undefined"?nil:ASTInterpreter)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=_st($ASTInterpreter())._new();
+_st($2)._context_(self);
+_st($2)._node_(_st(aNode)._nextChild());
+_st($2)._proceed();
+$3=_st($2)._result();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"evaluateNode:",{aNode:aNode},globals.AIContext)})},
+args: ["aNode"],
+source: "evaluateNode: aNode\x0a\x09^ ASTInterpreter new\x0a\x09\x09context: self;\x0a\x09\x09node: aNode nextChild;\x0a\x09\x09proceed;\x0a\x09\x09result",
+messageSends: ["context:", "new", "node:", "nextChild", "proceed", "result"],
+referencedClasses: ["ASTInterpreter"]
+}),
+globals.AIContext);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "evaluatedSelector",
@@ -711,12 +735,20 @@ protocol: 'accessing',
 fn: function (anAIContext){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1;
 self["@outerContext"]=anAIContext;
-_st(self["@outerContext"])._innerContext_(self);
+$1=self["@outerContext"];
+if(($receiver = $1) == nil || $receiver == null){
+$1;
+} else {
+var context;
+context=$receiver;
+_st(context)._innerContext_(self);
+};
 return self}, function($ctx1) {$ctx1.fill(self,"outerContext:",{anAIContext:anAIContext},globals.AIContext)})},
 args: ["anAIContext"],
-source: "outerContext: anAIContext\x0a\x09outerContext := anAIContext.\x0a\x09outerContext innerContext: self",
-messageSends: ["innerContext:"],
+source: "outerContext: anAIContext\x0a\x09outerContext := anAIContext.\x0a\x09outerContext ifNotNil: [ :context | \x0a\x09\x09context innerContext: self ]",
+messageSends: ["ifNotNil:", "innerContext:"],
 referencedClasses: []
 }),
 globals.AIContext);
@@ -925,29 +957,6 @@ referencedClasses: []
 }),
 globals.ASTDebugger);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "buildAST",
-protocol: 'initialization',
-fn: function (){
-var self=this;
-var ast;
-function $Smalltalk(){return globals.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
-function $SemanticAnalyzer(){return globals.SemanticAnalyzer||(typeof SemanticAnalyzer=="undefined"?nil:SemanticAnalyzer)}
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-ast=_st($Smalltalk())._parse_(_st(self._method())._source());
-_st(_st($SemanticAnalyzer())._on_(_st(_st(self._context())._receiver())._class()))._visit_(ast);
-$1=ast;
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"buildAST",{ast:ast},globals.ASTDebugger)})},
-args: [],
-source: "buildAST\x0a\x09\x22Build the AST tree from the method source code.\x0a\x09The AST is annotated with a SemanticAnalyzer,\x0a\x09to know the semantics and bindings of each node needed for later debugging\x22\x0a\x09\x0a\x09| ast |\x0a\x09\x0a\x09ast := Smalltalk parse: self method source.\x0a\x09(SemanticAnalyzer on: self context receiver class)\x0a\x09\x09visit: ast.\x0a\x09\x0a\x09^ ast",
-messageSends: ["parse:", "source", "method", "visit:", "on:", "class", "receiver", "context"],
-referencedClasses: ["Smalltalk", "SemanticAnalyzer"]
-}),
-globals.ASTDebugger);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "context",
@@ -980,64 +989,6 @@ referencedClasses: []
 }),
 globals.ASTDebugger);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "defaultInterpreterClass",
-protocol: 'defaults',
-fn: function (){
-var self=this;
-function $ASTInterpreter(){return globals.ASTInterpreter||(typeof ASTInterpreter=="undefined"?nil:ASTInterpreter)}
-return $ASTInterpreter();
-},
-args: [],
-source: "defaultInterpreterClass\x0a\x09^ ASTInterpreter",
-messageSends: [],
-referencedClasses: ["ASTInterpreter"]
-}),
-globals.ASTDebugger);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "initializeInterpreter",
-protocol: 'initialization',
-fn: function (){
-var self=this;
-var ast,next;
-function $ASTPCNodeVisitor(){return globals.ASTPCNodeVisitor||(typeof ASTPCNodeVisitor=="undefined"?nil:ASTPCNodeVisitor)}
-return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
-ast=self._buildAST();
-$1=_st($ASTPCNodeVisitor())._new();
-_st($1)._context_(self._context());
-_st($1)._visit_(ast);
-$2=_st($1)._currentNode();
-next=$2;
-_st(self._interpreter())._node_(next);
-return self}, function($ctx1) {$ctx1.fill(self,"initializeInterpreter",{ast:ast,next:next},globals.ASTDebugger)})},
-args: [],
-source: "initializeInterpreter\x0a\x09| ast next |\x0a\x09ast := self buildAST.\x0a\x09next := ASTPCNodeVisitor new\x0a\x09\x09context: self context;\x0a\x09\x09visit: ast;\x0a\x09\x09currentNode.\x0a\x09self interpreter node: next",
-messageSends: ["buildAST", "context:", "new", "context", "visit:", "currentNode", "node:", "interpreter"],
-referencedClasses: ["ASTPCNodeVisitor"]
-}),
-globals.ASTDebugger);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "initializeWithContext:",
-protocol: 'initialization',
-fn: function (aContext){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self._context_(aContext);
-self._initializeInterpreter();
-return self}, function($ctx1) {$ctx1.fill(self,"initializeWithContext:",{aContext:aContext},globals.ASTDebugger)})},
-args: ["aContext"],
-source: "initializeWithContext: aContext\x0a\x09\x22TODO: do we need to handle block contexts?\x22\x0a\x09\x0a\x09self context: aContext.\x0a\x09self initializeInterpreter",
-messageSends: ["context:", "initializeInterpreter"],
-referencedClasses: []
-}),
-globals.ASTDebugger);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "interpreter",
@@ -1045,34 +996,13 @@ protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2=self["@interpreter"];
-if(($receiver = $2) == nil || $receiver == null){
-self["@interpreter"]=_st(self._defaultInterpreterClass())._new();
-$1=self["@interpreter"];
-} else {
-$1=$2;
-};
+var $1;
+$1=_st(self._context())._interpreter();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"interpreter",{},globals.ASTDebugger)})},
 args: [],
-source: "interpreter\x0a\x09^ interpreter ifNil: [ interpreter := self defaultInterpreterClass new ]",
-messageSends: ["ifNil:", "new", "defaultInterpreterClass"],
-referencedClasses: []
-}),
-globals.ASTDebugger);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "interpreter:",
-protocol: 'accessing',
-fn: function (anInterpreter){
-var self=this;
-self["@interpreter"]=anInterpreter;
-return self},
-args: ["anInterpreter"],
-source: "interpreter: anInterpreter\x0a\x09interpreter := anInterpreter",
-messageSends: [],
+source: "interpreter\x0a\x09^ self context interpreter",
+messageSends: ["interpreter", "context"],
 referencedClasses: []
 }),
 globals.ASTDebugger);
@@ -1184,11 +1114,12 @@ protocol: 'stepping',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+self._flushOuterContexts();
 _st(self._interpreter())._stepOver();
 return self}, function($ctx1) {$ctx1.fill(self,"stepOver",{},globals.ASTDebugger)})},
 args: [],
-source: "stepOver\x0a\x09self interpreter stepOver",
-messageSends: ["stepOver", "interpreter"],
+source: "stepOver\x0a\x09self flushOuterContexts.\x0a\x09self interpreter stepOver",
+messageSends: ["flushOuterContexts", "stepOver", "interpreter"],
 referencedClasses: []
 }),
 globals.ASTDebugger);
@@ -1203,14 +1134,14 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
 $2=self._new();
-_st($2)._initializeWithContext_(aContext);
+_st($2)._context_(aContext);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"context:",{aContext:aContext},globals.ASTDebugger.klass)})},
 args: ["aContext"],
-source: "context: aContext\x0a\x09^ self new\x0a\x09\x09initializeWithContext: aContext;\x0a\x09\x09yourself",
-messageSends: ["initializeWithContext:", "new", "yourself"],
+source: "context: aContext\x0a\x09^ self new\x0a\x09\x09context: aContext;\x0a\x09\x09yourself",
+messageSends: ["context:", "new", "yourself"],
 referencedClasses: []
 }),
 globals.ASTDebugger.klass);

+ 2 - 1
js/Compiler-Semantic.js

@@ -1402,8 +1402,9 @@ selector: "isVariableGloballyUndefined:",
 protocol: 'testing',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return eval('typeof ' + aString + ' == "undefined"');
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"isVariableGloballyUndefined:",{aString:aString},globals.SemanticAnalyzer)})},
 args: ["aString"],
 source: "isVariableGloballyUndefined: aString\x0a\x09<return eval('typeof ' + aString + ' == \x22undefined\x22')>",
 messageSends: [],

+ 42 - 0
js/Helios-Browser.js

@@ -147,6 +147,48 @@ referencedClasses: []
 }),
 globals.HLBrowser);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "openClassNamed:",
+protocol: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._model())._openClassNamed_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"openClassNamed:",{aString:aString},globals.HLBrowser)})},
+args: ["aString"],
+source: "openClassNamed: aString\x0a\x09self model openClassNamed: aString",
+messageSends: ["openClassNamed:", "model"],
+referencedClasses: []
+}),
+globals.HLBrowser);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "openMethod:",
+protocol: 'actions',
+fn: function (aCompiledMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$4,$3,$5;
+$1=self._model();
+$2=$1;
+$4=_st(aCompiledMethod)._methodClass();
+$ctx1.sendIdx["methodClass"]=1;
+$3=_st($4)._package();
+_st($2)._selectedPackage_($3);
+_st($1)._selectedClass_(_st(aCompiledMethod)._methodClass());
+_st($1)._selectedProtocol_(_st(aCompiledMethod)._protocol());
+_st($1)._selectedMethod_(aCompiledMethod);
+$5=_st($1)._focusOnSourceCode();
+return self}, function($ctx1) {$ctx1.fill(self,"openMethod:",{aCompiledMethod:aCompiledMethod},globals.HLBrowser)})},
+args: ["aCompiledMethod"],
+source: "openMethod: aCompiledMethod\x0a\x09self model \x0a\x09\x09\x09selectedPackage: aCompiledMethod methodClass package;\x0a\x09\x09\x09selectedClass: aCompiledMethod methodClass;\x0a\x09\x09\x09selectedProtocol: aCompiledMethod protocol;\x0a\x09\x09\x09selectedMethod: aCompiledMethod;\x0a\x09\x09\x09focusOnSourceCode",
+messageSends: ["selectedPackage:", "model", "package", "methodClass", "selectedClass:", "selectedProtocol:", "protocol", "selectedMethod:", "focusOnSourceCode"],
+referencedClasses: []
+}),
+globals.HLBrowser);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "packagesListWidget",

+ 89 - 10
js/Helios-Commands-Tools.js

@@ -59,6 +59,88 @@ referencedClasses: []
 globals.HLToolCommand.klass);
 
 
+smalltalk.addClass('HLBrowseMethodCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "displayLabel",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "browse method";
+},
+args: [],
+source: "displayLabel\x0a\x09^ 'browse method'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "execute",
+protocol: 'executing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._model())._openMethod();
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLBrowseMethodCommand)})},
+args: [],
+source: "execute\x0a\x09self model openMethod",
+messageSends: ["openMethod", "model"],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isValidFor:",
+protocol: 'testing',
+fn: function (aModel){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(aModel)._isReferencesModel();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},globals.HLBrowseMethodCommand.klass)})},
+args: ["aModel"],
+source: "isValidFor: aModel\x0a\x09^ aModel isReferencesModel",
+messageSends: ["isReferencesModel"],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "b";
+},
+args: [],
+source: "key\x0a\x09^ 'b'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "browse method";
+},
+args: [],
+source: "label\x0a\x09^ 'browse method'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand.klass);
+
+
 smalltalk.addClass('HLCommitPackageCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
@@ -436,14 +518,11 @@ selector: "isValidFor:",
 protocol: 'testing',
 fn: function (aModel){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(aModel)._isBrowserModel();
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},globals.HLFindClassCommand.klass)})},
+return true;
+},
 args: ["aModel"],
-source: "isValidFor: aModel\x0a\x09^ aModel isBrowserModel",
-messageSends: ["isBrowserModel"],
+source: "isValidFor: aModel\x0a\x09^ true",
+messageSends: [],
 referencedClasses: []
 }),
 globals.HLFindClassCommand.klass);
@@ -498,7 +577,7 @@ $1="";
 } else {
 var class_;
 class_=$receiver;
-$1=_st(class_)._name();
+$1=_st(_st(class_)._theNonMetaClass())._name();
 };
 } else {
 var method;
@@ -508,8 +587,8 @@ $1=_st(method)._selector();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"defaultInput",{},globals.HLFindReferencesCommand)})},
 args: [],
-source: "defaultInput\x0a\x09^ self model selectedMethod \x0a\x09\x09ifNil: [\x0a\x09\x09\x09self model selectedClass\x0a\x09\x09\x09\x09ifNil: [ '' ]\x0a\x09\x09\x09\x09ifNotNil: [ :class | class name ] ]\x0a\x09\x09ifNotNil: [ :method | method selector ]",
-messageSends: ["ifNil:ifNotNil:", "selectedMethod", "model", "selectedClass", "name", "selector"],
+source: "defaultInput\x0a\x09^ self model selectedMethod \x0a\x09\x09ifNil: [\x0a\x09\x09\x09self model selectedClass\x0a\x09\x09\x09\x09ifNil: [ '' ]\x0a\x09\x09\x09\x09ifNotNil: [ :class | class theNonMetaClass name ] ]\x0a\x09\x09ifNotNil: [ :method | method selector ]",
+messageSends: ["ifNil:ifNotNil:", "selectedMethod", "model", "selectedClass", "name", "theNonMetaClass", "selector"],
 referencedClasses: []
 }),
 globals.HLFindReferencesCommand);

+ 11 - 5
js/Helios-Core.js

@@ -1881,14 +1881,19 @@ selector: "openAsTab",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+var instance;
 function $HLManager(){return globals.HLManager||(typeof HLManager=="undefined"?nil:HLManager)}
 function $HLTabWidget(){return globals.HLTabWidget||(typeof HLTabWidget=="undefined"?nil:HLTabWidget)}
 return smalltalk.withContext(function($ctx1) { 
-_st(_st($HLManager())._current())._addTab_(_st($HLTabWidget())._on_labelled_(self._new(),self._tabLabel()));
-return self}, function($ctx1) {$ctx1.fill(self,"openAsTab",{},globals.HLWidget.klass)})},
+var $1;
+instance=self._new();
+_st(_st($HLManager())._current())._addTab_(_st($HLTabWidget())._on_labelled_(instance,self._tabLabel()));
+$1=instance;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"openAsTab",{instance:instance},globals.HLWidget.klass)})},
 args: [],
-source: "openAsTab\x0a\x09HLManager current addTab: (HLTabWidget on: self new labelled: self tabLabel)",
-messageSends: ["addTab:", "current", "on:labelled:", "new", "tabLabel"],
+source: "openAsTab\x0a\x09| instance |\x0a\x09\x0a\x09instance := self new.\x0a\x09HLManager current addTab: (HLTabWidget \x0a\x09\x09on: instance \x0a\x09\x09labelled: self tabLabel).\x0a\x09^ instance",
+messageSends: ["new", "addTab:", "current", "on:labelled:", "tabLabel"],
 referencedClasses: ["HLManager", "HLTabWidget"]
 }),
 globals.HLWidget.klass);
@@ -2415,10 +2420,11 @@ selector: "positionOf:",
 protocol: 'accessing',
 fn: function (aListItem){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
     	return aListItem.parent().children().get().indexOf(aListItem.get(0)) + 1
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"positionOf:",{aListItem:aListItem},globals.HLListWidget)})},
 args: ["aListItem"],
 source: "positionOf: aListItem\x0a\x09<\x0a    \x09return aListItem.parent().children().get().indexOf(aListItem.get(0)) + 1\x0a\x09>",
 messageSends: [],

+ 189 - 56
js/Helios-Debugger.js

@@ -111,14 +111,26 @@ protocol: 'accessing',
 fn: function (){
 var self=this;
 function $HLDebuggerCodeWidget(){return globals.HLDebuggerCodeWidget||(typeof HLDebuggerCodeWidget=="undefined"?nil:HLDebuggerCodeWidget)}
+function $HLDebuggerCodeModel(){return globals.HLDebuggerCodeModel||(typeof HLDebuggerCodeModel=="undefined"?nil:HLDebuggerCodeModel)}
 return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$4,$1;
+var $2,$3,$4,$6,$7,$8,$9,$5,$10,$1;
 $2=self["@codeWidget"];
 if(($receiver = $2) == nil || $receiver == null){
 $3=_st($HLDebuggerCodeWidget())._new();
+$ctx1.sendIdx["new"]=1;
+$4=$3;
+$6=_st($HLDebuggerCodeModel())._new();
+$7=$6;
+$8=self._model();
+$ctx1.sendIdx["model"]=1;
+_st($7)._debuggerModel_($8);
+$9=_st($6)._yourself();
+$ctx1.sendIdx["yourself"]=1;
+$5=$9;
+_st($4)._model_($5);
 _st($3)._browserModel_(self._model());
-$4=_st($3)._yourself();
-self["@codeWidget"]=$4;
+$10=_st($3)._yourself();
+self["@codeWidget"]=$10;
 $1=self["@codeWidget"];
 } else {
 $1=$2;
@@ -126,9 +138,9 @@ $1=$2;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"codeWidget",{},globals.HLDebugger)})},
 args: [],
-source: "codeWidget\x0a\x09^ codeWidget ifNil: [ codeWidget := HLDebuggerCodeWidget new\x0a\x09\x09browserModel: self model;\x0a\x09\x09yourself ]",
-messageSends: ["ifNil:", "browserModel:", "new", "model", "yourself"],
-referencedClasses: ["HLDebuggerCodeWidget"]
+source: "codeWidget\x0a\x09^ codeWidget ifNil: [ codeWidget := HLDebuggerCodeWidget new\x0a\x09\x09model: (HLDebuggerCodeModel new\x0a\x09\x09\x09debuggerModel: self model;\x0a\x09\x09\x09yourself);\x0a\x09\x09browserModel: self model;\x0a\x09\x09yourself ]",
+messageSends: ["ifNil:", "model:", "new", "debuggerModel:", "model", "yourself", "browserModel:"],
+referencedClasses: ["HLDebuggerCodeWidget", "HLDebuggerCodeModel"]
 }),
 globals.HLDebugger);
 
@@ -398,6 +410,59 @@ referencedClasses: []
 globals.HLDebugger.klass);
 
 
+smalltalk.addClass('HLDebuggerCodeModel', globals.HLCodeModel, ['debuggerModel'], 'Helios-Debugger');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "debuggerModel",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@debuggerModel"];
+return $1;
+},
+args: [],
+source: "debuggerModel\x0a\x09^ debuggerModel",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLDebuggerCodeModel);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "debuggerModel:",
+protocol: 'accessing',
+fn: function (anObject){
+var self=this;
+self["@debuggerModel"]=anObject;
+return self},
+args: ["anObject"],
+source: "debuggerModel: anObject\x0a\x09debuggerModel := anObject",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLDebuggerCodeModel);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "doIt:",
+protocol: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._debuggerModel())._evaluate_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"doIt:",{aString:aString},globals.HLDebuggerCodeModel)})},
+args: ["aString"],
+source: "doIt: aString\x0a\x09^ self debuggerModel evaluate: aString",
+messageSends: ["evaluate:", "debuggerModel"],
+referencedClasses: []
+}),
+globals.HLDebuggerCodeModel);
+
+
+
 smalltalk.addClass('HLDebuggerCodeWidget', globals.HLBrowserCodeWidget, [], 'Helios-Debugger');
 smalltalk.addMethod(
 smalltalk.method({
@@ -493,58 +558,48 @@ fn: function (aNode){
 var self=this;
 var token;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$6,$5,$4,$3,$9,$8,$7,$2,$13,$12,$11,$10,$14,$19,$18,$17,$16,$20,$15,$22,$21;
+var $4,$3,$2,$1,$5,$10,$9,$8,$7,$13,$12,$11,$6,$18,$17,$16,$15,$14;
 if(($receiver = aNode) == nil || $receiver == null){
 aNode;
 } else {
-$1=self._editor();
-$ctx1.sendIdx["editor"]=1;
-$6=_st(aNode)._position();
-$ctx1.sendIdx["position"]=1;
-$5=_st($6)._x();
+self._clearHighlight();
+$4=_st(aNode)._positionStart();
+$ctx1.sendIdx["positionStart"]=1;
+$3=_st($4)._x();
 $ctx1.sendIdx["x"]=1;
-$4=_st($5).__minus((1));
+$2=_st($3).__minus((1));
 $ctx1.sendIdx["-"]=1;
-$3="line".__minus_gt($4);
-$ctx1.sendIdx["->"]=1;
-$9=_st(aNode)._position();
-$ctx1.sendIdx["position"]=2;
-$8=_st($9)._y();
-$7="ch".__minus_gt($8);
-$ctx1.sendIdx["->"]=2;
-$2=globals.HashedCollection._from_([$3,$7]);
-token=_st($1)._getTokenAt_($2);
-token;
-self._clearHighlight();
-$13=_st(aNode)._position();
-$ctx1.sendIdx["position"]=3;
-$12=_st($13)._x();
+$1=self._addStopAt_($2);
+$1;
+$5=self._editor();
+$10=_st(aNode)._positionStart();
+$ctx1.sendIdx["positionStart"]=2;
+$9=_st($10)._x();
 $ctx1.sendIdx["x"]=2;
-$11=_st($12).__minus((1));
+$8=_st($9).__minus((1));
 $ctx1.sendIdx["-"]=2;
-$10=self._addStopAt_($11);
-$10;
-$14=self._editor();
-$19=_st(aNode)._position();
-$ctx1.sendIdx["position"]=4;
-$18=_st($19)._x();
-$ctx1.sendIdx["x"]=3;
-$17=_st($18).__minus((1));
+$7="line".__minus_gt($8);
+$ctx1.sendIdx["->"]=1;
+$13=_st(_st(aNode)._positionStart())._y();
+$ctx1.sendIdx["y"]=1;
+$12=_st($13).__minus((1));
 $ctx1.sendIdx["-"]=3;
-$16="line".__minus_gt($17);
+$11="ch".__minus_gt($12);
+$ctx1.sendIdx["->"]=2;
+$6=globals.HashedCollection._from_([$7,$11]);
+$18=_st(aNode)._positionEnd();
+$ctx1.sendIdx["positionEnd"]=1;
+$17=_st($18)._x();
+$16=_st($17).__minus((1));
+$15="line".__minus_gt($16);
 $ctx1.sendIdx["->"]=3;
-$20="ch".__minus_gt(_st(token)._start());
-$ctx1.sendIdx["->"]=4;
-$15=globals.HashedCollection._from_([$16,$20]);
-$22="line".__minus_gt(_st(_st(_st(aNode)._position())._x()).__minus((1)));
-$ctx1.sendIdx["->"]=5;
-$21=globals.HashedCollection._from_([$22,"ch".__minus_gt(_st(token)._end())]);
-_st($14)._setSelection_to_($15,$21);
+$14=globals.HashedCollection._from_([$15,"ch".__minus_gt(_st(_st(aNode)._positionEnd())._y())]);
+_st($5)._setSelection_to_($6,$14);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"highlightNode:",{aNode:aNode,token:token},globals.HLDebuggerCodeWidget)})},
 args: ["aNode"],
-source: "highlightNode: aNode\x0a\x09| token |\x0a\x09\x0a\x09aNode ifNotNil: [\x0a\x09\x09token := self editor getTokenAt: #{ \x0a\x09\x09\x09'line' -> (aNode position x - 1). \x0a\x09\x09\x09'ch' -> aNode position y \x0a\x09\x09}.\x0a\x0a\x09\x09self\x0a\x09\x09\x09clearHighlight;\x0a\x09\x09\x09addStopAt: aNode position x - 1.\x0a\x0a\x09\x09self editor \x0a\x09\x09\x09setSelection: #{ 'line' -> (aNode position x - 1). 'ch' -> token start }\x0a\x09\x09\x09to: #{ 'line' -> (aNode position x - 1). 'ch' -> token end } ]",
-messageSends: ["ifNotNil:", "getTokenAt:", "editor", "->", "-", "x", "position", "y", "clearHighlight", "addStopAt:", "setSelection:to:", "start", "end"],
+source: "highlightNode: aNode\x0a\x09| token |\x0a\x09\x0a\x09aNode ifNotNil: [\x0a\x09\x09self\x0a\x09\x09\x09clearHighlight;\x0a\x09\x09\x09addStopAt: aNode positionStart x - 1.\x0a\x0a\x09\x09self editor \x0a\x09\x09\x09setSelection: #{ 'line' -> (aNode positionStart x - 1). 'ch' -> (aNode positionStart y - 1) }\x0a\x09\x09\x09to: #{ 'line' -> (aNode positionEnd x - 1). 'ch' -> (aNode positionEnd y) } ]",
+messageSends: ["ifNotNil:", "clearHighlight", "addStopAt:", "-", "x", "positionStart", "setSelection:to:", "editor", "->", "y", "positionEnd"],
 referencedClasses: []
 }),
 globals.HLDebuggerCodeWidget);
@@ -601,7 +656,7 @@ globals.HLDebuggerCodeWidget);
 
 
 smalltalk.addClass('HLDebuggerModel', globals.HLToolModel, ['rootContext', 'currentContext', 'contexts'], 'Helios-Debugger');
-globals.HLDebuggerModel.comment="I am a model for Helios debugging.\x0a\x0aMy instances hold a reference to an `AIContext` instance, built from a `MethodContext`. The context should be the root of the context stack.";
+globals.HLDebuggerModel.comment="I am a model for debugging Amber code in Helios.\x0a\x0aMy instances hold a reference to an `AIContext` instance, built from a `MethodContext`. The context should be the root of the context stack.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "contexts",
@@ -670,6 +725,45 @@ referencedClasses: ["HLDebuggerContextSelected"]
 }),
 globals.HLDebuggerModel);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "evaluate:",
+protocol: 'evaluating',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._environment())._interpret_inContext_(aString,self._currentContext());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"evaluate:",{aString:aString},globals.HLDebuggerModel)})},
+args: ["aString"],
+source: "evaluate: aString\x0a\x09^ self environment \x0a\x09\x09interpret: aString \x0a\x09\x09inContext: self currentContext",
+messageSends: ["interpret:inContext:", "environment", "currentContext"],
+referencedClasses: []
+}),
+globals.HLDebuggerModel);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "flushInnerContexts",
+protocol: 'private',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._currentContext();
+$ctx1.sendIdx["currentContext"]=1;
+_st($1)._innerContext_(nil);
+self["@rootContext"]=self._currentContext();
+self._initializeContexts();
+return self}, function($ctx1) {$ctx1.fill(self,"flushInnerContexts",{},globals.HLDebuggerModel)})},
+args: [],
+source: "flushInnerContexts\x0a\x09\x22When stepping, the inner contexts are not relevent anymore,\x0a\x09and can be flushed\x22\x0a\x09\x0a\x09self currentContext innerContext: nil.\x0a\x09rootContext := self currentContext.\x0a\x09self initializeContexts",
+messageSends: ["innerContext:", "currentContext", "initializeContexts"],
+referencedClasses: []
+}),
+globals.HLDebuggerModel);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initializeContexts",
@@ -710,7 +804,7 @@ self["@rootContext"]=_st($AIContext())._fromMethodContext_(aMethodContext);
 self._initializeContexts();
 return self}, function($ctx1) {$ctx1.fill(self,"initializeFromContext:",{aMethodContext:aMethodContext},globals.HLDebuggerModel)})},
 args: ["aMethodContext"],
-source: "initializeFromContext: aMethodContext\x0a\x09rootContext := AIContext fromMethodContext: aMethodContext.\x0a\x09self initializeContexts",
+source: "initializeFromContext: aMethodContext\x0a\x09rootContext := (AIContext fromMethodContext: aMethodContext).\x0a\x09self initializeContexts",
 messageSends: ["fromMethodContext:", "initializeContexts"],
 referencedClasses: ["AIContext"]
 }),
@@ -762,14 +856,15 @@ function $HLDebuggerStepped(){return globals.HLDebuggerStepped||(typeof HLDebugg
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 _st(self._interpreter())._restart();
+self._flushInnerContexts();
 $1=_st($HLDebuggerStepped())._new();
 _st($1)._context_(self._currentContext());
 $2=_st($1)._yourself();
 _st(self._announcer())._announce_($2);
 return self}, function($ctx1) {$ctx1.fill(self,"restart",{},globals.HLDebuggerModel)})},
 args: [],
-source: "restart\x0a\x09self interpreter restart.\x0a\x09self announcer announce: (HLDebuggerStepped new\x0a\x09\x09context: self currentContext;\x0a\x09\x09yourself)",
-messageSends: ["restart", "interpreter", "announce:", "announcer", "context:", "new", "currentContext", "yourself"],
+source: "restart\x0a\x09self interpreter restart.\x0a\x09self flushInnerContexts.\x0a\x09\x0a\x09self announcer announce: (HLDebuggerStepped new\x0a\x09\x09context: self currentContext;\x0a\x09\x09yourself)",
+messageSends: ["restart", "interpreter", "flushInnerContexts", "announce:", "announcer", "context:", "new", "currentContext", "yourself"],
 referencedClasses: ["HLDebuggerStepped"]
 }),
 globals.HLDebuggerModel);
@@ -801,14 +896,15 @@ function $HLDebuggerStepped(){return globals.HLDebuggerStepped||(typeof HLDebugg
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 _st(self._interpreter())._skip();
+self._flushInnerContexts();
 $1=_st($HLDebuggerStepped())._new();
 _st($1)._context_(self._currentContext());
 $2=_st($1)._yourself();
 _st(self._announcer())._announce_($2);
 return self}, function($ctx1) {$ctx1.fill(self,"skip",{},globals.HLDebuggerModel)})},
 args: [],
-source: "skip\x0a\x09self interpreter skip.\x0a\x09self announcer announce: (HLDebuggerStepped new\x0a\x09\x09context: self currentContext;\x0a\x09\x09yourself)",
-messageSends: ["skip", "interpreter", "announce:", "announcer", "context:", "new", "currentContext", "yourself"],
+source: "skip\x0a\x09self interpreter skip.\x0a\x09self flushInnerContexts.\x0a\x09\x0a\x09self announcer announce: (HLDebuggerStepped new\x0a\x09\x09context: self currentContext;\x0a\x09\x09yourself)",
+messageSends: ["skip", "interpreter", "flushInnerContexts", "announce:", "announcer", "context:", "new", "currentContext", "yourself"],
 referencedClasses: ["HLDebuggerStepped"]
 }),
 globals.HLDebuggerModel);
@@ -823,14 +919,15 @@ function $HLDebuggerStepped(){return globals.HLDebuggerStepped||(typeof HLDebugg
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 _st(self._interpreter())._stepOver();
+self._flushInnerContexts();
 $1=_st($HLDebuggerStepped())._new();
 _st($1)._context_(self._currentContext());
 $2=_st($1)._yourself();
 _st(self._announcer())._announce_($2);
 return self}, function($ctx1) {$ctx1.fill(self,"stepOver",{},globals.HLDebuggerModel)})},
 args: [],
-source: "stepOver\x0a\x09self interpreter stepOver.\x0a\x09self announcer announce: (HLDebuggerStepped new\x0a\x09\x09context: self currentContext;\x0a\x09\x09yourself)",
-messageSends: ["stepOver", "interpreter", "announce:", "announcer", "context:", "new", "currentContext", "yourself"],
+source: "stepOver\x0a\x09self interpreter stepOver.\x0a\x09self flushInnerContexts.\x0a\x09\x0a\x09self announcer announce: (HLDebuggerStepped new\x0a\x09\x09context: self currentContext;\x0a\x09\x09yourself)",
+messageSends: ["stepOver", "interpreter", "flushInnerContexts", "announce:", "announcer", "context:", "new", "currentContext", "yourself"],
 referencedClasses: ["HLDebuggerStepped"]
 }),
 globals.HLDebuggerModel);
@@ -964,6 +1061,41 @@ referencedClasses: []
 }),
 globals.HLStackListWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "observeModel",
+protocol: 'actions',
+fn: function (){
+var self=this;
+function $HLDebuggerStepped(){return globals.HLDebuggerStepped||(typeof HLDebuggerStepped=="undefined"?nil:HLDebuggerStepped)}
+return smalltalk.withContext(function($ctx1) { 
+globals.HLStackListWidget.superclass.fn.prototype._observeModel.apply(_st(self), []);
+_st(_st(self._model())._announcer())._on_send_to_($HLDebuggerStepped(),"onDebuggerStepped:",self);
+return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{},globals.HLStackListWidget)})},
+args: [],
+source: "observeModel\x0a\x09super observeModel.\x0a\x09\x0a\x09self model announcer \x0a\x09\x09on: HLDebuggerStepped\x0a\x09\x09send: #onDebuggerStepped:\x0a\x09\x09to: self",
+messageSends: ["observeModel", "on:send:to:", "announcer", "model"],
+referencedClasses: ["HLDebuggerStepped"]
+}),
+globals.HLStackListWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onDebuggerStepped:",
+protocol: 'reactions',
+fn: function (anAnnouncement){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@items"]=nil;
+self._refresh();
+return self}, function($ctx1) {$ctx1.fill(self,"onDebuggerStepped:",{anAnnouncement:anAnnouncement},globals.HLStackListWidget)})},
+args: ["anAnnouncement"],
+source: "onDebuggerStepped: anAnnouncement\x0a\x09items := nil.\x0a\x09self refresh",
+messageSends: ["refresh"],
+referencedClasses: []
+}),
+globals.HLStackListWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "renderButtonsOn:",
@@ -1055,10 +1187,11 @@ fn: function (aContext){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._currentContext_(aContext);
+globals.HLStackListWidget.superclass.fn.prototype._selectItem_.apply(_st(self), [aContext]);
 return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{aContext:aContext},globals.HLStackListWidget)})},
 args: ["aContext"],
-source: "selectItem: aContext\x0a   \x09self model currentContext: aContext",
-messageSends: ["currentContext:", "model"],
+source: "selectItem: aContext\x0a   \x09self model currentContext: aContext.\x0a\x09super selectItem: aContext",
+messageSends: ["currentContext:", "model", "selectItem:"],
 referencedClasses: []
 }),
 globals.HLStackListWidget);

+ 2 - 1
js/Helios-Inspector.js

@@ -280,6 +280,7 @@ selector: "onKeyDown:",
 protocol: 'reactions',
 fn: function (anEvent){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 if(anEvent.ctrlKey) {
 		if(anEvent.keyCode === 80) { //ctrl+p
 			self._printIt();
@@ -297,7 +298,7 @@ if(anEvent.ctrlKey) {
 			return false;
 		}
 	};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"onKeyDown:",{anEvent:anEvent},globals.HLInspectorModel)})},
 args: ["anEvent"],
 source: "onKeyDown: anEvent\x0a\x0a\x09<if(anEvent.ctrlKey) {\x0a\x09\x09if(anEvent.keyCode === 80) { //ctrl+p\x0a\x09\x09\x09self._printIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09if(anEvent.keyCode === 68) { //ctrl+d\x0a\x09\x09\x09self._doIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09if(anEvent.keyCode === 73) { //ctrl+i\x0a\x09\x09\x09self._inspectIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09}>",
 messageSends: [],

+ 54 - 0
js/Helios-References.js

@@ -944,6 +944,60 @@ referencedClasses: []
 }),
 globals.HLReferencesModel);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "openClassNamed:",
+protocol: 'actions',
+fn: function (aString){
+var self=this;
+var browser;
+function $HLBrowser(){return globals.HLBrowser||(typeof HLBrowser=="undefined"?nil:HLBrowser)}
+return smalltalk.withContext(function($ctx1) { 
+self._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+browser=_st($HLBrowser())._openAsTab();
+browser;
+return _st(browser)._openClassNamed_(aString);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"openClassNamed:",{aString:aString,browser:browser},globals.HLReferencesModel)})},
+args: ["aString"],
+source: "openClassNamed: aString\x0a\x09| browser |\x0a\x09\x0a\x09self withChangesDo: [\x0a\x09\x09browser := HLBrowser openAsTab.\x0a\x09\x09browser openClassNamed: aString ]",
+messageSends: ["withChangesDo:", "openAsTab", "openClassNamed:"],
+referencedClasses: ["HLBrowser"]
+}),
+globals.HLReferencesModel);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "openMethod",
+protocol: 'actions',
+fn: function (){
+var self=this;
+var browser;
+function $HLBrowser(){return globals.HLBrowser||(typeof HLBrowser=="undefined"?nil:HLBrowser)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._selectedMethod();
+$ctx1.sendIdx["selectedMethod"]=1;
+if(($receiver = $1) == nil || $receiver == null){
+return self;
+} else {
+$1;
+};
+self._withChangesDo_((function(){
+return smalltalk.withContext(function($ctx2) {
+browser=_st($HLBrowser())._openAsTab();
+browser;
+return _st(browser)._openMethod_(self._selectedMethod());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"openMethod",{browser:browser},globals.HLReferencesModel)})},
+args: [],
+source: "openMethod\x0a\x09| browser |\x0a\x09\x0a\x09self selectedMethod ifNil: [ ^ self ].\x0a\x09\x0a\x09self withChangesDo: [\x0a\x09\x09browser := HLBrowser openAsTab.\x0a\x09\x09browser openMethod: self selectedMethod ]",
+messageSends: ["ifNil:", "selectedMethod", "withChangesDo:", "openAsTab", "openMethod:"],
+referencedClasses: ["HLBrowser"]
+}),
+globals.HLReferencesModel);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "regexpReferencesOf:",

+ 6 - 3
js/Helios-Workspace.js

@@ -946,8 +946,9 @@ selector: "setEditorOn:",
 protocol: 'actions',
 fn: function (aTextarea){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self['@editor'] = CodeMirror.fromTextArea(aTextarea, self._editorOptions());
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"setEditorOn:",{aTextarea:aTextarea},globals.HLCodeWidget)})},
 args: ["aTextarea"],
 source: "setEditorOn: aTextarea\x0a\x09<self['@editor'] = CodeMirror.fromTextArea(aTextarea, self._editorOptions())>",
 messageSends: [],
@@ -1278,13 +1279,14 @@ selector: "setupCodeMirror",
 protocol: 'initialization',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  
 		CodeMirror.keyMap.default.fallthrough = ["basic"];
 		CodeMirror.commands.autocomplete = function(cm) {
 			CodeMirror.showHint(cm, self._hintFor_options_);
 		}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"setupCodeMirror",{},globals.HLCodeWidget.klass)})},
 args: [],
 source: "setupCodeMirror\x0a\x09< \x0a\x09\x09CodeMirror.keyMap.default.fallthrough = [\x22basic\x22];\x0a\x09\x09CodeMirror.commands.autocomplete = function(cm) {\x0a\x09\x09\x09CodeMirror.showHint(cm, self._hintFor_options_);\x0a\x09\x09}\x0a\x09>",
 messageSends: [],
@@ -1341,8 +1343,9 @@ selector: "setupKeyMaps",
 protocol: 'initialization',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 CodeMirror.keyMap['Amber'] = self._keyMap();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"setupKeyMaps",{},globals.HLCodeWidget.klass)})},
 args: [],
 source: "setupKeyMaps\x0a\x09<CodeMirror.keyMap['Amber'] = self._keyMap()>",
 messageSends: [],

+ 42 - 38
js/IDE.js

@@ -669,6 +669,7 @@ selector: "handleKeyDown:",
 protocol: 'actions',
 fn: function (anEvent){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 if(anEvent.ctrlKey) {
 		if(anEvent.keyCode === 80) { //ctrl+p
 			self._printIt();
@@ -686,7 +687,7 @@ if(anEvent.ctrlKey) {
 			return false;
 		}
 	};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"handleKeyDown:",{anEvent:anEvent},globals.SourceArea)})},
 args: ["anEvent"],
 source: "handleKeyDown: anEvent\x0a\x09<if(anEvent.ctrlKey) {\x0a\x09\x09if(anEvent.keyCode === 80) { //ctrl+p\x0a\x09\x09\x09self._printIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09if(anEvent.keyCode === 68) { //ctrl+d\x0a\x09\x09\x09self._doIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09if(anEvent.keyCode === 73) { //ctrl+i\x0a\x09\x09\x09self._inspectIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09}>",
 messageSends: [],
@@ -943,6 +944,7 @@ selector: "setEditorOn:",
 protocol: 'accessing',
 fn: function (aTextarea){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self['@editor'] = CodeMirror.fromTextArea(aTextarea, {
 		theme: 'default',
 		mode: 'text/x-stsrc',
@@ -953,7 +955,7 @@ self['@editor'] = CodeMirror.fromTextArea(aTextarea, {
 		matchBrackets: true,
 		electricChars: false
 	});
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"setEditorOn:",{aTextarea:aTextarea},globals.SourceArea)})},
 args: ["aTextarea"],
 source: "setEditorOn: aTextarea\x0a\x09<self['@editor'] = CodeMirror.fromTextArea(aTextarea, {\x0a\x09\x09theme: 'default',\x0a\x09\x09mode: 'text/x-stsrc',\x0a\x09\x09lineNumbers: true,\x0a\x09\x09enterMode: 'flat',\x0a\x09\x09indentWithTabs: true,\x0a\x09\x09indentUnit: 4,\x0a\x09\x09matchBrackets: true,\x0a\x09\x09electricChars: false\x0a\x09})>",
 messageSends: [],
@@ -1019,8 +1021,9 @@ selector: "setupCodeMirror",
 protocol: 'initialization',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  CodeMirror.keyMap["default"].fallthrough = ["basic"] ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"setupCodeMirror",{},globals.SourceArea.klass)})},
 args: [],
 source: "setupCodeMirror\x0a\x09< CodeMirror.keyMap[\x22default\x22].fallthrough = [\x22basic\x22] >",
 messageSends: [],
@@ -2487,6 +2490,7 @@ selector: "handleSourceAreaKeyDown:",
 protocol: 'actions',
 fn: function (anEvent){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 if(anEvent.ctrlKey) {
 		if(anEvent.keyCode === 83) { //ctrl+s
 			self._compile();
@@ -2495,7 +2499,7 @@ if(anEvent.ctrlKey) {
 		}
 	}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"handleSourceAreaKeyDown:",{anEvent:anEvent},globals.Browser)})},
 args: ["anEvent"],
 source: "handleSourceAreaKeyDown: anEvent\x0a\x09<if(anEvent.ctrlKey) {\x0a\x09\x09if(anEvent.keyCode === 83) { //ctrl+s\x0a\x09\x09\x09self._compile();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09}\x0a\x09>",
 messageSends: [],
@@ -7346,27 +7350,21 @@ var $1;
 variables=_st($Dictionary())._new();
 _st(variables)._at_put_("#self",self);
 $ctx1.sendIdx["at:put:"]=1;
-_st(variables)._at_put_("#home",self._home());
+_st(variables)._at_put_("#keys",self._keys());
 $ctx1.sendIdx["at:put:"]=2;
-_st(variables)._at_put_("#receiver",self._receiver());
-$ctx1.sendIdx["at:put:"]=3;
-_st(variables)._at_put_("#selector",self._selector());
-$ctx1.sendIdx["at:put:"]=4;
-_st(variables)._at_put_("#temps",self._temps());
-$ctx1.sendIdx["at:put:"]=5;
-_st(_st(self._class())._instanceVariableNames())._do_((function(each){
+self._keysAndValuesDo_((function(key,value){
 return smalltalk.withContext(function($ctx2) {
-return _st(variables)._at_put_(each,self._instVarAt_(each));
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+return _st(variables)._at_put_(key,value);
+}, function($ctx2) {$ctx2.fillBlock({key:key,value:value},$ctx1,1)})}));
 _st(anInspector)._setLabel_(self._printString());
 $1=_st(anInspector)._setVariables_(variables);
-return self}, function($ctx1) {$ctx1.fill(self,"inspectOn:",{anInspector:anInspector,variables:variables},globals.MethodContext)})},
+return self}, function($ctx1) {$ctx1.fill(self,"inspectOn:",{anInspector:anInspector,variables:variables},globals.AssociativeCollection)})},
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09variables at: '#home' put: self home.\x0a\x09variables at: '#receiver' put: self receiver.\x0a\x09variables at: '#selector' put: self selector.\x0a\x09variables at: '#temps' put: self temps.\x0a\x09self class instanceVariableNames do: [ :each |\x0a\x09\x09variables at: each put: (self instVarAt: each) ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
-messageSends: ["new", "at:put:", "home", "receiver", "selector", "temps", "do:", "instanceVariableNames", "class", "instVarAt:", "setLabel:", "printString", "setVariables:"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09variables at: '#keys' put: self keys.\x0a\x09self keysAndValuesDo: [ :key :value |\x0a\x09\x09variables at: key put: value ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
+messageSends: ["new", "at:put:", "keys", "keysAndValuesDo:", "setLabel:", "printString", "setVariables:"],
 referencedClasses: ["Dictionary"]
 }),
-globals.MethodContext);
+globals.AssociativeCollection);
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -7374,28 +7372,29 @@ selector: "inspectOn:",
 protocol: '*IDE',
 fn: function (anInspector){
 var self=this;
-var variables;
+var variables,i;
 function $Dictionary(){return globals.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 variables=_st($Dictionary())._new();
 _st(variables)._at_put_("#self",self);
 $ctx1.sendIdx["at:put:"]=1;
-_st(variables)._at_put_("#keys",self._keys());
-$ctx1.sendIdx["at:put:"]=2;
-self._keysAndValuesDo_((function(key,value){
+i=(1);
+self._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(variables)._at_put_(key,value);
-}, function($ctx2) {$ctx2.fillBlock({key:key,value:value},$ctx1,1)})}));
+_st(variables)._at_put_(i,each);
+i=_st(i).__plus((1));
+return i;
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 _st(anInspector)._setLabel_(self._printString());
 $1=_st(anInspector)._setVariables_(variables);
-return self}, function($ctx1) {$ctx1.fill(self,"inspectOn:",{anInspector:anInspector,variables:variables},globals.AssociativeCollection)})},
+return self}, function($ctx1) {$ctx1.fill(self,"inspectOn:",{anInspector:anInspector,variables:variables,i:i},globals.Set)})},
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09variables at: '#keys' put: self keys.\x0a\x09self keysAndValuesDo: [ :key :value |\x0a\x09\x09variables at: key put: value ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
-messageSends: ["new", "at:put:", "keys", "keysAndValuesDo:", "setLabel:", "printString", "setVariables:"],
+source: "inspectOn: anInspector\x0a\x09| variables i |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09i := 1.\x0a\x09self do: [ :each |\x0a\x09\x09variables at: i put: each.\x0a\x09\x09i := i + 1 ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
+messageSends: ["new", "at:put:", "do:", "+", "setLabel:", "printString", "setVariables:"],
 referencedClasses: ["Dictionary"]
 }),
-globals.AssociativeCollection);
+globals.Set);
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -7403,28 +7402,33 @@ selector: "inspectOn:",
 protocol: '*IDE',
 fn: function (anInspector){
 var self=this;
-var variables,i;
+var variables;
 function $Dictionary(){return globals.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 variables=_st($Dictionary())._new();
 _st(variables)._at_put_("#self",self);
 $ctx1.sendIdx["at:put:"]=1;
-i=(1);
-self._do_((function(each){
+_st(variables)._at_put_("#home",self._home());
+$ctx1.sendIdx["at:put:"]=2;
+_st(variables)._at_put_("#receiver",self._receiver());
+$ctx1.sendIdx["at:put:"]=3;
+_st(variables)._at_put_("#selector",self._selector());
+$ctx1.sendIdx["at:put:"]=4;
+_st(variables)._at_put_("#locals",self._locals());
+$ctx1.sendIdx["at:put:"]=5;
+_st(_st(self._class())._instanceVariableNames())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-_st(variables)._at_put_(i,each);
-i=_st(i).__plus((1));
-return i;
+return _st(variables)._at_put_(each,self._instVarAt_(each));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 _st(anInspector)._setLabel_(self._printString());
 $1=_st(anInspector)._setVariables_(variables);
-return self}, function($ctx1) {$ctx1.fill(self,"inspectOn:",{anInspector:anInspector,variables:variables,i:i},globals.Set)})},
+return self}, function($ctx1) {$ctx1.fill(self,"inspectOn:",{anInspector:anInspector,variables:variables},globals.MethodContext)})},
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables i |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09i := 1.\x0a\x09self do: [ :each |\x0a\x09\x09variables at: i put: each.\x0a\x09\x09i := i + 1 ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
-messageSends: ["new", "at:put:", "do:", "+", "setLabel:", "printString", "setVariables:"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09variables at: '#home' put: self home.\x0a\x09variables at: '#receiver' put: self receiver.\x0a\x09variables at: '#selector' put: self selector.\x0a\x09variables at: '#locals' put: self locals.\x0a\x09self class instanceVariableNames do: [ :each |\x0a\x09\x09variables at: each put: (self instVarAt: each) ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
+messageSends: ["new", "at:put:", "home", "receiver", "selector", "locals", "do:", "instanceVariableNames", "class", "instVarAt:", "setLabel:", "printString", "setVariables:"],
 referencedClasses: ["Dictionary"]
 }),
-globals.Set);
+globals.MethodContext);
 
 });

+ 36 - 18
js/Kernel-Classes.js

@@ -221,8 +221,9 @@ selector: "basicAddCompiledMethod:",
 protocol: 'private',
 fn: function (aMethod){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 smalltalk.addMethod(aMethod, self);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicAddCompiledMethod:",{aMethod:aMethod},globals.Behavior)})},
 args: ["aMethod"],
 source: "basicAddCompiledMethod: aMethod\x0a\x09<smalltalk.addMethod(aMethod, self)>",
 messageSends: [],
@@ -236,8 +237,9 @@ selector: "basicNew",
 protocol: 'instance creation',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return new self.fn();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicNew",{},globals.Behavior)})},
 args: [],
 source: "basicNew\x0a\x09<return new self.fn()>",
 messageSends: [],
@@ -251,8 +253,9 @@ selector: "basicRemoveCompiledMethod:",
 protocol: 'private',
 fn: function (aMethod){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 smalltalk.removeMethod(aMethod,self);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicRemoveCompiledMethod:",{aMethod:aMethod},globals.Behavior)})},
 args: ["aMethod"],
 source: "basicRemoveCompiledMethod: aMethod\x0a\x09<smalltalk.removeMethod(aMethod,self)>",
 messageSends: [],
@@ -501,8 +504,9 @@ selector: "instanceVariableNames",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.iVarNames;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"instanceVariableNames",{},globals.Behavior)})},
 args: [],
 source: "instanceVariableNames\x0a\x09<return self.iVarNames>",
 messageSends: [],
@@ -531,8 +535,9 @@ selector: "javascriptConstructor",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.fn;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"javascriptConstructor",{},globals.Behavior)})},
 args: [],
 source: "javascriptConstructor\x0a\x09\x22Answer the JS constructor used to instantiate. See boot.js\x22\x0a\x09\x0a\x09<return self.fn>",
 messageSends: [],
@@ -546,8 +551,9 @@ selector: "javascriptConstructor:",
 protocol: 'accessing',
 fn: function (aJavaScriptFunction){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 smalltalk.setClassConstructor(self, aJavaScriptFunction);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"javascriptConstructor:",{aJavaScriptFunction:aJavaScriptFunction},globals.Behavior)})},
 args: ["aJavaScriptFunction"],
 source: "javascriptConstructor: aJavaScriptFunction\x0a\x09\x22Set the JS constructor used to instantiate.\x0a\x09See the JS counter-part in boot.js `smalltalk.setClassConstructor'\x22\x0a\x09\x0a\x09<smalltalk.setClassConstructor(self, aJavaScriptFunction);>",
 messageSends: [],
@@ -615,6 +621,7 @@ selector: "methodDictionary",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 var dict = globals.HashedCollection._new();
 	var methods = self.methods;
 	Object.keys(methods).forEach(function(i) {
@@ -623,7 +630,7 @@ var dict = globals.HashedCollection._new();
 		}
 	});
 	return dict;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"methodDictionary",{},globals.Behavior)})},
 args: [],
 source: "methodDictionary\x0a\x09<var dict = globals.HashedCollection._new();\x0a\x09var methods = self.methods;\x0a\x09Object.keys(methods).forEach(function(i) {\x0a\x09\x09if(methods[i].selector) {\x0a\x09\x09\x09dict._at_put_(methods[i].selector, methods[i]);\x0a\x09\x09}\x0a\x09});\x0a\x09return dict>",
 messageSends: [],
@@ -716,8 +723,9 @@ selector: "name",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.className || nil;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"name",{},globals.Behavior)})},
 args: [],
 source: "name\x0a\x09<return self.className || nil>",
 messageSends: [],
@@ -864,8 +872,9 @@ selector: "prototype",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.fn.prototype;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"prototype",{},globals.Behavior)})},
 args: [],
 source: "prototype\x0a\x09<return self.fn.prototype>",
 messageSends: [],
@@ -978,8 +987,9 @@ selector: "superclass",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.superclass || nil;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"superclass",{},globals.Behavior)})},
 args: [],
 source: "superclass\x0a\x09<return self.superclass || nil>",
 messageSends: [],
@@ -1327,8 +1337,9 @@ selector: "subclasses",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.subclasses._copy();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"subclasses",{},globals.Class)})},
 args: [],
 source: "subclasses\x0a\x09<return self.subclasses._copy()>",
 messageSends: [],
@@ -1401,8 +1412,9 @@ selector: "instanceClass",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.instanceClass;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"instanceClass",{},globals.Metaclass)})},
 args: [],
 source: "instanceClass\x0a\x09<return self.instanceClass>",
 messageSends: [],
@@ -1562,11 +1574,12 @@ selector: "basicAddSubclassOf:named:instanceVariableNames:package:",
 protocol: 'private',
 fn: function (aClass,aString,aCollection,packageName){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		smalltalk.addClass(aString, aClass, aCollection, packageName);
 		return globals[aString]
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicAddSubclassOf:named:instanceVariableNames:package:",{aClass:aClass,aString:aString,aCollection:aCollection,packageName:packageName},globals.ClassBuilder)})},
 args: ["aClass", "aString", "aCollection", "packageName"],
 source: "basicAddSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName\x0a\x09<\x0a\x09\x09smalltalk.addClass(aString, aClass, aCollection, packageName);\x0a\x09\x09return globals[aString]\x0a\x09>",
 messageSends: [],
@@ -1617,8 +1630,9 @@ selector: "basicRemoveClass:",
 protocol: 'private',
 fn: function (aClass){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 smalltalk.removeClass(aClass);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicRemoveClass:",{aClass:aClass},globals.ClassBuilder)})},
 args: ["aClass"],
 source: "basicRemoveClass: aClass\x0a\x09<smalltalk.removeClass(aClass)>",
 messageSends: [],
@@ -1632,12 +1646,13 @@ selector: "basicRenameClass:to:",
 protocol: 'private',
 fn: function (aClass,aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		globals[aString] = aClass;
 		delete globals[aClass.className];
 		aClass.className = aString;
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicRenameClass:to:",{aClass:aClass,aString:aString},globals.ClassBuilder)})},
 args: ["aClass", "aString"],
 source: "basicRenameClass: aClass to: aString\x0a\x09<\x0a\x09\x09globals[aString] = aClass;\x0a\x09\x09delete globals[aClass.className];\x0a\x09\x09aClass.className = aString;\x0a\x09>",
 messageSends: [],
@@ -1651,12 +1666,13 @@ selector: "basicSwapClassNames:with:",
 protocol: '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},
+return self}, function($ctx1) {$ctx1.fill(self,"basicSwapClassNames:with:",{aClass:aClass,anotherClass:anotherClass},globals.ClassBuilder)})},
 args: ["aClass", "anotherClass"],
 source: "basicSwapClassNames: aClass with: anotherClass\x0a\x09<\x0a\x09\x09var tmp = aClass.className;\x0a\x09\x09aClass.className = anotherClass.className;\x0a\x09\x09anotherClass.className = tmp;\x0a\x09>",
 messageSends: [],
@@ -1884,10 +1900,11 @@ selector: "rawRenameClass:to:",
 protocol: 'private',
 fn: function (aClass,aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		globals[aString] = aClass;
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"rawRenameClass:to:",{aClass:aClass,aString:aString},globals.ClassBuilder)})},
 args: ["aClass", "aString"],
 source: "rawRenameClass: aClass to: aString\x0a\x09<\x0a\x09\x09globals[aString] = aClass;\x0a\x09>",
 messageSends: [],
@@ -1925,8 +1942,9 @@ selector: "setupClass:",
 protocol: 'public',
 fn: function (aClass){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 smalltalk.init(aClass);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"setupClass:",{aClass:aClass},globals.ClassBuilder)})},
 args: ["aClass"],
 source: "setupClass: aClass\x0a\x09<smalltalk.init(aClass);>",
 messageSends: [],

File diff suppressed because it is too large
+ 161 - 80
js/Kernel-Collections.js


+ 14 - 7
js/Kernel-Exceptions.js

@@ -10,8 +10,9 @@ selector: "context",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.context;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"context",{},globals.Error)})},
 args: [],
 source: "context\x0a\x09<return self.context>",
 messageSends: [],
@@ -41,8 +42,9 @@ selector: "isSmalltalkError",
 protocol: 'testing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.smalltalkError === true;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"isSmalltalkError",{},globals.Error)})},
 args: [],
 source: "isSmalltalkError\x0a\x09<return self.smalltalkError === true>",
 messageSends: [],
@@ -56,8 +58,9 @@ selector: "jsStack",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.stack;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"jsStack",{},globals.Error)})},
 args: [],
 source: "jsStack\x0a\x09<return self.stack>",
 messageSends: [],
@@ -103,8 +106,9 @@ selector: "resignal",
 protocol: 'signaling',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 throw(self);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"resignal",{},globals.Error)})},
 args: [],
 source: "resignal\x0a\x09\x22Resignal the receiver without changing its exception context\x22\x0a\x09\x0a\x09<throw(self)>",
 messageSends: [],
@@ -118,8 +122,9 @@ selector: "signal",
 protocol: 'signaling',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"signal",{},globals.Error)})},
 args: [],
 source: "signal\x0a\x09<self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self)>",
 messageSends: [],
@@ -205,8 +210,9 @@ selector: "context:",
 protocol: 'accessing',
 fn: function (aMethodContext){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.context = aMethodContext;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"context:",{aMethodContext:aMethodContext},globals.JavaScriptException)})},
 args: ["aMethodContext"],
 source: "context: aMethodContext\x0a\x09\x22Set the context from the outside.\x0a\x09See boot.js `inContext()` exception handling\x22\x0a\x09\x0a\x09<self.context = aMethodContext>",
 messageSends: [],
@@ -252,8 +258,9 @@ selector: "messageText",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return 'JavaScript exception: ' + self["@exception"].toString();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"messageText",{},globals.JavaScriptException)})},
 args: [],
 source: "messageText\x0a\x09<return 'JavaScript exception: ' + self[\x22@exception\x22].toString()>",
 messageSends: [],

+ 109 - 37
js/Kernel-Infrastructure.js

@@ -512,7 +512,7 @@ globals.Environment);
 smalltalk.addMethod(
 smalltalk.method({
 selector: "eval:on:",
-protocol: 'actions',
+protocol: 'evaluating',
 fn: function (aString,aReceiver){
 var self=this;
 var compiler;
@@ -585,6 +585,43 @@ referencedClasses: ["Inspector"]
 }),
 globals.Environment);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "interpret:inContext:",
+protocol: 'evaluating',
+fn: function (aString,anAIContext){
+var self=this;
+var compiler,ast;
+function $Compiler(){return globals.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+function $Error(){return globals.Error||(typeof Error=="undefined"?nil:Error)}
+function $SemanticAnalyzer(){return globals.SemanticAnalyzer||(typeof SemanticAnalyzer=="undefined"?nil:SemanticAnalyzer)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+var $early={};
+try {
+compiler=_st($Compiler())._new();
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+ast=_st(compiler)._parseExpression_(aString);
+return ast;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._on_do_($Error(),(function(ex){
+return smalltalk.withContext(function($ctx2) {
+$1=self._alert_(_st(ex)._messageText());
+throw $early=[$1];
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1,2)})}));
+_st(_st($SemanticAnalyzer())._on_(_st(_st(anAIContext)._receiver())._class()))._visit_(ast);
+$2=_st(anAIContext)._evaluateNode_(ast);
+return $2;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"interpret:inContext:",{aString:aString,anAIContext:anAIContext,compiler:compiler,ast:ast},globals.Environment)})},
+args: ["aString", "anAIContext"],
+source: "interpret: aString inContext: anAIContext\x0a\x09\x22Similar to #eval:on:, with the following differences:\x0a\x09- instead of compiling and running `aString`, `aString` is interpreted using an `ASTInterpreter`\x0a\x09- instead of evaluating against a receiver, evaluate in the context of `anAIContext`\x22\x0a\x0a\x09| compiler ast |\x0a\x09compiler := Compiler new.\x0a\x09[ ast := compiler parseExpression: aString ] on: Error do: [ :ex |\x0a\x09\x09^ self alert: ex messageText ].\x0a\x09(SemanticAnalyzer on: anAIContext receiver class)\x0a\x09\x09visit: ast.\x0a\x09^ anAIContext evaluateNode: ast",
+messageSends: ["new", "on:do:", "parseExpression:", "alert:", "messageText", "visit:", "on:", "class", "receiver", "evaluateNode:"],
+referencedClasses: ["Compiler", "Error", "SemanticAnalyzer"]
+}),
+globals.Environment);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "moveClass:toPackage:",
@@ -912,12 +949,13 @@ selector: "addObjectVariablesTo:",
 protocol: 'proxy',
 fn: function (aDictionary){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		for(var i in self['@jsObject']) {
 			aDictionary._at_put_(i, self['@jsObject'][i]);
 		}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"addObjectVariablesTo:",{aDictionary:aDictionary},globals.JSObjectProxy)})},
 args: ["aDictionary"],
 source: "addObjectVariablesTo: aDictionary\x0a\x09<\x0a\x09\x09for(var i in self['@jsObject']) {\x0a\x09\x09\x09aDictionary._at_put_(i, self['@jsObject'][i]);\x0a\x09\x09}\x0a\x09>",
 messageSends: [],
@@ -948,8 +986,9 @@ selector: "at:",
 protocol: 'accessing',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self['@jsObject'][aString];
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"at:",{aString:aString},globals.JSObjectProxy)})},
 args: ["aString"],
 source: "at: aString\x0a\x09<return self['@jsObject'][aString]>",
 messageSends: [],
@@ -963,11 +1002,12 @@ selector: "at:ifAbsent:",
 protocol: 'accessing',
 fn: function (aString,aBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var obj = self['@jsObject'];
 		return aString in obj ? obj[aString] : aBlock._value();
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"at:ifAbsent:",{aString:aString,aBlock:aBlock},globals.JSObjectProxy)})},
 args: ["aString", "aBlock"],
 source: "at: aString ifAbsent: aBlock\x0a\x09\x22return the aString property or evaluate aBlock if the property is not defined on the object\x22\x0a\x09<\x0a\x09\x09var obj = self['@jsObject'];\x0a\x09\x09return aString in obj ? obj[aString] : aBlock._value();\x0a\x09>",
 messageSends: [],
@@ -981,11 +1021,12 @@ selector: "at:ifPresent:",
 protocol: 'accessing',
 fn: function (aString,aBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var obj = self['@jsObject'];
 		return aString in obj ? aBlock._value_(obj[aString]) : nil;
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"at:ifPresent:",{aString:aString,aBlock:aBlock},globals.JSObjectProxy)})},
 args: ["aString", "aBlock"],
 source: "at: aString ifPresent: aBlock\x0a\x09\x22return the evaluation of aBlock with the value if the property is defined or return nil\x22\x0a\x09<\x0a\x09\x09var obj = self['@jsObject'];\x0a\x09\x09return aString in obj ? aBlock._value_(obj[aString]) : nil;\x0a\x09>",
 messageSends: [],
@@ -999,11 +1040,12 @@ selector: "at:ifPresent:ifAbsent:",
 protocol: 'accessing',
 fn: function (aString,aBlock,anotherBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var obj = self['@jsObject'];
 		return aString in obj ? aBlock._value_(obj[aString]) : anotherBlock._value();
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"at:ifPresent:ifAbsent:",{aString:aString,aBlock:aBlock,anotherBlock:anotherBlock},globals.JSObjectProxy)})},
 args: ["aString", "aBlock", "anotherBlock"],
 source: "at: aString ifPresent: aBlock ifAbsent: anotherBlock\x0a\x09\x22return the evaluation of aBlock with the value if the property is defined\x0a\x09or return value of anotherBlock\x22\x0a\x09<\x0a\x09\x09var obj = self['@jsObject'];\x0a\x09\x09return aString in obj ? aBlock._value_(obj[aString]) : anotherBlock._value();\x0a\x09>",
 messageSends: [],
@@ -1017,8 +1059,9 @@ selector: "at:put:",
 protocol: 'accessing',
 fn: function (aString,anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self['@jsObject'][aString] = anObject;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"at:put:",{aString:aString,anObject:anObject},globals.JSObjectProxy)})},
 args: ["aString", "anObject"],
 source: "at: aString put: anObject\x0a\x09<return self['@jsObject'][aString] = anObject>",
 messageSends: [],
@@ -1032,8 +1075,9 @@ selector: "compareJSObjectWith:",
 protocol: 'private',
 fn: function (aJSObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self["@jsObject"] === aJSObject;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"compareJSObjectWith:",{aJSObject:aJSObject},globals.JSObjectProxy)})},
 args: ["aJSObject"],
 source: " compareJSObjectWith: aJSObject\x0a \x09<return self[\x22@jsObject\x22] === aJSObject>",
 messageSends: [],
@@ -1072,10 +1116,11 @@ selector: "forwardMessage:withArguments:",
 protocol: 'proxy',
 fn: function (aString,anArray){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		return smalltalk.send(self._jsObject(), aString, anArray);
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"forwardMessage:withArguments:",{aString:aString,anArray:anArray},globals.JSObjectProxy)})},
 args: ["aString", "anArray"],
 source: "forwardMessage: aString withArguments: anArray\x0a\x09<\x0a\x09\x09return smalltalk.send(self._jsObject(), aString, anArray);\x0a\x09>",
 messageSends: [],
@@ -1143,13 +1188,14 @@ selector: "keysAndValuesDo:",
 protocol: 'enumerating',
 fn: function (aBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var o = self['@jsObject'];
 		for(var i in o) {
 			aBlock._value_value_(i, o[i]);
 		}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"keysAndValuesDo:",{aBlock:aBlock},globals.JSObjectProxy)})},
 args: ["aBlock"],
 source: "keysAndValuesDo: aBlock\x0a\x09<\x0a\x09\x09var o = self['@jsObject'];\x0a\x09\x09for(var i in o) {\x0a\x09\x09\x09aBlock._value_value_(i, o[i]);\x0a\x09\x09}\x0a\x09>",
 messageSends: [],
@@ -1163,8 +1209,9 @@ selector: "lookupProperty:",
 protocol: 'accessing',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return aString in self._jsObject() ? aString : nil;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"lookupProperty:",{aString:aString},globals.JSObjectProxy)})},
 args: ["aString"],
 source: "lookupProperty: aString\x0a\x09\x22Looks up a property in JS object.\x0a\x09Answer the property if it is present, or nil if it is not present.\x22\x0a\x09\x0a\x09<return aString in self._jsObject() ? aString : nil>",
 messageSends: [],
@@ -1194,13 +1241,14 @@ selector: "printString",
 protocol: 'printing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var js = self['@jsObject'];
 		return js.toString
 			? js.toString()
 			: Object.prototype.toString.call(js)
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"printString",{},globals.JSObjectProxy)})},
 args: [],
 source: "printString\x0a\x09<\x0a\x09\x09var js = self['@jsObject'];\x0a\x09\x09return js.toString\x0a\x09\x09\x09? js.toString()\x0a\x09\x09\x09: Object.prototype.toString.call(js)\x0a\x09>",
 messageSends: [],
@@ -1277,8 +1325,9 @@ selector: "addElement:",
 protocol: 'accessing',
 fn: function (anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.elements.addElement(anObject);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"addElement:",{anObject:anObject},globals.Organizer)})},
 args: ["anObject"],
 source: "addElement: anObject\x0a\x09<self.elements.addElement(anObject)>",
 messageSends: [],
@@ -1310,8 +1359,9 @@ selector: "removeElement:",
 protocol: 'accessing',
 fn: function (anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.elements.removeElement(anObject);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"removeElement:",{anObject:anObject},globals.Organizer)})},
 args: ["anObject"],
 source: "removeElement: anObject\x0a\x09<self.elements.removeElement(anObject)>",
 messageSends: [],
@@ -1377,8 +1427,9 @@ selector: "theClass",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  return self.theClass ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"theClass",{},globals.ClassOrganizer)})},
 args: [],
 source: "theClass\x0a\x09< return self.theClass >",
 messageSends: [],
@@ -1400,8 +1451,9 @@ selector: "basicTransport",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.transport;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicTransport",{},globals.Package)})},
 args: [],
 source: "basicTransport\x0a\x09\x22Answer the transport literal JavaScript object as setup in the JavaScript file, if any\x22\x0a\x09\x0a\x09<return self.transport>",
 messageSends: [],
@@ -1565,8 +1617,9 @@ selector: "name",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.pkgName;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"name",{},globals.Package)})},
 args: [],
 source: "name\x0a\x09<return self.pkgName>",
 messageSends: [],
@@ -1580,8 +1633,9 @@ selector: "name:",
 protocol: 'accessing',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.pkgName = aString;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"name:",{aString:aString},globals.Package)})},
 args: ["aString"],
 source: "name: aString\x0a\x09<self.pkgName = aString>",
 messageSends: [],
@@ -1939,8 +1993,9 @@ selector: "globals",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return (new Function('return this'))();;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"globals",{},globals.PlatformInterface.klass)})},
 args: [],
 source: "globals\x0a\x09<return (new Function('return this'))();>",
 messageSends: [],
@@ -2370,8 +2425,9 @@ selector: "basicCreatePackage:",
 protocol: 'private',
 fn: function (packageName){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.addPackage(packageName);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicCreatePackage:",{packageName:packageName},globals.SmalltalkImage)})},
 args: ["packageName"],
 source: "basicCreatePackage: packageName\x0a\x09\x22Create and bind a new bare package with given name and return it.\x22\x0a\x09<return smalltalk.addPackage(packageName)>",
 messageSends: [],
@@ -2385,12 +2441,16 @@ selector: "basicParse:",
 protocol: 'private',
 fn: function (aString){
 var self=this;
-return smalltalk.parser.parse(aString);
-return self},
+function $SmalltalkParser(){return globals.SmalltalkParser||(typeof SmalltalkParser=="undefined"?nil:SmalltalkParser)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($SmalltalkParser())._parse_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"basicParse:",{aString:aString},globals.SmalltalkImage)})},
 args: ["aString"],
-source: "basicParse: aString\x0a\x09<return smalltalk.parser.parse(aString)>",
-messageSends: [],
-referencedClasses: []
+source: "basicParse: aString\x0a\x09^ SmalltalkParser parse: aString",
+messageSends: ["parse:"],
+referencedClasses: ["SmalltalkParser"]
 }),
 globals.SmalltalkImage);
 
@@ -2400,8 +2460,9 @@ selector: "classes",
 protocol: 'classes',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.classes();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"classes",{},globals.SmalltalkImage)})},
 args: [],
 source: "classes\x0a\x09<return smalltalk.classes()>",
 messageSends: [],
@@ -2516,8 +2577,9 @@ selector: "deleteClass:",
 protocol: 'private',
 fn: function (aClass){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 smalltalk.removeClass(aClass);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"deleteClass:",{aClass:aClass},globals.SmalltalkImage)})},
 args: ["aClass"],
 source: "deleteClass: aClass\x0a\x09\x22Deletes a class by deleting its binding only. Use #removeClass instead\x22\x0a\x09\x0a\x09<smalltalk.removeClass(aClass)>",
 messageSends: [],
@@ -2549,8 +2611,9 @@ selector: "deletePackage:",
 protocol: 'private',
 fn: function (packageName){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 delete smalltalk.packages[packageName];
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"deletePackage:",{packageName:packageName},globals.SmalltalkImage)})},
 args: ["packageName"],
 source: "deletePackage: packageName\x0a\x09\x22Deletes a package by deleting its binding, but does not check if it contains classes etc.\x0a\x09To remove a package, use #removePackage instead.\x22\x0a\x0a\x09<delete smalltalk.packages[packageName]>",
 messageSends: [],
@@ -2564,8 +2627,9 @@ selector: "globalJsVariables",
 protocol: 'globals',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.globalJsVariables;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"globalJsVariables",{},globals.SmalltalkImage)})},
 args: [],
 source: "globalJsVariables\x0a\x09\x22Array of global JavaScript variables\x22\x0a\x09<return smalltalk.globalJsVariables>",
 messageSends: [],
@@ -2579,8 +2643,9 @@ selector: "globals",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return globals;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"globals",{},globals.SmalltalkImage)})},
 args: [],
 source: "globals\x0a\x09\x22Future compatibility to be able to use Smalltalk globals at: ...\x22\x0a\x09<return globals>",
 messageSends: [],
@@ -2594,8 +2659,9 @@ selector: "includesKey:",
 protocol: 'accessing',
 fn: function (aKey){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.hasOwnProperty(aKey);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"includesKey:",{aKey:aKey},globals.SmalltalkImage)})},
 args: ["aKey"],
 source: "includesKey: aKey\x0a\x09<return smalltalk.hasOwnProperty(aKey)>",
 messageSends: [],
@@ -2609,8 +2675,9 @@ selector: "isSmalltalkObject:",
 protocol: 'testing',
 fn: function (anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return typeof anObject.klass !== 'undefined';
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"isSmalltalkObject:",{anObject:anObject},globals.SmalltalkImage)})},
 args: ["anObject"],
 source: "isSmalltalkObject: anObject\x0a\x09\x22Consider anObject a Smalltalk object if it has a 'klass' property.\x0a\x09Note that this may be unaccurate\x22\x0a\x09\x0a\x09<return typeof anObject.klass !== 'undefined'>",
 messageSends: [],
@@ -2624,8 +2691,9 @@ selector: "packageAt:",
 protocol: 'packages',
 fn: function (packageName){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.packages[packageName];
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"packageAt:",{packageName:packageName},globals.SmalltalkImage)})},
 args: ["packageName"],
 source: "packageAt: packageName\x0a\x09<return smalltalk.packages[packageName]>",
 messageSends: [],
@@ -2658,12 +2726,13 @@ selector: "packages",
 protocol: 'packages',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		return Object.keys(smalltalk.packages).map(function(k) {
 			return smalltalk.packages[k];
 		})
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"packages",{},globals.SmalltalkImage)})},
 args: [],
 source: "packages\x0a\x09\x22Return all Package instances in the system.\x22\x0a\x0a\x09<\x0a\x09\x09return Object.keys(smalltalk.packages).map(function(k) {\x0a\x09\x09\x09return smalltalk.packages[k];\x0a\x09\x09})\x0a\x09>",
 messageSends: [],
@@ -2757,8 +2826,9 @@ selector: "readJSObject:",
 protocol: 'accessing',
 fn: function (anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.readJSObject(anObject);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"readJSObject:",{anObject:anObject},globals.SmalltalkImage)})},
 args: ["anObject"],
 source: "readJSObject: anObject\x0a\x09<return smalltalk.readJSObject(anObject)>",
 messageSends: [],
@@ -2857,8 +2927,9 @@ selector: "reservedWords",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.reservedWords;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"reservedWords",{},globals.SmalltalkImage)})},
 args: [],
 source: "reservedWords\x0a\x09\x22JavaScript reserved words\x22\x0a\x09<return smalltalk.reservedWords>",
 messageSends: [],
@@ -2887,8 +2958,9 @@ selector: "vm",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"vm",{},globals.SmalltalkImage)})},
 args: [],
 source: "vm\x0a\x09\x22Future compatibility to be able to use Smalltalk vm ...\x22\x0a\x09<return smalltalk>",
 messageSends: [],

+ 66 - 33
js/Kernel-Methods.js

@@ -10,8 +10,9 @@ selector: "applyTo:arguments:",
 protocol: 'evaluating',
 fn: function (anObject,aCollection){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.apply(anObject, aCollection);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"applyTo:arguments:",{anObject:anObject,aCollection:aCollection},globals.BlockClosure)})},
 args: ["anObject", "aCollection"],
 source: "applyTo: anObject arguments: aCollection\x0a\x09<return self.apply(anObject, aCollection)>",
 messageSends: [],
@@ -25,8 +26,9 @@ selector: "asCompiledMethod:",
 protocol: 'converting',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.method({selector:aString, fn:self});;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asCompiledMethod:",{aString:aString},globals.BlockClosure)})},
 args: ["aString"],
 source: "asCompiledMethod: aString\x0a\x09<return smalltalk.method({selector:aString, fn:self});>",
 messageSends: [],
@@ -40,8 +42,9 @@ selector: "compiledSource",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.toString();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"compiledSource",{},globals.BlockClosure)})},
 args: [],
 source: "compiledSource\x0a\x09<return self.toString()>",
 messageSends: [],
@@ -55,6 +58,7 @@ selector: "currySelf",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		return function () {
 			var args = [ this ];
@@ -62,7 +66,7 @@ var self=this;
 			return self.apply(null, args);
 		}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"currySelf",{},globals.BlockClosure)})},
 args: [],
 source: "currySelf\x0a\x09\x22Transforms [ :selfarg :x :y | stcode ] block\x0a\x09which represents JS function (selfarg, x, y, ...) {jscode}\x0a\x09into function (x, y, ...) {jscode} that takes selfarg from 'this'.\x0a\x09IOW, it is usable as JS method and first arg takes the receiver.\x22\x0a\x09\x0a\x09<\x0a\x09\x09return function () {\x0a\x09\x09\x09var args = [ this ];\x0a\x09\x09\x09args.push.apply(args, arguments);\x0a\x09\x09\x09return self.apply(null, args);\x0a\x09\x09}\x0a\x09>",
 messageSends: [],
@@ -76,8 +80,9 @@ selector: "ensure:",
 protocol: 'evaluating',
 fn: function (aBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 try{return self._value()}finally{aBlock._value()};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"ensure:",{aBlock:aBlock},globals.BlockClosure)})},
 args: ["aBlock"],
 source: "ensure: aBlock\x0a\x09<try{return self._value()}finally{aBlock._value()}>",
 messageSends: [],
@@ -108,8 +113,9 @@ selector: "new",
 protocol: 'evaluating',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return new self();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"new",{},globals.BlockClosure)})},
 args: [],
 source: "new\x0a\x09\x22Use the receiver as a JS constructor.\x0a\x09*Do not* use this method to instanciate Smalltalk objects!\x22\x0a\x09<return new self()>",
 messageSends: [],
@@ -177,6 +183,7 @@ selector: "newWithValues:",
 protocol: 'evaluating',
 fn: function (aCollection){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var constructor = function() {};
 		constructor.prototype = self.prototype;
@@ -184,7 +191,7 @@ var self=this;
 		var result = self.apply(object, aCollection);
 		return typeof result === "object" ? result : object;
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"newWithValues:",{aCollection:aCollection},globals.BlockClosure)})},
 args: ["aCollection"],
 source: "newWithValues: aCollection\x0a\x09\x22Use the receiver as a JavaScript constructor with a variable number of arguments.\x0a\x09Answer the object created using the operator `new`.\x0a\x0a\x09This algorithm was inspired by http://stackoverflow.com/a/6069331.\x0a\x0a\x09Here's a general breakdown of what's going on:\x0a\x091) Create a new, empty constructor function.\x0a\x092) Set it's prototype to the receiver's prototype. Because the receiver is a `BlockClosure`, it is also a JavaScript function.\x0a\x093) Instantiate a new object using the constructor function just created. \x0a\x09\x09This forces the interpreter to set the internal [[prototype]] property to what was set on the function before. \x0a   \x09\x09This has to be done, as we have no access to the [[prototype]] property externally.\x0a\x094) Apply `self` to the object I just instantiated.\x22\x0a\x0a\x09<\x0a\x09\x09var constructor = function() {};\x0a\x09\x09constructor.prototype = self.prototype;\x0a\x09\x09var object = new constructor;\x0a\x09\x09var result = self.apply(object, aCollection);\x0a\x09\x09return typeof result === \x22object\x22 ? result : object;\x0a\x09>",
 messageSends: [],
@@ -198,8 +205,9 @@ selector: "numArgs",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.length;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"numArgs",{},globals.BlockClosure)})},
 args: [],
 source: "numArgs\x0a\x09<return self.length>",
 messageSends: [],
@@ -277,8 +285,9 @@ selector: "value",
 protocol: 'evaluating',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self();;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"value",{},globals.BlockClosure)})},
 args: [],
 source: "value\x0a\x09<return self();>",
 messageSends: [],
@@ -292,8 +301,9 @@ selector: "value:",
 protocol: 'evaluating',
 fn: function (anArg){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self(anArg);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"value:",{anArg:anArg},globals.BlockClosure)})},
 args: ["anArg"],
 source: "value: anArg\x0a\x09<return self(anArg);>",
 messageSends: [],
@@ -307,8 +317,9 @@ selector: "value:value:",
 protocol: 'evaluating',
 fn: function (firstArg,secondArg){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self(firstArg, secondArg);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"value:value:",{firstArg:firstArg,secondArg:secondArg},globals.BlockClosure)})},
 args: ["firstArg", "secondArg"],
 source: "value: firstArg value: secondArg\x0a\x09<return self(firstArg, secondArg);>",
 messageSends: [],
@@ -322,8 +333,9 @@ selector: "value:value:value:",
 protocol: 'evaluating',
 fn: function (firstArg,secondArg,thirdArg){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self(firstArg, secondArg, thirdArg);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"value:value:value:",{firstArg:firstArg,secondArg:secondArg,thirdArg:thirdArg},globals.BlockClosure)})},
 args: ["firstArg", "secondArg", "thirdArg"],
 source: "value: firstArg value: secondArg value: thirdArg\x0a\x09<return self(firstArg, secondArg, thirdArg);>",
 messageSends: [],
@@ -337,11 +349,12 @@ selector: "valueWithInterval:",
 protocol: 'timeout/interval',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var interval = setInterval(self, aNumber);
 		return globals.Timeout._on_(interval);
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"valueWithInterval:",{aNumber:aNumber},globals.BlockClosure)})},
 args: ["aNumber"],
 source: "valueWithInterval: aNumber\x0a\x09<\x0a\x09\x09var interval = setInterval(self, aNumber);\x0a\x09\x09return globals.Timeout._on_(interval);\x0a\x09>",
 messageSends: [],
@@ -355,8 +368,9 @@ selector: "valueWithPossibleArguments:",
 protocol: 'evaluating',
 fn: function (aCollection){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.apply(null, aCollection);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"valueWithPossibleArguments:",{aCollection:aCollection},globals.BlockClosure)})},
 args: ["aCollection"],
 source: "valueWithPossibleArguments: aCollection\x0a\x09<return self.apply(null, aCollection);>",
 messageSends: [],
@@ -370,11 +384,12 @@ selector: "valueWithTimeout:",
 protocol: 'timeout/interval',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var timeout = setTimeout(self, aNumber);
 		return globals.Timeout._on_(timeout);
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"valueWithTimeout:",{aNumber:aNumber},globals.BlockClosure)})},
 args: ["aNumber"],
 source: "valueWithTimeout: aNumber\x0a\x09<\x0a\x09\x09var timeout = setTimeout(self, aNumber);\x0a\x09\x09return globals.Timeout._on_(timeout);\x0a\x09>",
 messageSends: [],
@@ -406,8 +421,9 @@ selector: "whileFalse:",
 protocol: 'controlling',
 fn: function (aBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 while(!smalltalk.assert(self._value())) {aBlock._value()};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"whileFalse:",{aBlock:aBlock},globals.BlockClosure)})},
 args: ["aBlock"],
 source: "whileFalse: aBlock\x0a\x09<while(!smalltalk.assert(self._value())) {aBlock._value()}>",
 messageSends: [],
@@ -439,8 +455,9 @@ selector: "whileTrue:",
 protocol: 'controlling',
 fn: function (aBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 while(smalltalk.assert(self._value())) {aBlock._value()};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"whileTrue:",{aBlock:aBlock},globals.BlockClosure)})},
 args: ["aBlock"],
 source: "whileTrue: aBlock\x0a\x09<while(smalltalk.assert(self._value())) {aBlock._value()}>",
 messageSends: [],
@@ -458,8 +475,9 @@ selector: "arguments",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.args || [];
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"arguments",{},globals.CompiledMethod)})},
 args: [],
 source: "arguments\x0a\x09<return self.args || []>",
 messageSends: [],
@@ -1440,8 +1458,9 @@ selector: "evaluatedSelector",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.evaluatedSelector;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"evaluatedSelector",{},globals.MethodContext)})},
 args: [],
 source: "evaluatedSelector\x0a\x09<return self.evaluatedSelector>",
 messageSends: [],
@@ -1455,8 +1474,9 @@ selector: "home",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.homeContext;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"home",{},globals.MethodContext)})},
 args: [],
 source: "home\x0a\x09<return self.homeContext>",
 messageSends: [],
@@ -1470,8 +1490,9 @@ selector: "index",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.index || 0;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"index",{},globals.MethodContext)})},
 args: [],
 source: "index\x0a\x09<return self.index || 0>",
 messageSends: [],
@@ -1503,8 +1524,9 @@ selector: "locals",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.locals || {};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"locals",{},globals.MethodContext)})},
 args: [],
 source: "locals\x0a\x09<return self.locals || {}>",
 messageSends: [],
@@ -1575,8 +1597,9 @@ selector: "outerContext",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.outerContext || self.homeContext;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"outerContext",{},globals.MethodContext)})},
 args: [],
 source: "outerContext\x0a\x09<return self.outerContext || self.homeContext>",
 messageSends: [],
@@ -1612,8 +1635,9 @@ selector: "receiver",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.receiver;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"receiver",{},globals.MethodContext)})},
 args: [],
 source: "receiver\x0a\x09<return self.receiver>",
 messageSends: [],
@@ -1627,6 +1651,7 @@ selector: "selector",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		if(self.selector) {
 			return smalltalk.convertSelector(self.selector);
@@ -1634,7 +1659,7 @@ var self=this;
 			return nil;
 		}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"selector",{},globals.MethodContext)})},
 args: [],
 source: "selector\x0a\x09<\x0a\x09\x09if(self.selector) {\x0a\x09\x09\x09return smalltalk.convertSelector(self.selector);\x0a\x09\x09} else {\x0a\x09\x09\x09return nil;\x0a\x09\x09}\x0a\x09>",
 messageSends: [],
@@ -1648,8 +1673,9 @@ selector: "sendIndexAt:",
 protocol: 'accessing',
 fn: function (aSelector){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.sendIdx[aSelector] || 0;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"sendIndexAt:",{aSelector:aSelector},globals.MethodContext)})},
 args: ["aSelector"],
 source: "sendIndexAt: aSelector\x0a\x09<return self.sendIdx[aSelector] || 0>",
 messageSends: [],
@@ -1663,8 +1689,9 @@ selector: "sendIndexes",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.sendIdx;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"sendIndexes",{},globals.MethodContext)})},
 args: [],
 source: "sendIndexes\x0a\x09<return self.sendIdx>",
 messageSends: [],
@@ -1702,11 +1729,12 @@ selector: "constructor:",
 protocol: 'instance creation',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var native=eval(aString);
 		return new native();
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"constructor:",{aString:aString},globals.NativeFunction.klass)})},
 args: ["aString"],
 source: "constructor: aString\x0a\x09<\x0a\x09\x09var native=eval(aString);\x0a\x09\x09return new native();\x0a\x09>",
 messageSends: [],
@@ -1720,11 +1748,12 @@ selector: "constructor:value:",
 protocol: 'instance creation',
 fn: function (aString,anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var native=eval(aString);
 		return new native(anObject);
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:",{aString:aString,anObject:anObject},globals.NativeFunction.klass)})},
 args: ["aString", "anObject"],
 source: "constructor: aString value:anObject\x0a\x09<\x0a\x09\x09var native=eval(aString);\x0a\x09\x09return new native(anObject);\x0a\x09>",
 messageSends: [],
@@ -1738,11 +1767,12 @@ selector: "constructor:value:value:",
 protocol: 'instance creation',
 fn: function (aString,anObject,anObject2){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var native=eval(aString);
 		return new native(anObject,anObject2);
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:value:",{aString:aString,anObject:anObject,anObject2:anObject2},globals.NativeFunction.klass)})},
 args: ["aString", "anObject", "anObject2"],
 source: "constructor: aString value:anObject value: anObject2\x0a\x09<\x0a\x09\x09var native=eval(aString);\x0a\x09\x09return new native(anObject,anObject2);\x0a\x09>",
 messageSends: [],
@@ -1756,11 +1786,12 @@ selector: "constructor:value:value:value:",
 protocol: 'instance creation',
 fn: function (aString,anObject,anObject2,anObject3){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var native=eval(aString);
 		return new native(anObject,anObject2, anObject3);
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:value:value:",{aString:aString,anObject:anObject,anObject2:anObject2,anObject3:anObject3},globals.NativeFunction.klass)})},
 args: ["aString", "anObject", "anObject2", "anObject3"],
 source: "constructor: aString value:anObject value: anObject2 value:anObject3\x0a\x09<\x0a\x09\x09var native=eval(aString);\x0a\x09\x09return new native(anObject,anObject2, anObject3);\x0a\x09>",
 messageSends: [],
@@ -1796,11 +1827,12 @@ selector: "clearInterval",
 protocol: 'timeout/interval',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var interval = self["@rawTimeout"];
 		clearInterval(interval);
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"clearInterval",{},globals.Timeout)})},
 args: [],
 source: "clearInterval\x0a\x09<\x0a\x09\x09var interval = self[\x22@rawTimeout\x22];\x0a\x09\x09clearInterval(interval);\x0a\x09>",
 messageSends: [],
@@ -1814,11 +1846,12 @@ selector: "clearTimeout",
 protocol: 'timeout/interval',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var timeout = self["@rawTimeout"];
 		clearTimeout(timeout);
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"clearTimeout",{},globals.Timeout)})},
 args: [],
 source: "clearTimeout\x0a\x09<\x0a\x09\x09var timeout = self[\x22@rawTimeout\x22];\x0a\x09\x09clearTimeout(timeout);\x0a\x09>",
 messageSends: [],

+ 166 - 83
js/Kernel-Objects.js

@@ -66,8 +66,9 @@ selector: "class",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.klass;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"class",{},globals.ProtoObject)})},
 args: [],
 source: "class\x0a\x09<return self.klass>",
 messageSends: [],
@@ -102,6 +103,7 @@ selector: "identityHash",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var hash=self.identityHash;
 		if (hash) return hash;
@@ -109,7 +111,7 @@ var self=this;
 		Object.defineProperty(self, 'identityHash', {value:hash});
 		return hash;
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"identityHash",{},globals.ProtoObject)})},
 args: [],
 source: "identityHash\x0a\x09<\x0a\x09\x09var hash=self.identityHash;\x0a\x09\x09if (hash) return hash;\x0a\x09\x09hash=smalltalk.nextId();\x0a\x09\x09Object.defineProperty(self, 'identityHash', {value:hash});\x0a\x09\x09return hash;\x0a\x09>",
 messageSends: [],
@@ -168,8 +170,9 @@ selector: "instVarAt:",
 protocol: 'accessing',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  return self['@'+aString] ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"instVarAt:",{aString:aString},globals.ProtoObject)})},
 args: ["aString"],
 source: "instVarAt: aString\x0a\x09< return self['@'+aString] >",
 messageSends: [],
@@ -183,8 +186,9 @@ selector: "instVarAt:put:",
 protocol: 'accessing',
 fn: function (aString,anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  self['@' + aString] = anObject ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"instVarAt:put:",{aString:aString,anObject:anObject},globals.ProtoObject)})},
 args: ["aString", "anObject"],
 source: "instVarAt: aString put: anObject\x0a\x09< self['@' + aString] = anObject >",
 messageSends: [],
@@ -216,8 +220,9 @@ selector: "perform:withArguments:",
 protocol: 'message handling',
 fn: function (aString,aCollection){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return smalltalk.send(self, aString._asSelector(), aCollection);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"perform:withArguments:",{aString:aString,aCollection:aCollection},globals.ProtoObject)})},
 args: ["aString", "aCollection"],
 source: "perform: aString withArguments: aCollection\x0a\x09<return smalltalk.send(self, aString._asSelector(), aCollection)>",
 messageSends: [],
@@ -449,8 +454,9 @@ selector: "basicAt:",
 protocol: 'accessing',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self[aString];
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicAt:",{aString:aString},globals.Object)})},
 args: ["aString"],
 source: "basicAt: aString\x0a\x09<return self[aString]>",
 messageSends: [],
@@ -464,8 +470,9 @@ selector: "basicAt:put:",
 protocol: 'accessing',
 fn: function (aString,anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self[aString] = anObject;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicAt:put:",{aString:aString,anObject:anObject},globals.Object)})},
 args: ["aString", "anObject"],
 source: "basicAt: aString put: anObject\x0a\x09<return self[aString] = anObject>",
 messageSends: [],
@@ -479,8 +486,9 @@ selector: "basicDelete:",
 protocol: 'accessing',
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 delete self[aString]; return aString;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicDelete:",{aString:aString},globals.Object)})},
 args: ["aString"],
 source: "basicDelete: aString\x0a\x09<delete self[aString]; return aString>",
 messageSends: [],
@@ -512,8 +520,9 @@ selector: "basicPerform:withArguments:",
 protocol: 'message handling',
 fn: function (aString,aCollection){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self[aString].apply(self, aCollection);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"basicPerform:withArguments:",{aString:aString,aCollection:aCollection},globals.Object)})},
 args: ["aString", "aCollection"],
 source: "basicPerform: aString withArguments: aCollection\x0a\x09<return self[aString].apply(self, aCollection);>",
 messageSends: [],
@@ -545,6 +554,7 @@ selector: "deepCopy",
 protocol: 'copying',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var copy = self.klass._new();
 		Object.keys(self).forEach(function (i) {
@@ -554,7 +564,7 @@ var self=this;
 		});
 		return copy;
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"deepCopy",{},globals.Object)})},
 args: [],
 source: "deepCopy\x0a\x09<\x0a\x09\x09var copy = self.klass._new();\x0a\x09\x09Object.keys(self).forEach(function (i) {\x0a\x09\x09if(/^@.+/.test(i)) {\x0a\x09\x09\x09copy[i] = self[i]._deepCopy();\x0a\x09\x09}\x0a\x09\x09});\x0a\x09\x09return copy;\x0a\x09>",
 messageSends: [],
@@ -1014,6 +1024,7 @@ selector: "shallowCopy",
 protocol: 'copying',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		var copy = self.klass._new();
 		Object.keys(self).forEach(function(i) {
@@ -1023,7 +1034,7 @@ var self=this;
 		});
 		return copy;
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"shallowCopy",{},globals.Object)})},
 args: [],
 source: "shallowCopy\x0a\x09<\x0a\x09\x09var copy = self.klass._new();\x0a\x09\x09Object.keys(self).forEach(function(i) {\x0a\x09\x09if(/^@.+/.test(i)) {\x0a\x09\x09\x09copy[i] = self[i];\x0a\x09\x09}\x0a\x09\x09});\x0a\x09\x09return copy;\x0a\x09>",
 messageSends: [],
@@ -1085,8 +1096,9 @@ selector: "throw:",
 protocol: 'error handling',
 fn: function (anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  throw anObject ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"throw:",{anObject:anObject},globals.Object)})},
 args: ["anObject"],
 source: "throw: anObject\x0a\x09< throw anObject >",
 messageSends: [],
@@ -1100,8 +1112,9 @@ selector: "try:catch:",
 protocol: 'error handling',
 fn: function (aBlock,anotherBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 try{return aBlock._value()} catch(e) {return anotherBlock._value_(e)};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"try:catch:",{aBlock:aBlock,anotherBlock:anotherBlock},globals.Object)})},
 args: ["aBlock", "anotherBlock"],
 source: "try: aBlock catch: anotherBlock\x0a\x09<try{return aBlock._value()} catch(e) {return anotherBlock._value_(e)}>",
 messageSends: [],
@@ -1115,8 +1128,9 @@ selector: "value",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.valueOf();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"value",{},globals.Object)})},
 args: [],
 source: "value\x0a\x09<return self.valueOf()>",
 messageSends: [],
@@ -1227,6 +1241,7 @@ selector: "&",
 protocol: 'controlling',
 fn: function (aBoolean){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		if(self == true) {
 		return aBoolean;
@@ -1234,7 +1249,7 @@ var self=this;
 		return false;
 		}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"&",{aBoolean:aBoolean},globals.Boolean)})},
 args: ["aBoolean"],
 source: "& aBoolean\x0a\x09<\x0a\x09\x09if(self == true) {\x0a\x09\x09return aBoolean;\x0a\x09\x09} else {\x0a\x09\x09return false;\x0a\x09\x09}\x0a\x09>",
 messageSends: [],
@@ -1248,13 +1263,14 @@ selector: "=",
 protocol: 'comparing',
 fn: function (aBoolean){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		return aBoolean != null &&
 			typeof aBoolean._isBoolean === "function" &&
 			aBoolean._isBoolean() &&
 			Boolean(self == true) == aBoolean
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"=",{aBoolean:aBoolean},globals.Boolean)})},
 args: ["aBoolean"],
 source: "= aBoolean\x0a\x09<\x0a\x09\x09return aBoolean != null &&\x0a\x09\x09\x09typeof aBoolean._isBoolean === \x22function\x22 &&\x0a\x09\x09\x09aBoolean._isBoolean() &&\x0a\x09\x09\x09Boolean(self == true) == aBoolean\x0a\x09>",
 messageSends: [],
@@ -1345,8 +1361,9 @@ selector: "asString",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  return self.toString() ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asString",{},globals.Boolean)})},
 args: [],
 source: "asString\x0a\x09< return self.toString() >",
 messageSends: [],
@@ -1433,6 +1450,7 @@ selector: "ifTrue:ifFalse:",
 protocol: 'controlling',
 fn: function (aBlock,anotherBlock){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		if(self == true) {
 		return aBlock._value();
@@ -1440,7 +1458,7 @@ var self=this;
 		return anotherBlock._value();
 		}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"ifTrue:ifFalse:",{aBlock:aBlock,anotherBlock:anotherBlock},globals.Boolean)})},
 args: ["aBlock", "anotherBlock"],
 source: "ifTrue: aBlock ifFalse: anotherBlock\x0a\x09\x22inlined in the Compiler\x22\x0a\x09<\x0a\x09\x09if(self == true) {\x0a\x09\x09return aBlock._value();\x0a\x09\x09} else {\x0a\x09\x09return anotherBlock._value();\x0a\x09\x09}\x0a\x09>",
 messageSends: [],
@@ -1555,6 +1573,7 @@ selector: "|",
 protocol: 'controlling',
 fn: function (aBoolean){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		if(self == true) {
 		return true;
@@ -1562,7 +1581,7 @@ var self=this;
 		return aBoolean;
 		}
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"|",{aBoolean:aBoolean},globals.Boolean)})},
 args: ["aBoolean"],
 source: "| aBoolean\x0a\x09<\x0a\x09\x09if(self == true) {\x0a\x09\x09return true;\x0a\x09\x09} else {\x0a\x09\x09return aBoolean;\x0a\x09\x09}\x0a\x09>",
 messageSends: [],
@@ -1580,8 +1599,9 @@ selector: "+",
 protocol: 'arithmetic',
 fn: function (aDate){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self + aDate;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"+",{aDate:aDate},globals.Date)})},
 args: ["aDate"],
 source: "+ aDate\x0a\x09<return self + aDate>",
 messageSends: [],
@@ -1595,8 +1615,9 @@ selector: "-",
 protocol: 'arithmetic',
 fn: function (aDate){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self - aDate;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"-",{aDate:aDate},globals.Date)})},
 args: ["aDate"],
 source: "- aDate\x0a\x09<return self - aDate>",
 messageSends: [],
@@ -1610,8 +1631,9 @@ selector: "<",
 protocol: 'comparing',
 fn: function (aDate){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self < aDate;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"<",{aDate:aDate},globals.Date)})},
 args: ["aDate"],
 source: "< aDate\x0a\x09<return self < aDate>",
 messageSends: [],
@@ -1625,8 +1647,9 @@ selector: "<=",
 protocol: 'comparing',
 fn: function (aDate){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self <= aDate;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"<=",{aDate:aDate},globals.Date)})},
 args: ["aDate"],
 source: "<= aDate\x0a\x09<return self <= aDate>",
 messageSends: [],
@@ -1640,8 +1663,9 @@ selector: ">",
 protocol: 'comparing',
 fn: function (aDate){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self > aDate;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,">",{aDate:aDate},globals.Date)})},
 args: ["aDate"],
 source: "> aDate\x0a\x09<return self >> aDate>",
 messageSends: [],
@@ -1655,8 +1679,9 @@ selector: ">=",
 protocol: 'comparing',
 fn: function (aDate){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self >= aDate;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,">=",{aDate:aDate},globals.Date)})},
 args: ["aDate"],
 source: ">= aDate\x0a\x09<return self >>= aDate>",
 messageSends: [],
@@ -1670,8 +1695,9 @@ selector: "asDateString",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.toDateString();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asDateString",{},globals.Date)})},
 args: [],
 source: "asDateString\x0a\x09<return self.toDateString()>",
 messageSends: [],
@@ -1685,8 +1711,9 @@ selector: "asLocaleString",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.toLocaleString();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asLocaleString",{},globals.Date)})},
 args: [],
 source: "asLocaleString\x0a\x09<return self.toLocaleString()>",
 messageSends: [],
@@ -1736,8 +1763,9 @@ selector: "asString",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.toString();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asString",{},globals.Date)})},
 args: [],
 source: "asString\x0a\x09<return self.toString()>",
 messageSends: [],
@@ -1751,8 +1779,9 @@ selector: "asTimeString",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.toTimeString();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asTimeString",{},globals.Date)})},
 args: [],
 source: "asTimeString\x0a\x09<return self.toTimeString()>",
 messageSends: [],
@@ -1800,8 +1829,9 @@ selector: "dayOfMonth",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getDate();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"dayOfMonth",{},globals.Date)})},
 args: [],
 source: "dayOfMonth\x0a\x09<return self.getDate()>",
 messageSends: [],
@@ -1815,8 +1845,9 @@ selector: "dayOfMonth:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.setDate(aNumber);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"dayOfMonth:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "dayOfMonth: aNumber\x0a\x09<self.setDate(aNumber)>",
 messageSends: [],
@@ -1830,8 +1861,9 @@ selector: "dayOfWeek",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getDay() + 1;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"dayOfWeek",{},globals.Date)})},
 args: [],
 source: "dayOfWeek\x0a\x09<return self.getDay() + 1>",
 messageSends: [],
@@ -1845,8 +1877,9 @@ selector: "dayOfWeek:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.setDay(aNumber - 1);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"dayOfWeek:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "dayOfWeek: aNumber\x0a\x09<return self.setDay(aNumber - 1)>",
 messageSends: [],
@@ -1860,8 +1893,9 @@ selector: "hours",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getHours();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"hours",{},globals.Date)})},
 args: [],
 source: "hours\x0a\x09<return self.getHours()>",
 messageSends: [],
@@ -1875,8 +1909,9 @@ selector: "hours:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.setHours(aNumber);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"hours:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "hours: aNumber\x0a\x09<self.setHours(aNumber)>",
 messageSends: [],
@@ -1890,8 +1925,9 @@ selector: "milliseconds",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getMilliseconds();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"milliseconds",{},globals.Date)})},
 args: [],
 source: "milliseconds\x0a\x09<return self.getMilliseconds()>",
 messageSends: [],
@@ -1905,8 +1941,9 @@ selector: "milliseconds:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.setMilliseconds(aNumber);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"milliseconds:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "milliseconds: aNumber\x0a\x09<self.setMilliseconds(aNumber)>",
 messageSends: [],
@@ -1920,8 +1957,9 @@ selector: "minutes",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getMinutes();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"minutes",{},globals.Date)})},
 args: [],
 source: "minutes\x0a\x09<return self.getMinutes()>",
 messageSends: [],
@@ -1935,8 +1973,9 @@ selector: "minutes:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.setMinutes(aNumber);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"minutes:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "minutes: aNumber\x0a\x09<self.setMinutes(aNumber)>",
 messageSends: [],
@@ -1950,8 +1989,9 @@ selector: "month",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getMonth() + 1;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"month",{},globals.Date)})},
 args: [],
 source: "month\x0a\x09<return self.getMonth() + 1>",
 messageSends: [],
@@ -1965,8 +2005,9 @@ selector: "month:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.setMonth(aNumber - 1);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"month:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "month: aNumber\x0a\x09<self.setMonth(aNumber - 1)>",
 messageSends: [],
@@ -1996,8 +2037,9 @@ selector: "seconds",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getSeconds();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"seconds",{},globals.Date)})},
 args: [],
 source: "seconds\x0a\x09<return self.getSeconds()>",
 messageSends: [],
@@ -2011,8 +2053,9 @@ selector: "seconds:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.setSeconds(aNumber);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"seconds:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "seconds: aNumber\x0a\x09<self.setSeconds(aNumber)>",
 messageSends: [],
@@ -2026,8 +2069,9 @@ selector: "time",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getTime();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"time",{},globals.Date)})},
 args: [],
 source: "time\x0a\x09<return self.getTime()>",
 messageSends: [],
@@ -2041,8 +2085,9 @@ selector: "time:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.setTime(aNumber);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"time:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "time: aNumber\x0a\x09<self.setTime(aNumber)>",
 messageSends: [],
@@ -2056,8 +2101,9 @@ selector: "year",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.getFullYear();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"year",{},globals.Date)})},
 args: [],
 source: "year\x0a\x09<return self.getFullYear()>",
 messageSends: [],
@@ -2071,8 +2117,9 @@ selector: "year:",
 protocol: 'accessing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 self.setFullYear(aNumber);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"year:",{aNumber:aNumber},globals.Date)})},
 args: ["aNumber"],
 source: "year: aNumber\x0a\x09<self.setFullYear(aNumber)>",
 messageSends: [],
@@ -2179,8 +2226,9 @@ selector: "new:",
 protocol: 'instance creation',
 fn: function (anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return new Date(anObject);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"new:",{anObject:anObject},globals.Date.klass)})},
 args: ["anObject"],
 source: "new: anObject\x0a\x09<return new Date(anObject)>",
 messageSends: [],
@@ -2233,8 +2281,9 @@ selector: "&",
 protocol: 'converting',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self & aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"&",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "& aNumber\x0a\x09<return self & aNumber>",
 messageSends: [],
@@ -2248,8 +2297,9 @@ selector: "*",
 protocol: 'arithmetic',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self * aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"*",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "* aNumber\x0a\x09\x22Inlined in the Compiler\x22\x0a\x09<return self * aNumber>",
 messageSends: [],
@@ -2281,8 +2331,9 @@ selector: "+",
 protocol: 'arithmetic',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self + aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"+",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "+ aNumber\x0a\x09\x22Inlined in the Compiler\x22\x0a\x09<return self + aNumber>",
 messageSends: [],
@@ -2296,8 +2347,9 @@ selector: "-",
 protocol: 'arithmetic',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self - aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"-",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "- aNumber\x0a\x09\x22Inlined in the Compiler\x22\x0a\x09<return self - aNumber>",
 messageSends: [],
@@ -2311,8 +2363,9 @@ selector: "/",
 protocol: 'arithmetic',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self / aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"/",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "/ aNumber\x0a\x09\x22Inlined in the Compiler\x22\x0a\x09<return self / aNumber>",
 messageSends: [],
@@ -2344,8 +2397,9 @@ selector: "<",
 protocol: 'comparing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self < aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"<",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "< aNumber\x0a\x09\x22Inlined in the Compiler\x22\x0a\x09<return self < aNumber>",
 messageSends: [],
@@ -2359,8 +2413,9 @@ selector: "<=",
 protocol: 'comparing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self <= aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"<=",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "<= aNumber\x0a\x09\x22Inlined in the Compiler\x22\x0a\x09<return self <= aNumber>",
 messageSends: [],
@@ -2374,13 +2429,14 @@ selector: "=",
 protocol: 'comparing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		return aNumber != null &&
 			typeof aNumber._isNumber === "function" &&
 			aNumber._isNumber() &&
 			Number(self) == aNumber
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"=",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "= aNumber\x0a\x09<\x0a\x09\x09return aNumber != null &&\x0a\x09\x09\x09typeof aNumber._isNumber === \x22function\x22 &&\x0a\x09\x09\x09aNumber._isNumber() &&\x0a\x09\x09\x09Number(self) == aNumber\x0a\x09>",
 messageSends: [],
@@ -2394,8 +2450,9 @@ selector: ">",
 protocol: 'comparing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self > aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,">",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "> aNumber\x0a\x09\x22Inlined in the Compiler\x22\x0a\x09<return self >> aNumber>",
 messageSends: [],
@@ -2409,8 +2466,9 @@ selector: ">=",
 protocol: 'comparing',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self >= aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,">=",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: ">= aNumber\x0a\x09\x22Inlined in the Compiler\x22\x0a\x09<return self >>= aNumber>",
 messageSends: [],
@@ -2443,8 +2501,9 @@ selector: "\x5c\x5c",
 protocol: 'arithmetic',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self % aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"\x5c\x5c",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "\x5c\x5c aNumber\x0a\x09<return self % aNumber>",
 messageSends: [],
@@ -2458,8 +2517,9 @@ selector: "abs",
 protocol: 'arithmetic',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.abs(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"abs",{},globals.Number)})},
 args: [],
 source: "abs\x0a\x09<return Math.abs(self);>",
 messageSends: [],
@@ -2473,8 +2533,9 @@ selector: "arcCos",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.acos(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"arcCos",{},globals.Number)})},
 args: [],
 source: "arcCos\x0a\x09<return Math.acos(self);>",
 messageSends: [],
@@ -2488,8 +2549,9 @@ selector: "arcSin",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.asin(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"arcSin",{},globals.Number)})},
 args: [],
 source: "arcSin\x0a\x09<return Math.asin(self);>",
 messageSends: [],
@@ -2503,8 +2565,9 @@ selector: "arcTan",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.atan(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"arcTan",{},globals.Number)})},
 args: [],
 source: "arcTan\x0a\x09<return Math.atan(self);>",
 messageSends: [],
@@ -2586,8 +2649,9 @@ selector: "asString",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
  return String(self) ;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"asString",{},globals.Number)})},
 args: [],
 source: "asString\x0a\x09< return String(self) >",
 messageSends: [],
@@ -2620,8 +2684,9 @@ selector: "ceiling",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.ceil(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"ceiling",{},globals.Number)})},
 args: [],
 source: "ceiling\x0a\x09<return Math.ceil(self);>",
 messageSends: [],
@@ -2650,8 +2715,9 @@ selector: "cos",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.cos(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"cos",{},globals.Number)})},
 args: [],
 source: "cos\x0a\x09<return Math.cos(self);>",
 messageSends: [],
@@ -2701,8 +2767,9 @@ selector: "floor",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.floor(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"floor",{},globals.Number)})},
 args: [],
 source: "floor\x0a\x09<return Math.floor(self);>",
 messageSends: [],
@@ -2782,8 +2849,9 @@ selector: "ln",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.log(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"ln",{},globals.Number)})},
 args: [],
 source: "ln\x0a\x09<return Math.log(self);>",
 messageSends: [],
@@ -2797,8 +2865,9 @@ selector: "log",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.log(self) / Math.LN10;;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"log",{},globals.Number)})},
 args: [],
 source: "log\x0a\x09<return Math.log(self) / Math.LN10;>",
 messageSends: [],
@@ -2812,8 +2881,9 @@ selector: "log:",
 protocol: 'mathematical functions',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.log(self) / Math.log(aNumber);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"log:",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "log: aNumber\x0a\x09<return Math.log(self) / Math.log(aNumber);>",
 messageSends: [],
@@ -2827,8 +2897,9 @@ selector: "max:",
 protocol: 'arithmetic',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.max(self, aNumber);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"max:",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "max: aNumber\x0a\x09<return Math.max(self, aNumber);>",
 messageSends: [],
@@ -2842,8 +2913,9 @@ selector: "min:",
 protocol: 'arithmetic',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.min(self, aNumber);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"min:",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "min: aNumber\x0a\x09<return Math.min(self, aNumber);>",
 messageSends: [],
@@ -2945,8 +3017,9 @@ selector: "printShowingDecimalPlaces:",
 protocol: 'printing',
 fn: function (placesDesired){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self.toFixed(placesDesired);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"printShowingDecimalPlaces:",{placesDesired:placesDesired},globals.Number)})},
 args: ["placesDesired"],
 source: "printShowingDecimalPlaces: placesDesired\x0a\x09<return self.toFixed(placesDesired)>",
 messageSends: [],
@@ -2960,8 +3033,9 @@ selector: "raisedTo:",
 protocol: 'mathematical functions',
 fn: function (exponent){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.pow(self, exponent);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"raisedTo:",{exponent:exponent},globals.Number)})},
 args: ["exponent"],
 source: "raisedTo: exponent\x0a\x09<return Math.pow(self, exponent);>",
 messageSends: [],
@@ -2975,8 +3049,9 @@ selector: "rounded",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.round(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"rounded",{},globals.Number)})},
 args: [],
 source: "rounded\x0a\x09<return Math.round(self);>",
 messageSends: [],
@@ -3016,8 +3091,9 @@ selector: "sin",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.sin(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"sin",{},globals.Number)})},
 args: [],
 source: "sin\x0a\x09<return Math.sin(self);>",
 messageSends: [],
@@ -3031,8 +3107,9 @@ selector: "sqrt",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.sqrt(self);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"sqrt",{},globals.Number)})},
 args: [],
 source: "sqrt\x0a\x09<return Math.sqrt(self)>",
 messageSends: [],
@@ -3064,8 +3141,9 @@ selector: "tan",
 protocol: 'mathematical functions',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.tan(self);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"tan",{},globals.Number)})},
 args: [],
 source: "tan\x0a\x09<return Math.tan(self);>",
 messageSends: [],
@@ -3271,6 +3349,7 @@ selector: "truncated",
 protocol: 'converting',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 		if(self >= 0) {
 			return Math.floor(self);
@@ -3278,7 +3357,7 @@ var self=this;
 			return Math.floor(self * (-1)) * (-1);
 		};
 	;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"truncated",{},globals.Number)})},
 args: [],
 source: "truncated\x0a\x09<\x0a\x09\x09if(self >>= 0) {\x0a\x09\x09\x09return Math.floor(self);\x0a\x09\x09} else {\x0a\x09\x09\x09return Math.floor(self * (-1)) * (-1);\x0a\x09\x09};\x0a\x09>",
 messageSends: [],
@@ -3292,8 +3371,9 @@ selector: "|",
 protocol: 'converting',
 fn: function (aNumber){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return self | aNumber;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"|",{aNumber:aNumber},globals.Number)})},
 args: ["aNumber"],
 source: "| aNumber\x0a\x09<return self | aNumber>",
 messageSends: [],
@@ -3308,8 +3388,9 @@ selector: "e",
 protocol: 'instance creation',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.E;;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"e",{},globals.Number.klass)})},
 args: [],
 source: "e\x0a\x09<return Math.E;>",
 messageSends: [],
@@ -3353,8 +3434,9 @@ selector: "pi",
 protocol: 'instance creation',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.PI;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"pi",{},globals.Number.klass)})},
 args: [],
 source: "pi\x0a\x09<return Math.PI>",
 messageSends: [],
@@ -3686,8 +3768,9 @@ selector: "next",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return Math.random();
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"next",{},globals.Random)})},
 args: [],
 source: "next\x0a\x09<return Math.random()>",
 messageSends: [],

+ 8 - 4
js/Kernel-Tests.js

@@ -297,6 +297,7 @@ selector: "testNewWithValues",
 protocol: 'tests',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 
 	function theTestPrototype() {this.name = "theTestPrototype";}
 	function theTestConstructor(arg1, arg2, arg3) {}
@@ -309,7 +310,7 @@ var self=this;
 	"newWithValues: cannot help if the argument list is wrong, and should warn that a mistake was made."
 	function constructionShouldFail() {var anotherResult = theWrappedConstructor._newWithValues_('This is so wrong');}
 	self._should_raise_(_st(constructionShouldFail), globals.Error);;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"testNewWithValues",{},globals.BlockClosureTest)})},
 args: [],
 source: "testNewWithValues\x0a<\x0a\x09function theTestPrototype() {this.name = \x22theTestPrototype\x22;}\x0a\x09function theTestConstructor(arg1, arg2, arg3) {}\x0a\x09theTestConstructor.prototype = new theTestPrototype;\x0a\x0a\x09var theWrappedConstructor = _st(theTestConstructor);\x0a\x09var theResult = theWrappedConstructor._newWithValues_([1, 2, 3 ]);\x0a\x09self._assert_equals_(Object.getPrototypeOf(theResult).name, 'theTestPrototype');\x0a\x0a\x09\x22newWithValues: cannot help if the argument list is wrong, and should warn that a mistake was made.\x22\x0a\x09function constructionShouldFail() {var anotherResult = theWrappedConstructor._newWithValues_('This is so wrong');}\x0a\x09self._should_raise_(_st(constructionShouldFail), globals.Error);\x0a>",
 messageSends: [],
@@ -5785,8 +5786,9 @@ selector: "jsObject",
 protocol: 'accessing',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return jsObject = {a: 1, b: function() {return 2;}, c: function(object) {return object;}, d: '', 'e': null, 'f': void 0};
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"jsObject",{},globals.JSObjectProxyTest)})},
 args: [],
 source: "jsObject\x0a\x09<return jsObject = {a: 1, b: function() {return 2;}, c: function(object) {return object;}, d: '', 'e': null, 'f': void 0}>",
 messageSends: [],
@@ -6224,8 +6226,9 @@ selector: "throwException",
 protocol: 'helpers',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 throw 'test';
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"throwException",{},globals.JavaScriptExceptionTest)})},
 args: [],
 source: "throwException\x0a\x09<throw 'test'>",
 messageSends: [],
@@ -7713,8 +7716,9 @@ selector: "notDefined",
 protocol: 'tests',
 fn: function (){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return void 0;;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"notDefined",{},globals.ObjectTest)})},
 args: [],
 source: "notDefined\x0a\x09<return void 0;>",
 messageSends: [],

+ 2 - 1
js/Kernel-Transcript.js

@@ -52,8 +52,9 @@ selector: "show:",
 protocol: 'printing',
 fn: function (anObject){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
 console.log(String(_st(anObject)._asString()));
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"show:",{anObject:anObject},globals.ConsoleTranscript)})},
 args: ["anObject"],
 source: "show: anObject\x0a\x22Smalltalk objects should have no trouble displaying themselves on the Transcript; Javascript objects don't know how, so must be wrapped in a JSObectProxy.\x22\x0a<console.log(String(_st(anObject)._asString()))>",
 messageSends: [],

+ 1 - 1
package.json

@@ -36,7 +36,7 @@
     "es6-promise": "~0.1.1"
   },
   "devDependencies": {
-    "pegjs": "~0.7.0",
+    "pegjs": "~0.8.0",
     "grunt": "~0.4.0",
     "grunt-contrib-jshint": "~0.3.0",
     "amdefine": "0.0.8"

+ 32 - 20
st/Compiler-AST.st

@@ -1,6 +1,6 @@
 Smalltalk createPackage: 'Compiler-AST'!
 Object subclass: #Node
-	instanceVariableNames: 'parent position nodes shouldBeInlined shouldBeAliased'
+	instanceVariableNames: 'parent position source nodes shouldBeInlined shouldBeAliased'
 	package: 'Compiler-AST'!
 !Node commentStamp!
 I am the abstract root class of the abstract syntax tree.
@@ -66,6 +66,18 @@ position
 		self parent ifNotNil: [ :node | node position ] ]
 !
 
+position: aPosition
+	position := aPosition
+!
+
+positionEnd
+	^ self positionStart + ((self source lines size - 1) @ (self source lines last size - 1))
+!
+
+positionStart
+	^ self position
+!
+
 shouldBeAliased
 	^ shouldBeAliased ifNil: [ false ]
 !
@@ -80,6 +92,18 @@ shouldBeInlined
 
 shouldBeInlined: aBoolean
 	shouldBeInlined := aBoolean
+!
+
+size
+	^ self source size
+!
+
+source
+	^ source ifNil: [ '' ]
+!
+
+source: aString
+	source := aString
 ! !
 
 !Node methodsFor: 'building'!
@@ -87,10 +111,6 @@ shouldBeInlined: aBoolean
 nodes: aCollection
 	nodes := aCollection.
 	aCollection do: [ :each | each parent: self ]
-!
-
-position: aPosition
-	position := aPosition
 ! !
 
 !Node methodsFor: 'copying'!
@@ -340,25 +360,19 @@ accept: aVisitor
 ! !
 
 Node subclass: #JSStatementNode
-	instanceVariableNames: 'source'
+	instanceVariableNames: ''
 	package: 'Compiler-AST'!
 !JSStatementNode commentStamp!
 I represent an JavaScript statement node.!
 
-!JSStatementNode methodsFor: 'accessing'!
-
-source
-	^ source ifNil: [ '' ]
-!
-
-source: aString
-	source := aString
-! !
-
 !JSStatementNode methodsFor: 'testing'!
 
 isJSStatementNode
 	^ true
+!
+
+requiresSmalltalkContext
+	^ true
 ! !
 
 !JSStatementNode methodsFor: 'visiting'!
@@ -393,10 +407,6 @@ classReferences: aCollection
 	classReferences := aCollection
 !
 
-extent
-	^ self source lines size @ (self source lines last size + 1)
-!
-
 messageSends
 	^ self sendIndexes keys
 !
@@ -557,6 +567,7 @@ superSend: aBoolean
 valueForReceiver: anObject
 	^ SendNode new
 		position: self position;
+		source: self source;
 		receiver: (self receiver
 		ifNil: [ anObject ] 
 		ifNotNil: [ self receiver valueForReceiver: anObject ]);
@@ -630,6 +641,7 @@ temps: aCollection
 asBlockSequenceNode
 	^ BlockSequenceNode new
 		position: self position;
+		source: self source;
 		nodes: self nodes;
 		temps: self temps;
 		yourself

+ 15 - 46
st/Compiler-Interpreter.st

@@ -167,7 +167,8 @@ outerContext
 
 outerContext: anAIContext
 	outerContext := anAIContext.
-	outerContext innerContext: self
+	outerContext ifNotNil: [ :context | 
+		context innerContext: self ]
 !
 
 selector
@@ -190,6 +191,16 @@ sendIndexes: aDictionary
 	sendIndexes := aDictionary
 ! !
 
+!AIContext methodsFor: 'evaluating'!
+
+evaluateNode: aNode
+	^ ASTInterpreter new
+		context: self;
+		node: aNode nextChild;
+		proceed;
+		result
+! !
+
 !AIContext methodsFor: 'factory'!
 
 newBlockContext
@@ -321,11 +332,7 @@ context: aContext
 !
 
 interpreter
-	^ interpreter ifNil: [ interpreter := self defaultInterpreterClass new ]
-!
-
-interpreter: anInterpreter
-	interpreter := anInterpreter
+	^ self context interpreter
 !
 
 method
@@ -336,45 +343,6 @@ nextNode
 	^ self interpreter nextNode
 ! !
 
-!ASTDebugger methodsFor: 'defaults'!
-
-defaultInterpreterClass
-	^ ASTInterpreter
-! !
-
-!ASTDebugger methodsFor: 'initialization'!
-
-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 parse: self method source.
-	(SemanticAnalyzer on: self context receiver class)
-		visit: ast.
-	
-	^ ast
-!
-
-initializeInterpreter
-	| ast next |
-	ast := self buildAST.
-	next := ASTPCNodeVisitor new
-		context: self context;
-		visit: ast;
-		currentNode.
-	self interpreter node: next
-!
-
-initializeWithContext: aContext
-	"TODO: do we need to handle block contexts?"
-	
-	self context: aContext.
-	self initializeInterpreter
-! !
-
 !ASTDebugger methodsFor: 'stepping'!
 
 proceed
@@ -394,6 +362,7 @@ stepInto
 !
 
 stepOver
+	self flushOuterContexts.
 	self interpreter stepOver
 ! !
 
@@ -407,7 +376,7 @@ atEnd
 
 context: aContext
 	^ self new
-		initializeWithContext: aContext;
+		context: aContext;
 		yourself
 ! !
 

+ 13 - 0
st/Helios-Browser.st

@@ -25,6 +25,19 @@ focus
 	^ self packagesListWidget focus
 !
 
+openClassNamed: aString
+	self model openClassNamed: aString
+!
+
+openMethod: aCompiledMethod
+	self model 
+			selectedPackage: aCompiledMethod methodClass package;
+			selectedClass: aCompiledMethod methodClass;
+			selectedProtocol: aCompiledMethod protocol;
+			selectedMethod: aCompiledMethod;
+			focusOnSourceCode
+!
+
 unregister
 	super unregister.
 

+ 34 - 2
st/Helios-Commands-Tools.st

@@ -23,6 +23,38 @@ isValidFor: aModel
 	^ aModel isToolModel
 ! !
 
+HLToolCommand subclass: #HLBrowseMethodCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Tools'!
+
+!HLBrowseMethodCommand methodsFor: 'accessing'!
+
+displayLabel
+	^ 'browse method'
+! !
+
+!HLBrowseMethodCommand methodsFor: 'executing'!
+
+execute
+	self model openMethod
+! !
+
+!HLBrowseMethodCommand class methodsFor: 'accessing'!
+
+key
+	^ 'b'
+!
+
+label
+	^ 'browse method'
+! !
+
+!HLBrowseMethodCommand class methodsFor: 'testing'!
+
+isValidFor: aModel
+	^ aModel isReferencesModel
+! !
+
 HLToolCommand subclass: #HLCommitPackageCommand
 	instanceVariableNames: ''
 	package: 'Helios-Commands-Tools'!
@@ -177,7 +209,7 @@ label
 !HLFindClassCommand class methodsFor: 'testing'!
 
 isValidFor: aModel
-	^ aModel isBrowserModel
+	^ true
 ! !
 
 HLFindCommand subclass: #HLFindReferencesCommand
@@ -205,7 +237,7 @@ defaultInput
 		ifNil: [
 			self model selectedClass
 				ifNil: [ '' ]
-				ifNotNil: [ :class | class name ] ]
+				ifNotNil: [ :class | class theNonMetaClass name ] ]
 		ifNotNil: [ :method | method selector ]
 ! !
 

+ 7 - 1
st/Helios-Core.st

@@ -657,7 +657,13 @@ refresh
 !HLWidget class methodsFor: 'accessing'!
 
 openAsTab
-	HLManager current addTab: (HLTabWidget on: self new labelled: self tabLabel)
+	| instance |
+	
+	instance := self new.
+	HLManager current addTab: (HLTabWidget 
+		on: instance 
+		labelled: self tabLabel).
+	^ instance
 !
 
 tabClass

+ 71 - 11
st/Helios-Debugger.st

@@ -53,6 +53,9 @@ I am the main widget for the Helios debugger.!
 
 codeWidget
 	^ codeWidget ifNil: [ codeWidget := HLDebuggerCodeWidget new
+		model: (HLDebuggerCodeModel new
+			debuggerModel: self model;
+			yourself);
 		browserModel: self model;
 		yourself ]
 !
@@ -143,6 +146,26 @@ on: aMethodContext
 		yourself
 ! !
 
+HLCodeModel subclass: #HLDebuggerCodeModel
+	instanceVariableNames: 'debuggerModel'
+	package: 'Helios-Debugger'!
+
+!HLDebuggerCodeModel methodsFor: 'accessing'!
+
+debuggerModel
+	^ debuggerModel
+!
+
+debuggerModel: anObject
+	debuggerModel := anObject
+! !
+
+!HLDebuggerCodeModel methodsFor: 'actions'!
+
+doIt: aString
+	^ self debuggerModel evaluate: aString
+! !
+
 HLBrowserCodeWidget subclass: #HLDebuggerCodeWidget
 	instanceVariableNames: ''
 	package: 'Helios-Debugger'!
@@ -181,18 +204,13 @@ highlightNode: aNode
 	| token |
 	
 	aNode ifNotNil: [
-		token := self editor getTokenAt: #{ 
-			'line' -> (aNode position x - 1). 
-			'ch' -> aNode position y 
-		}.
-
 		self
 			clearHighlight;
-			addStopAt: aNode position x - 1.
+			addStopAt: aNode positionStart x - 1.
 
 		self editor 
-			setSelection: #{ 'line' -> (aNode position x - 1). 'ch' -> token start }
-			to: #{ 'line' -> (aNode position x - 1). 'ch' -> token end } ]
+			setSelection: #{ 'line' -> (aNode positionStart x - 1). 'ch' -> (aNode positionStart y - 1) }
+			to: #{ 'line' -> (aNode positionEnd x - 1). 'ch' -> (aNode positionEnd y) } ]
 !
 
 observeBrowserModel
@@ -224,7 +242,7 @@ HLToolModel subclass: #HLDebuggerModel
 	instanceVariableNames: 'rootContext currentContext contexts'
 	package: 'Helios-Debugger'!
 !HLDebuggerModel commentStamp!
-I am a model for Helios debugging.
+I am a model for debugging Amber code in Helios.
 
 My instances hold a reference to an `AIContext` instance, built from a `MethodContext`. The context should be the root of the context stack.!
 
@@ -264,6 +282,8 @@ rootContext
 
 restart
 	self interpreter restart.
+	self flushInnerContexts.
+	
 	self announcer announce: (HLDebuggerStepped new
 		context: self currentContext;
 		yourself)
@@ -271,6 +291,8 @@ restart
 
 skip
 	self interpreter skip.
+	self flushInnerContexts.
+	
 	self announcer announce: (HLDebuggerStepped new
 		context: self currentContext;
 		yourself)
@@ -278,6 +300,8 @@ skip
 
 stepOver
 	self interpreter stepOver.
+	self flushInnerContexts.
+	
 	self announcer announce: (HLDebuggerStepped new
 		context: self currentContext;
 		yourself)
@@ -287,6 +311,14 @@ where
 	self announcer announce: HLDebuggerWhere new
 ! !
 
+!HLDebuggerModel methodsFor: 'evaluating'!
+
+evaluate: aString
+	^ self environment 
+		interpret: aString 
+		inContext: self currentContext
+! !
+
 !HLDebuggerModel methodsFor: 'initialization'!
 
 initializeContexts
@@ -303,7 +335,18 @@ initializeContexts
 !
 
 initializeFromContext: aMethodContext
-	rootContext := AIContext fromMethodContext: aMethodContext.
+	rootContext := (AIContext fromMethodContext: aMethodContext).
+	self initializeContexts
+! !
+
+!HLDebuggerModel methodsFor: 'private'!
+
+flushInnerContexts
+	"When stepping, the inner contexts are not relevent anymore,
+	and can be flushed"
+	
+	self currentContext innerContext: nil.
+	rootContext := self currentContext.
 	self initializeContexts
 ! !
 
@@ -357,12 +400,22 @@ label
 
 !HLStackListWidget methodsFor: 'actions'!
 
+observeModel
+	super observeModel.
+	
+	self model announcer 
+		on: HLDebuggerStepped
+		send: #onDebuggerStepped:
+		to: self
+!
+
 restart
 	self model restart
 !
 
 selectItem: aContext
-   	self model currentContext: aContext
+   	self model currentContext: aContext.
+	super selectItem: aContext
 !
 
 skip
@@ -377,6 +430,13 @@ where
 	self model where
 ! !
 
+!HLStackListWidget methodsFor: 'reactions'!
+
+onDebuggerStepped: anAnnouncement
+	items := nil.
+	self refresh
+! !
+
 !HLStackListWidget methodsFor: 'rendering'!
 
 renderButtonsOn: html

+ 18 - 0
st/Helios-References.st

@@ -319,6 +319,24 @@ sendersOf: aString
 
 !HLReferencesModel methodsFor: 'actions'!
 
+openClassNamed: aString
+	| browser |
+	
+	self withChangesDo: [
+		browser := HLBrowser openAsTab.
+		browser openClassNamed: aString ]
+!
+
+openMethod
+	| browser |
+	
+	self selectedMethod ifNil: [ ^ self ].
+	
+	self withChangesDo: [
+		browser := HLBrowser openAsTab.
+		browser openMethod: self selectedMethod ]
+!
+
 search: aString
 	self updateCaches.
 	

+ 17 - 17
st/IDE.st

@@ -2343,23 +2343,6 @@ inspectOn: anInspector
 	anInspector setLabel: label
 ! !
 
-!MethodContext methodsFor: '*IDE'!
-
-inspectOn: anInspector
-	| variables |
-	variables := Dictionary new.
-	variables at: '#self' put: self.
-	variables at: '#home' put: self home.
-	variables at: '#receiver' put: self receiver.
-	variables at: '#selector' put: self selector.
-	variables at: '#temps' put: self temps.
-	self class instanceVariableNames do: [ :each |
-		variables at: each put: (self instVarAt: each) ].
-	anInspector
-		setLabel: self printString;
-		setVariables: variables
-! !
-
 !AssociativeCollection methodsFor: '*IDE'!
 
 inspectOn: anInspector
@@ -2389,3 +2372,20 @@ inspectOn: anInspector
 		setVariables: variables
 ! !
 
+!MethodContext methodsFor: '*IDE'!
+
+inspectOn: anInspector
+	| variables |
+	variables := Dictionary new.
+	variables at: '#self' put: self.
+	variables at: '#home' put: self home.
+	variables at: '#receiver' put: self receiver.
+	variables at: '#selector' put: self selector.
+	variables at: '#locals' put: self locals.
+	self class instanceVariableNames do: [ :each |
+		variables at: each put: (self instVarAt: each) ].
+	anInspector
+		setLabel: self printString;
+		setVariables: variables
+! !
+

+ 25 - 9
st/Kernel-Infrastructure.st

@@ -146,14 +146,6 @@ copyClass: aClass to: aClassName
 	ClassBuilder new copyClass: aClass named: aClassName
 !
 
-eval: aString on: aReceiver
-	| compiler |
-	compiler := Compiler new.
-	[ compiler parseExpression: aString ] on: Error do: [ :ex |
-		^ self alert: ex messageText ].
-	^ compiler evaluateExpression: aString on: aReceiver
-!
-
 inspect: anObject
 	Inspector inspect: anObject
 !
@@ -251,6 +243,30 @@ evaluate: aBlock on: anErrorClass do: exceptionBlock
  			ifFalse: [ exception signal ] ]
 ! !
 
+!Environment methodsFor: 'evaluating'!
+
+eval: aString on: aReceiver
+	| compiler |
+	compiler := Compiler new.
+	[ compiler parseExpression: aString ] on: Error do: [ :ex |
+		^ self alert: ex messageText ].
+	^ compiler evaluateExpression: aString on: aReceiver
+!
+
+interpret: aString inContext: anAIContext
+	"Similar to #eval:on:, with the following differences:
+	- instead of compiling and running `aString`, `aString` is interpreted using an `ASTInterpreter`
+	- instead of evaluating against a receiver, evaluate in the context of `anAIContext`"
+
+	| compiler ast |
+	compiler := Compiler new.
+	[ ast := compiler parseExpression: aString ] on: Error do: [ :ex |
+		^ self alert: ex messageText ].
+	(SemanticAnalyzer on: anAIContext receiver class)
+		visit: ast.
+	^ anAIContext evaluateNode: ast
+! !
+
 !Environment methodsFor: 'services'!
 
 registerErrorHandler: anErrorHandler
@@ -1103,7 +1119,7 @@ basicCreatePackage: packageName
 !
 
 basicParse: aString
-	<return smalltalk.parser.parse(aString)>
+	^ SmalltalkParser parse: aString
 !
 
 createPackage: packageName properties: aDict

+ 1 - 1
support/boot.js

@@ -1129,5 +1129,5 @@ define("amber_vm/boot", [ 'require', './browser-compatibility' ], function (requ
 		brikz.rebuild();
 	};
 
-	return { smalltalk: api, nil: brikz.root.nil, globals: globals };
+	return { vm: api, nil: brikz.root.nil, globals: globals };
 });

+ 0 - 1
support/deploy.js

@@ -1,5 +1,4 @@
 define([
-    'amber_vm/smalltalk',
     './helpers',
     'jquery',
     'amber_core/Kernel-Objects',

+ 1 - 1
support/devel.js

@@ -1,5 +1,5 @@
 define([
-	'amber_vm/smalltalk', // pre-fetch, dep of ./deploy
+	'./helpers', // pre-fetch, dep of ./deploy
 	'./deploy', // pre-fetch, dep of ./lang
 	'./lang',
 	'jquery-ui',

+ 1 - 1
support/helios.js

@@ -1,5 +1,5 @@
 define([
-	'amber_vm/smalltalk', // pre-fetch, dep of ./deploy
+	'./helpers', // pre-fetch, dep of ./deploy
 	'./deploy', // pre-fetch, dep of ./lang
 	'./lang',
 	'jquery-ui',

+ 30 - 6
support/helpers.js

@@ -1,12 +1,36 @@
-define("amber/helpers", ["amber_vm/smalltalk", "require"], function (smalltalk, require) {
-    var exports = {
-        popupHelios: function () {
-            window.open(require.toUrl('amber_helios/html/helios.html'), "Helios", "menubar=no, status=no, scrollbars=no, menubar=no, width=1000, height=600");
-        }
+define("amber/helpers", ["amber_vm/smalltalk", "amber_vm/globals", "require"], function (vm, globals, require) {
+    var exports = Object.create(globals);
+
+    // API
+
+    exports.popupHelios = function () {
+        window.open(require.toUrl('amber_helios/html/helios.html'), "Helios", "menubar=no, status=no, scrollbars=no, menubar=no, width=1000, height=600");
     };
+    Object.defineProperty(exports, "vm", {
+        value: vm,
+        enumerable: true, configurable: true, writable: false
+    });
+    Object.defineProperty(exports, "globals", {
+        value: globals,
+        enumerable: true, configurable: true, writable: false
+    });
+
+    // Backward compatibility, deprecated
+
     Object.defineProperty(exports, "smalltalk", {
-        value: smalltalk,
+        value: vm,
         enumerable: true, configurable: true, writable: false
     });
+    exports.defaultAmdNamespace = null;
+    exports.initialize = function () {
+        console.warn("smalltalk.defaultAmdNamespace is deprecated. Please use smalltalk.vm.defaultAmdNamespace instead.");
+        console.warn("smalltalk.initialize is deprecated. Please  use smalltalk.vm.initialize instead.");
+        console.warn("smalltalk.ClassName is deprecated. Please  use smalltalk.globals.ClassName instead.");
+        vm.defaultAmdNamespace = exports.defaultAmdNamespace || vm.defaultAmdNamespace;
+        return vm.initialize();
+    };
+
+    // Exports
+
     return  exports;
 });

+ 1 - 1
support/lang.js

@@ -1,5 +1,5 @@
 define([
-	'amber_vm/smalltalk', // pre-fetch, dep of ./deploy
+	'./helpers', // pre-fetch, dep of ./deploy
 	'./deploy',
 	'amber_vm/parser',
 	'amber_core/Kernel-ImportExport',

+ 3415 - 3819
support/parser.js

@@ -1,4121 +1,3717 @@
-define("amber_vm/parser", ["./smalltalk", "./nil"], function(smalltalk, nil) {
-smalltalk.parser = (function(){
+define("amber_vm/parser", ["./globals", "./nil"], function(globals, nil) {
+globals.SmalltalkParser = (function() {
   /*
-   * Generated by PEG.js 0.7.0.
+   * Generated by PEG.js 0.8.0.
    *
    * http://pegjs.majda.cz/
    */
-  
-  function quote(s) {
-    /*
-     * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
-     * string literal except for the closing quote character, backslash,
-     * carriage return, line separator, paragraph separator, and line feed.
-     * Any character may appear in the form of an escape sequence.
-     *
-     * For portability, we also escape escape all control and non-ASCII
-     * characters. Note that "\0" and "\v" escape sequences are not used
-     * because JSHint does not like the first and IE the second.
-     */
-     return '"' + s
-      .replace(/\\/g, '\\\\')  // backslash
-      .replace(/"/g, '\\"')    // closing quote character
-      .replace(/\x08/g, '\\b') // backspace
-      .replace(/\t/g, '\\t')   // horizontal tab
-      .replace(/\n/g, '\\n')   // line feed
-      .replace(/\f/g, '\\f')   // form feed
-      .replace(/\r/g, '\\r')   // carriage return
-      .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape)
-      + '"';
+
+  function peg$subclass(child, parent) {
+    function ctor() { this.constructor = child; }
+    ctor.prototype = parent.prototype;
+    child.prototype = new ctor();
   }
-  
-  var result = {
-    /*
-     * Parses the input with a generated parser. If the parsing is successfull,
-     * returns a value explicitly or implicitly specified by the grammar from
-     * which the parser was generated (see |PEG.buildParser|). If the parsing is
-     * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
-     */
-    parse: function(input, startRule) {
-      var parseFunctions = {
-        "separator": parse_separator,
-        "comments": parse_comments,
-        "ws": parse_ws,
-        "identifier": parse_identifier,
-        "keyword": parse_keyword,
-        "selector": parse_selector,
-        "className": parse_className,
-        "string": parse_string,
-        "symbol": parse_symbol,
-        "bareSymbol": parse_bareSymbol,
-        "number": parse_number,
-        "numberExp": parse_numberExp,
-        "hex": parse_hex,
-        "float": parse_float,
-        "integer": parse_integer,
-        "literalArray": parse_literalArray,
-        "bareLiteralArray": parse_bareLiteralArray,
-        "literalArrayRest": parse_literalArrayRest,
-        "dynamicArray": parse_dynamicArray,
-        "dynamicDictionary": parse_dynamicDictionary,
-        "pseudoVariable": parse_pseudoVariable,
-        "parseTimeLiteral": parse_parseTimeLiteral,
-        "runtimeLiteral": parse_runtimeLiteral,
-        "literal": parse_literal,
-        "variable": parse_variable,
-        "keywordPair": parse_keywordPair,
-        "binarySelector": parse_binarySelector,
-        "keywordPattern": parse_keywordPattern,
-        "binaryPattern": parse_binaryPattern,
-        "unaryPattern": parse_unaryPattern,
-        "expression": parse_expression,
-        "expressionList": parse_expressionList,
-        "expressions": parse_expressions,
-        "assignment": parse_assignment,
-        "ret": parse_ret,
-        "temps": parse_temps,
-        "blockParamList": parse_blockParamList,
-        "subexpression": parse_subexpression,
-        "statements": parse_statements,
-        "sequence": parse_sequence,
-        "stSequence": parse_stSequence,
-        "block": parse_block,
-        "operand": parse_operand,
-        "unaryMessage": parse_unaryMessage,
-        "unaryTail": parse_unaryTail,
-        "unarySend": parse_unarySend,
-        "binaryMessage": parse_binaryMessage,
-        "binaryTail": parse_binaryTail,
-        "binarySend": parse_binarySend,
-        "keywordMessage": parse_keywordMessage,
-        "keywordSend": parse_keywordSend,
-        "message": parse_message,
-        "cascade": parse_cascade,
-        "jsStatement": parse_jsStatement,
-        "method": parse_method
-      };
-      
-      if (startRule !== undefined) {
-        if (parseFunctions[startRule] === undefined) {
-          throw new Error("Invalid rule name: " + quote(startRule) + ".");
-        }
-      } else {
-        startRule = "method";
-      }
-      
-      var pos = { offset: 0, line: 1, column: 1, seenCR: false };
-      var reportFailures = 0;
-      var rightmostFailuresPos = { offset: 0, line: 1, column: 1, seenCR: false };
-      var rightmostFailuresExpected = [];
-      var cache = {};
-      
-      function padLeft(input, padding, length) {
-        var result = input;
-        
-        var padLength = length - input.length;
-        for (var i = 0; i < padLength; i++) {
-          result = padding + result;
-        }
-        
-        return result;
-      }
-      
-      function escape(ch) {
-        var charCode = ch.charCodeAt(0);
-        var escapeChar;
-        var length;
-        
-        if (charCode <= 0xFF) {
-          escapeChar = 'x';
-          length = 2;
-        } else {
-          escapeChar = 'u';
-          length = 4;
-        }
-        
-        return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
-      }
-      
-      function clone(object) {
-        var result = {};
-        for (var key in object) {
-          result[key] = object[key];
-        }
-        return result;
-      }
-      
-      function advance(pos, n) {
-        var endOffset = pos.offset + n;
-        
-        for (var offset = pos.offset; offset < endOffset; offset++) {
-          var ch = input.charAt(offset);
-          if (ch === "\n") {
-            if (!pos.seenCR) { pos.line++; }
-            pos.column = 1;
-            pos.seenCR = false;
-          } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
-            pos.line++;
-            pos.column = 1;
-            pos.seenCR = true;
-          } else {
-            pos.column++;
-            pos.seenCR = false;
-          }
-        }
-        
-        pos.offset += n;
-      }
-      
-      function matchFailed(failure) {
-        if (pos.offset < rightmostFailuresPos.offset) {
-          return;
-        }
-        
-        if (pos.offset > rightmostFailuresPos.offset) {
-          rightmostFailuresPos = clone(pos);
-          rightmostFailuresExpected = [];
-        }
-        
-        rightmostFailuresExpected.push(failure);
-      }
-      
-      function parse_separator() {
-        var cacheKey = "separator@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        
-        if (/^[ \t\x0B\f\xA0\uFEFF\n\r\u2028\u2029]/.test(input.charAt(pos.offset))) {
-          result1 = input.charAt(pos.offset);
-          advance(pos, 1);
-        } else {
-          result1 = null;
-          if (reportFailures === 0) {
-            matchFailed("[ \\t\\x0B\\f\\xA0\\uFEFF\\n\\r\\u2028\\u2029]");
-          }
-        }
-        if (result1 !== null) {
-          result0 = [];
-          while (result1 !== null) {
-            result0.push(result1);
-            if (/^[ \t\x0B\f\xA0\uFEFF\n\r\u2028\u2029]/.test(input.charAt(pos.offset))) {
-              result1 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result1 = null;
-              if (reportFailures === 0) {
-                matchFailed("[ \\t\\x0B\\f\\xA0\\uFEFF\\n\\r\\u2028\\u2029]");
-              }
-            }
-          }
-        } else {
-          result0 = null;
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_comments() {
-        var cacheKey = "comments@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3;
-        var pos0;
-        
-        pos0 = clone(pos);
-        if (/^["]/.test(input.charAt(pos.offset))) {
-          result1 = input.charAt(pos.offset);
-          advance(pos, 1);
-        } else {
-          result1 = null;
-          if (reportFailures === 0) {
-            matchFailed("[\"]");
-          }
-        }
-        if (result1 !== null) {
-          result2 = [];
-          if (/^[^"]/.test(input.charAt(pos.offset))) {
-            result3 = input.charAt(pos.offset);
-            advance(pos, 1);
-          } else {
-            result3 = null;
-            if (reportFailures === 0) {
-              matchFailed("[^\"]");
-            }
-          }
-          while (result3 !== null) {
-            result2.push(result3);
-            if (/^[^"]/.test(input.charAt(pos.offset))) {
-              result3 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result3 = null;
-              if (reportFailures === 0) {
-                matchFailed("[^\"]");
-              }
-            }
-          }
-          if (result2 !== null) {
-            if (/^["]/.test(input.charAt(pos.offset))) {
-              result3 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result3 = null;
-              if (reportFailures === 0) {
-                matchFailed("[\"]");
-              }
-            }
-            if (result3 !== null) {
-              result1 = [result1, result2, result3];
-            } else {
-              result1 = null;
-              pos = clone(pos0);
-            }
-          } else {
-            result1 = null;
-            pos = clone(pos0);
-          }
-        } else {
-          result1 = null;
-          pos = clone(pos0);
-        }
-        if (result1 !== null) {
-          result0 = [];
-          while (result1 !== null) {
-            result0.push(result1);
-            pos0 = clone(pos);
-            if (/^["]/.test(input.charAt(pos.offset))) {
-              result1 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result1 = null;
-              if (reportFailures === 0) {
-                matchFailed("[\"]");
-              }
-            }
-            if (result1 !== null) {
-              result2 = [];
-              if (/^[^"]/.test(input.charAt(pos.offset))) {
-                result3 = input.charAt(pos.offset);
-                advance(pos, 1);
-              } else {
-                result3 = null;
-                if (reportFailures === 0) {
-                  matchFailed("[^\"]");
-                }
-              }
-              while (result3 !== null) {
-                result2.push(result3);
-                if (/^[^"]/.test(input.charAt(pos.offset))) {
-                  result3 = input.charAt(pos.offset);
-                  advance(pos, 1);
-                } else {
-                  result3 = null;
-                  if (reportFailures === 0) {
-                    matchFailed("[^\"]");
-                  }
-                }
-              }
-              if (result2 !== null) {
-                if (/^["]/.test(input.charAt(pos.offset))) {
-                  result3 = input.charAt(pos.offset);
-                  advance(pos, 1);
-                } else {
-                  result3 = null;
-                  if (reportFailures === 0) {
-                    matchFailed("[\"]");
-                  }
-                }
-                if (result3 !== null) {
-                  result1 = [result1, result2, result3];
-                } else {
-                  result1 = null;
-                  pos = clone(pos0);
-                }
-              } else {
-                result1 = null;
-                pos = clone(pos0);
-              }
-            } else {
-              result1 = null;
-              pos = clone(pos0);
-            }
-          }
-        } else {
-          result0 = null;
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_ws() {
-        var cacheKey = "ws@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        
-        result0 = [];
-        result1 = parse_separator();
-        if (result1 === null) {
-          result1 = parse_comments();
-        }
-        while (result1 !== null) {
-          result0.push(result1);
-          result1 = parse_separator();
-          if (result1 === null) {
-            result1 = parse_comments();
-          }
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_identifier() {
-        var cacheKey = "identifier@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (/^[a-zA-Z]/.test(input.charAt(pos.offset))) {
-          result0 = input.charAt(pos.offset);
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("[a-zA-Z]");
-          }
-        }
-        if (result0 !== null) {
-          result1 = [];
-          if (/^[a-zA-Z0-9]/.test(input.charAt(pos.offset))) {
-            result2 = input.charAt(pos.offset);
-            advance(pos, 1);
-          } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("[a-zA-Z0-9]");
-            }
-          }
-          while (result2 !== null) {
-            result1.push(result2);
-            if (/^[a-zA-Z0-9]/.test(input.charAt(pos.offset))) {
-              result2 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("[a-zA-Z0-9]");
-              }
-            }
-          }
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, first, others) {return first + others.join("");})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_keyword() {
-        var cacheKey = "keyword@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_identifier();
-        if (result0 !== null) {
-          if (/^[:]/.test(input.charAt(pos.offset))) {
-            result1 = input.charAt(pos.offset);
-            advance(pos, 1);
-          } else {
-            result1 = null;
-            if (reportFailures === 0) {
-              matchFailed("[:]");
-            }
-          }
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, first, last) {return first + last;})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_selector() {
-        var cacheKey = "selector@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (/^[a-zA-Z]/.test(input.charAt(pos.offset))) {
-          result0 = input.charAt(pos.offset);
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("[a-zA-Z]");
-          }
-        }
-        if (result0 !== null) {
-          result1 = [];
-          if (/^[a-zA-Z0-9:]/.test(input.charAt(pos.offset))) {
-            result2 = input.charAt(pos.offset);
-            advance(pos, 1);
-          } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("[a-zA-Z0-9:]");
-            }
-          }
-          while (result2 !== null) {
-            result1.push(result2);
-            if (/^[a-zA-Z0-9:]/.test(input.charAt(pos.offset))) {
-              result2 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("[a-zA-Z0-9:]");
-              }
-            }
-          }
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, first, others) {return first + others.join("");})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_className() {
-        var cacheKey = "className@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (/^[A-Z]/.test(input.charAt(pos.offset))) {
-          result0 = input.charAt(pos.offset);
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("[A-Z]");
-          }
-        }
-        if (result0 !== null) {
-          result1 = [];
-          if (/^[a-zA-Z0-9]/.test(input.charAt(pos.offset))) {
-            result2 = input.charAt(pos.offset);
-            advance(pos, 1);
-          } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("[a-zA-Z0-9]");
-            }
-          }
-          while (result2 !== null) {
-            result1.push(result2);
-            if (/^[a-zA-Z0-9]/.test(input.charAt(pos.offset))) {
-              result2 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("[a-zA-Z0-9]");
-              }
-            }
-          }
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, first, others) {return first + others.join("");})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_string() {
-        var cacheKey = "string@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2;
-        var pos0, pos1, pos2;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (/^[']/.test(input.charAt(pos.offset))) {
-          result0 = input.charAt(pos.offset);
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("[']");
-          }
-        }
-        if (result0 !== null) {
-          result1 = [];
-          pos2 = clone(pos);
-          if (input.substr(pos.offset, 2) === "''") {
-            result2 = "''";
-            advance(pos, 2);
-          } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("\"''\"");
-            }
-          }
-          if (result2 !== null) {
-            result2 = (function(offset, line, column) {return "'";})(pos2.offset, pos2.line, pos2.column);
-          }
-          if (result2 === null) {
-            pos = clone(pos2);
-          }
-          if (result2 === null) {
-            if (/^[^']/.test(input.charAt(pos.offset))) {
-              result2 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("[^']");
-              }
-            }
-          }
-          while (result2 !== null) {
-            result1.push(result2);
-            pos2 = clone(pos);
-            if (input.substr(pos.offset, 2) === "''") {
-              result2 = "''";
-              advance(pos, 2);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("\"''\"");
-              }
-            }
-            if (result2 !== null) {
-              result2 = (function(offset, line, column) {return "'";})(pos2.offset, pos2.line, pos2.column);
-            }
-            if (result2 === null) {
-              pos = clone(pos2);
-            }
-            if (result2 === null) {
-              if (/^[^']/.test(input.charAt(pos.offset))) {
-                result2 = input.charAt(pos.offset);
-                advance(pos, 1);
-              } else {
-                result2 = null;
-                if (reportFailures === 0) {
-                  matchFailed("[^']");
-                }
-              }
-            }
-          }
-          if (result1 !== null) {
-            if (/^[']/.test(input.charAt(pos.offset))) {
-              result2 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("[']");
-              }
-            }
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, val) {
-                             return smalltalk.ValueNode._new()
-                                    ._position_((line).__at(column))
+
+  function SyntaxError(message, expected, found, offset, line, column) {
+    this.message  = message;
+    this.expected = expected;
+    this.found    = found;
+    this.offset   = offset;
+    this.line     = line;
+    this.column   = column;
+
+    this.name     = "SyntaxError";
+  }
+
+  peg$subclass(SyntaxError, Error);
+
+  function parse(input) {
+    var options = arguments.length > 1 ? arguments[1] : {},
+
+        peg$FAILED = {},
+
+        peg$startRuleFunctions = { start: peg$parsestart },
+        peg$startRuleFunction  = peg$parsestart,
+
+        peg$c0 = [],
+        peg$c1 = peg$FAILED,
+        peg$c2 = /^[ \t\x0B\f\xA0\uFEFF\n\r\u2028\u2029]/,
+        peg$c3 = { type: "class", value: "[ \\t\\x0B\\f\\xA0\\uFEFF\\n\\r\\u2028\\u2029]", description: "[ \\t\\x0B\\f\\xA0\\uFEFF\\n\\r\\u2028\\u2029]" },
+        peg$c4 = /^["]/,
+        peg$c5 = { type: "class", value: "[\"]", description: "[\"]" },
+        peg$c6 = /^[^"]/,
+        peg$c7 = { type: "class", value: "[^\"]", description: "[^\"]" },
+        peg$c8 = /^[a-zA-Z]/,
+        peg$c9 = { type: "class", value: "[a-zA-Z]", description: "[a-zA-Z]" },
+        peg$c10 = /^[a-zA-Z0-9]/,
+        peg$c11 = { type: "class", value: "[a-zA-Z0-9]", description: "[a-zA-Z0-9]" },
+        peg$c12 = function(first, others) {return first + others.join("");},
+        peg$c13 = /^[:]/,
+        peg$c14 = { type: "class", value: "[:]", description: "[:]" },
+        peg$c15 = function(first, last) {return first + last;},
+        peg$c16 = /^[a-zA-Z0-9:]/,
+        peg$c17 = { type: "class", value: "[a-zA-Z0-9:]", description: "[a-zA-Z0-9:]" },
+        peg$c18 = /^[A-Z]/,
+        peg$c19 = { type: "class", value: "[A-Z]", description: "[A-Z]" },
+        peg$c20 = /^[']/,
+        peg$c21 = { type: "class", value: "[']", description: "[']" },
+        peg$c22 = "''",
+        peg$c23 = { type: "literal", value: "''", description: "\"''\"" },
+        peg$c24 = function() {return "'";},
+        peg$c25 = /^[^']/,
+        peg$c26 = { type: "class", value: "[^']", description: "[^']" },
+        peg$c27 = function(val) {
+                             return globals.ValueNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
                                     ._value_(val.join("").replace(/\"/ig, '"'));
-                         })(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_symbol() {
-        var cacheKey = "symbol@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.charCodeAt(pos.offset) === 35) {
-          result0 = "#";
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"#\"");
-          }
-        }
-        if (result0 !== null) {
-          result1 = parse_bareSymbol();
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, rest) {return rest;})(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_bareSymbol() {
-        var cacheKey = "bareSymbol@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        result0 = parse_selector();
-        if (result0 === null) {
-          result0 = parse_binarySelector();
-          if (result0 === null) {
-            pos1 = clone(pos);
-            result0 = parse_string();
-            if (result0 !== null) {
-              result0 = (function(offset, line, column, node) {return node._value();})(pos1.offset, pos1.line, pos1.column, result0);
-            }
-            if (result0 === null) {
-              pos = clone(pos1);
-            }
-          }
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, val) {
-                              return smalltalk.ValueNode._new()
-                                     ._position_((line).__at(column))
+                         },
+        peg$c28 = "#",
+        peg$c29 = { type: "literal", value: "#", description: "\"#\"" },
+        peg$c30 = function(rest) {return rest;},
+        peg$c31 = function(node) {return node._value();},
+        peg$c32 = function(val) {
+                              return globals.ValueNode._new()
+                                     ._position_((line()).__at(column()))
+                                     ._source_(text())
                                      ._value_(val);
-                          })(pos0.offset, pos0.line, pos0.column, result0);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_number() {
-        var cacheKey = "number@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        var pos0;
-        
-        pos0 = clone(pos);
-        result0 = parse_numberExp();
-        if (result0 === null) {
-          result0 = parse_hex();
-          if (result0 === null) {
-            result0 = parse_float();
-            if (result0 === null) {
-              result0 = parse_integer();
-            }
-          }
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, n) {
-                             return smalltalk.ValueNode._new()
-                                    ._position_((line).__at(column))
+                          },
+        peg$c33 = function(n) {
+                             return globals.ValueNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
                                     ._value_(n);
-                         })(pos0.offset, pos0.line, pos0.column, result0);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_numberExp() {
-        var cacheKey = "numberExp@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_float();
-        if (result0 === null) {
-          result0 = parse_integer();
-        }
-        if (result0 !== null) {
-          if (input.charCodeAt(pos.offset) === 101) {
-            result1 = "e";
-            advance(pos, 1);
-          } else {
-            result1 = null;
-            if (reportFailures === 0) {
-              matchFailed("\"e\"");
-            }
-          }
-          if (result1 !== null) {
-            result2 = parse_integer();
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, n) {return parseFloat(n.join(""));})(pos0.offset, pos0.line, pos0.column, result0);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_hex() {
-        var cacheKey = "hex@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (/^[\-]/.test(input.charAt(pos.offset))) {
-          result0 = input.charAt(pos.offset);
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("[\\-]");
-          }
-        }
-        result0 = result0 !== null ? result0 : "";
-        if (result0 !== null) {
-          if (input.substr(pos.offset, 3) === "16r") {
-            result1 = "16r";
-            advance(pos, 3);
-          } else {
-            result1 = null;
-            if (reportFailures === 0) {
-              matchFailed("\"16r\"");
-            }
-          }
-          if (result1 !== null) {
-            if (/^[0-9a-fA-F]/.test(input.charAt(pos.offset))) {
-              result3 = input.charAt(pos.offset);
-              advance(pos, 1);
-            } else {
-              result3 = null;
-              if (reportFailures === 0) {
-                matchFailed("[0-9a-fA-F]");
-              }
-            }
-            if (result3 !== null) {
-              result2 = [];
-              while (result3 !== null) {
-                result2.push(result3);
-                if (/^[0-9a-fA-F]/.test(input.charAt(pos.offset))) {
-                  result3 = input.charAt(pos.offset);
-                  advance(pos, 1);
-                } else {
-                  result3 = null;
-                  if (reportFailures === 0) {
-                    matchFailed("[0-9a-fA-F]");
-                  }
-                }
-              }
-            } else {
-              result2 = null;
-            }
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
+                         },
+        peg$c34 = "e",
+        peg$c35 = { type: "literal", value: "e", description: "\"e\"" },
+        peg$c36 = function(n) {return parseFloat(n.join(""));},
+        peg$c37 = null,
+        peg$c38 = /^[\-]/,
+        peg$c39 = { type: "class", value: "[\\-]", description: "[\\-]" },
+        peg$c40 = "16r",
+        peg$c41 = { type: "literal", value: "16r", description: "\"16r\"" },
+        peg$c42 = /^[0-9a-fA-F]/,
+        peg$c43 = { type: "class", value: "[0-9a-fA-F]", description: "[0-9a-fA-F]" },
+        peg$c44 = function(neg, num) {return parseInt(((neg || '') + num.join("")), 16);},
+        peg$c45 = /^[0-9]/,
+        peg$c46 = { type: "class", value: "[0-9]", description: "[0-9]" },
+        peg$c47 = ".",
+        peg$c48 = { type: "literal", value: ".", description: "\".\"" },
+        peg$c49 = function(neg, digits, dec) {return parseFloat(((neg || '') + digits.join("") + "." + dec.join("")), 10);},
+        peg$c50 = function(neg, digits) {return (parseInt((neg || '') +digits.join(""), 10));},
+        peg$c51 = "#(",
+        peg$c52 = { type: "literal", value: "#(", description: "\"#(\"" },
+        peg$c53 = "(",
+        peg$c54 = { type: "literal", value: "(", description: "\"(\"" },
+        peg$c55 = function(lit) {return lit._value();},
+        peg$c56 = ")",
+        peg$c57 = { type: "literal", value: ")", description: "\")\"" },
+        peg$c58 = function(lits) {
+                             return globals.ValueNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._value_(lits);
+                         },
+        peg$c59 = "{",
+        peg$c60 = { type: "literal", value: "{", description: "\"{\"" },
+        peg$c61 = "}",
+        peg$c62 = { type: "literal", value: "}", description: "\"}\"" },
+        peg$c63 = function(expressions) {
+                             return globals.DynamicArrayNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._nodes_(expressions || []);
+                         },
+        peg$c64 = "#{",
+        peg$c65 = { type: "literal", value: "#{", description: "\"#{\"" },
+        peg$c66 = function(expressions) {
+                                return globals.DynamicDictionaryNode._new()
+                                       ._position_((line()).__at(column()))
+                                       ._source_(text())
+                                       ._nodes_(expressions || []);
+                            },
+        peg$c67 = "true",
+        peg$c68 = { type: "literal", value: "true", description: "\"true\"" },
+        peg$c69 = function() {return true;},
+        peg$c70 = "false",
+        peg$c71 = { type: "literal", value: "false", description: "\"false\"" },
+        peg$c72 = function() {return false;},
+        peg$c73 = "nil",
+        peg$c74 = { type: "literal", value: "nil", description: "\"nil\"" },
+        peg$c75 = function() {return nil;},
+        peg$c76 = function(val) {
+                               return globals.ValueNode._new()
+                                      ._position_((line()).__at(column()))
+                                      ._source_(text())
+                                      ._value_(val);
+                           },
+        peg$c77 = function(identifier) {
+                             return globals.VariableNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._value_(identifier);
+                         },
+        peg$c78 = function(key, arg) {return {key:key, arg: arg};},
+        peg$c79 = /^[\\+*\/=><,@%~|&\-]/,
+        peg$c80 = { type: "class", value: "[\\\\+*\\/=><,@%~|&\\-]", description: "[\\\\+*\\/=><,@%~|&\\-]" },
+        peg$c81 = function(bin) {return bin.join("");},
+        peg$c82 = function(pairs) {
+                             var keywords = [];
+                             var params = [];
+                             var i = 0;
+                             for(i = 0; i < pairs.length; i++){
+                                 keywords.push(pairs[i].key);
+                             }
+                             for(i = 0; i < pairs.length; i++){
+                                 params.push(pairs[i].arg);
+                             }
+                             return [keywords.join(""), params];
+                         },
+        peg$c83 = function(selector, arg) {return [selector, [arg]];},
+        peg$c84 = function(selector) {return [selector, []];},
+        peg$c85 = function(expression) {return expression;},
+        peg$c86 = function(first, others) {
+                             var result = [first];
+                             for(var i = 0; i < others.length; i++) {
+                                 result.push(others[i]);
+                             }
+                             return result;
+                         },
+        peg$c87 = ":=",
+        peg$c88 = { type: "literal", value: ":=", description: "\":=\"" },
+        peg$c89 = function(variable, expression) {
+                             return globals.AssignmentNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._left_(variable)
+                                    ._right_(expression);
+                         },
+        peg$c90 = "^",
+        peg$c91 = { type: "literal", value: "^", description: "\"^\"" },
+        peg$c92 = function(expression) {
+                             return globals.ReturnNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._nodes_([expression]);
+                         },
+        peg$c93 = "|",
+        peg$c94 = { type: "literal", value: "|", description: "\"|\"" },
+        peg$c95 = function(variable) {return variable;},
+        peg$c96 = function(vars) {return vars;},
+        peg$c97 = ":",
+        peg$c98 = { type: "literal", value: ":", description: "\":\"" },
+        peg$c99 = function(param) {return param;},
+        peg$c100 = function(params) {return params;},
+        peg$c101 = /^[.]/,
+        peg$c102 = { type: "class", value: "[.]", description: "[.]" },
+        peg$c103 = function(ret) {return [ret];},
+        peg$c104 = function(exps, ret) {
+                               var expressions = exps;
+                               expressions.push(ret);
+                               return expressions;
+                           },
+        peg$c105 = function(expressions) {
+                               return expressions || [];
+                           },
+        peg$c106 = function(temps, statements) {
+                             return globals.SequenceNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._temps_(temps || [])
+                                    ._nodes_(statements || []);
+                         },
+        peg$c107 = "[",
+        peg$c108 = { type: "literal", value: "[", description: "\"[\"" },
+        peg$c109 = "]",
+        peg$c110 = { type: "literal", value: "]", description: "\"]\"" },
+        peg$c111 = function(params, sequence) {
+                             return globals.BlockNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._parameters_(params || [])
+                                    ._nodes_([sequence._asBlockSequenceNode()]);
+                         },
+        peg$c112 = void 0,
+        peg$c113 = function(selector) {
+                             return globals.SendNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._selector_(selector);
+                         },
+        peg$c114 = function(message, tail) {
+                             if(tail) {
+                                 return tail._valueForReceiver_(message);
+                             }
+                             else {
+                                 return message;
+                             }
+                         },
+        peg$c115 = function(receiver, tail) {
+                             if(tail) {
+                                 return tail._valueForReceiver_(receiver);
+                             }
+                             else {
+                                 return receiver;
+                             }
+                         },
+        peg$c116 = function(selector, arg) {
+                             return globals.SendNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._selector_(selector)
+                                    ._arguments_([arg]);
+                         },
+        peg$c117 = function(message, tail) {
+                             if(tail) {
+                                 return tail._valueForReceiver_(message);
+                              }
+                             else {
+                                 return message;
+                             }
+                         },
+        peg$c118 = function(pair) {return pair;},
+        peg$c119 = function(pairs) {
+                             var selector = [];
+                             var args = [];
+                              for(var i = 0; i < pairs.length; i++) {
+                                  selector.push(pairs[i].key);
+                                  args.push(pairs[i].arg);
+                              }
+                              return globals.SendNode._new()
+                                     ._position_((line()).__at(column()))
+                                     ._source_(text())
+                                     ._selector_(selector.join(""))
+                                     ._arguments_(args);
+                         },
+        peg$c120 = function(receiver, tail) {
+                             return tail._valueForReceiver_(receiver);
+                         },
+        peg$c121 = ";",
+        peg$c122 = { type: "literal", value: ";", description: "\";\"" },
+        peg$c123 = function(mess) {return mess;},
+        peg$c124 = function(send, messages) {
+                             var cascade = [];
+                             cascade.push(send);
+                             for(var i = 0; i < messages.length; i++) {
+                                 cascade.push(messages[i]);
+                             }
+                             return globals.CascadeNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(text())
+                                    ._receiver_(send._receiver())
+                                    ._nodes_(cascade);
+                         },
+        peg$c125 = "<",
+        peg$c126 = { type: "literal", value: "<", description: "\"<\"" },
+        peg$c127 = ">>",
+        peg$c128 = { type: "literal", value: ">>", description: "\">>\"" },
+        peg$c129 = function() {return ">";},
+        peg$c130 = /^[^>]/,
+        peg$c131 = { type: "class", value: "[^>]", description: "[^>]" },
+        peg$c132 = ">",
+        peg$c133 = { type: "literal", value: ">", description: "\">\"" },
+        peg$c134 = function(val) {
+                             return globals.JSStatementNode._new()
+                                    ._position_((line()).__at(column()))
+                                    ._source_(val.join(""))
+                         },
+        peg$c135 = function(pattern, sequence) {
+                              return globals.MethodNode._new()
+                                     ._position_((line()).__at(column()))
+                                     ._source_(text())
+                                     ._selector_(pattern[0])
+                                     ._arguments_(pattern[1])
+                                     ._nodes_([sequence]);
+                         },
+
+        peg$currPos          = 0,
+        peg$reportedPos      = 0,
+        peg$cachedPos        = 0,
+        peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
+        peg$maxFailPos       = 0,
+        peg$maxFailExpected  = [],
+        peg$silentFails      = 0,
+
+        peg$cache = {},
+        peg$result;
+
+    if ("startRule" in options) {
+      if (!(options.startRule in peg$startRuleFunctions)) {
+        throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
+      }
+
+      peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
+    }
+
+    function text() {
+      return input.substring(peg$reportedPos, peg$currPos);
+    }
+
+    function offset() {
+      return peg$reportedPos;
+    }
+
+    function line() {
+      return peg$computePosDetails(peg$reportedPos).line;
+    }
+
+    function column() {
+      return peg$computePosDetails(peg$reportedPos).column;
+    }
+
+    function expected(description) {
+      throw peg$buildException(
+        null,
+        [{ type: "other", description: description }],
+        peg$reportedPos
+      );
+    }
+
+    function error(message) {
+      throw peg$buildException(message, null, peg$reportedPos);
+    }
+
+    function peg$computePosDetails(pos) {
+      function advance(details, startPos, endPos) {
+        var p, ch;
+
+        for (p = startPos; p < endPos; p++) {
+          ch = input.charAt(p);
+          if (ch === "\n") {
+            if (!details.seenCR) { details.line++; }
+            details.column = 1;
+            details.seenCR = false;
+          } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
+            details.line++;
+            details.column = 1;
+            details.seenCR = true;
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            details.column++;
+            details.seenCR = false;
           }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
         }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, neg, num) {return parseInt((neg + num.join("")), 16);})(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_float() {
-        var cacheKey = "float@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (/^[\-]/.test(input.charAt(pos.offset))) {
-          result0 = input.charAt(pos.offset);
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("[\\-]");
-          }
+      }
+
+      if (peg$cachedPos !== pos) {
+        if (peg$cachedPos > pos) {
+          peg$cachedPos = 0;
+          peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
         }
-        result0 = result0 !== null ? result0 : "";
-        if (result0 !== null) {
-          if (/^[0-9]/.test(input.charAt(pos.offset))) {
-            result2 = input.charAt(pos.offset);
-            advance(pos, 1);
-          } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("[0-9]");
-            }
-          }
-          if (result2 !== null) {
-            result1 = [];
-            while (result2 !== null) {
-              result1.push(result2);
-              if (/^[0-9]/.test(input.charAt(pos.offset))) {
-                result2 = input.charAt(pos.offset);
-                advance(pos, 1);
-              } else {
-                result2 = null;
-                if (reportFailures === 0) {
-                  matchFailed("[0-9]");
-                }
-              }
-            }
-          } else {
-            result1 = null;
-          }
-          if (result1 !== null) {
-            if (input.charCodeAt(pos.offset) === 46) {
-              result2 = ".";
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("\".\"");
-              }
-            }
-            if (result2 !== null) {
-              if (/^[0-9]/.test(input.charAt(pos.offset))) {
-                result4 = input.charAt(pos.offset);
-                advance(pos, 1);
-              } else {
-                result4 = null;
-                if (reportFailures === 0) {
-                  matchFailed("[0-9]");
-                }
-              }
-              if (result4 !== null) {
-                result3 = [];
-                while (result4 !== null) {
-                  result3.push(result4);
-                  if (/^[0-9]/.test(input.charAt(pos.offset))) {
-                    result4 = input.charAt(pos.offset);
-                    advance(pos, 1);
-                  } else {
-                    result4 = null;
-                    if (reportFailures === 0) {
-                      matchFailed("[0-9]");
-                    }
-                  }
-                }
-              } else {
-                result3 = null;
-              }
-              if (result3 !== null) {
-                result0 = [result0, result1, result2, result3];
-              } else {
-                result0 = null;
-                pos = clone(pos1);
-              }
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
+        advance(peg$cachedPosDetails, peg$cachedPos, pos);
+        peg$cachedPos = pos;
+      }
+
+      return peg$cachedPosDetails;
+    }
+
+    function peg$fail(expected) {
+      if (peg$currPos < peg$maxFailPos) { return; }
+
+      if (peg$currPos > peg$maxFailPos) {
+        peg$maxFailPos = peg$currPos;
+        peg$maxFailExpected = [];
+      }
+
+      peg$maxFailExpected.push(expected);
+    }
+
+    function peg$buildException(message, expected, pos) {
+      function cleanupExpected(expected) {
+        var i = 1;
+
+        expected.sort(function(a, b) {
+          if (a.description < b.description) {
+            return -1;
+          } else if (a.description > b.description) {
+            return 1;
+          } else {
+            return 0;
+          }
+        });
+
+        while (i < expected.length) {
+          if (expected[i - 1] === expected[i]) {
+            expected.splice(i, 1);
+          } else {
+            i++;
+          }
+        }
+      }
+
+      function buildMessage(expected, found) {
+        function stringEscape(s) {
+          function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
+
+          return s
+            .replace(/\\/g,   '\\\\')
+            .replace(/"/g,    '\\"')
+            .replace(/\x08/g, '\\b')
+            .replace(/\t/g,   '\\t')
+            .replace(/\n/g,   '\\n')
+            .replace(/\f/g,   '\\f')
+            .replace(/\r/g,   '\\r')
+            .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
+            .replace(/[\x10-\x1F\x80-\xFF]/g,    function(ch) { return '\\x'  + hex(ch); })
+            .replace(/[\u0180-\u0FFF]/g,         function(ch) { return '\\u0' + hex(ch); })
+            .replace(/[\u1080-\uFFFF]/g,         function(ch) { return '\\u'  + hex(ch); });
+        }
+
+        var expectedDescs = new Array(expected.length),
+            expectedDesc, foundDesc, i;
+
+        for (i = 0; i < expected.length; i++) {
+          expectedDescs[i] = expected[i].description;
+        }
+
+        expectedDesc = expected.length > 1
+          ? expectedDescs.slice(0, -1).join(", ")
+              + " or "
+              + expectedDescs[expected.length - 1]
+          : expectedDescs[0];
+
+        foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
+
+        return "Expected " + expectedDesc + " but " + foundDesc + " found.";
+      }
+
+      var posDetails = peg$computePosDetails(pos),
+          found      = pos < input.length ? input.charAt(pos) : null;
+
+      if (expected !== null) {
+        cleanupExpected(expected);
+      }
+
+      return new SyntaxError(
+        message !== null ? message : buildMessage(expected, found),
+        expected,
+        found,
+        pos,
+        posDetails.line,
+        posDetails.column
+      );
+    }
+
+    function peg$parsestart() {
+      var s0;
+
+      var key    = peg$currPos * 56 + 0,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$parsemethod();
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseseparator() {
+      var s0, s1;
+
+      var key    = peg$currPos * 56 + 1,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = [];
+      if (peg$c2.test(input.charAt(peg$currPos))) {
+        s1 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c3); }
+      }
+      if (s1 !== peg$FAILED) {
+        while (s1 !== peg$FAILED) {
+          s0.push(s1);
+          if (peg$c2.test(input.charAt(peg$currPos))) {
+            s1 = input.charAt(peg$currPos);
+            peg$currPos++;
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            s1 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c3); }
           }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
         }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, neg, digits, dec) {return parseFloat((neg + digits.join("") + "." + dec.join("")), 10);})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1], result0[3]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_integer() {
-        var cacheKey = "integer@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (/^[\-]/.test(input.charAt(pos.offset))) {
-          result0 = input.charAt(pos.offset);
-          advance(pos, 1);
+      } else {
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsecomments() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 2,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = [];
+      s1 = peg$currPos;
+      if (peg$c4.test(input.charAt(peg$currPos))) {
+        s2 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s2 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c5); }
+      }
+      if (s2 !== peg$FAILED) {
+        s3 = [];
+        if (peg$c6.test(input.charAt(peg$currPos))) {
+          s4 = input.charAt(peg$currPos);
+          peg$currPos++;
         } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("[\\-]");
-          }
+          s4 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c7); }
         }
-        result0 = result0 !== null ? result0 : "";
-        if (result0 !== null) {
-          if (/^[0-9]/.test(input.charAt(pos.offset))) {
-            result2 = input.charAt(pos.offset);
-            advance(pos, 1);
-          } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("[0-9]");
-            }
-          }
-          if (result2 !== null) {
-            result1 = [];
-            while (result2 !== null) {
-              result1.push(result2);
-              if (/^[0-9]/.test(input.charAt(pos.offset))) {
-                result2 = input.charAt(pos.offset);
-                advance(pos, 1);
-              } else {
-                result2 = null;
-                if (reportFailures === 0) {
-                  matchFailed("[0-9]");
-                }
-              }
-            }
+        while (s4 !== peg$FAILED) {
+          s3.push(s4);
+          if (peg$c6.test(input.charAt(peg$currPos))) {
+            s4 = input.charAt(peg$currPos);
+            peg$currPos++;
           } else {
-            result1 = null;
-          }
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, neg, digits) {return (parseInt(neg+digits.join(""), 10));})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_literalArray() {
-        var cacheKey = "literalArray@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.substr(pos.offset, 2) === "#(") {
-          result0 = "#(";
-          advance(pos, 2);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"#(\"");
+            s4 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c7); }
           }
         }
-        if (result0 !== null) {
-          result1 = parse_literalArrayRest();
-          if (result1 !== null) {
-            result0 = [result0, result1];
+        if (s3 !== peg$FAILED) {
+          if (peg$c4.test(input.charAt(peg$currPos))) {
+            s4 = input.charAt(peg$currPos);
+            peg$currPos++;
           } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, rest) {return rest;})(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_bareLiteralArray() {
-        var cacheKey = "bareLiteralArray@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.charCodeAt(pos.offset) === 40) {
-          result0 = "(";
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"(\"");
+            s4 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c5); }
           }
-        }
-        if (result0 !== null) {
-          result1 = parse_literalArrayRest();
-          if (result1 !== null) {
-            result0 = [result0, result1];
+          if (s4 !== peg$FAILED) {
+            s2 = [s2, s3, s4];
+            s1 = s2;
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s1;
+            s1 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, rest) {return rest;})(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_literalArrayRest() {
-        var cacheKey = "literalArrayRest@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+          peg$currPos = s1;
+          s1 = peg$c1;
         }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1, pos2, pos3;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          result1 = [];
-          pos2 = clone(pos);
-          pos3 = clone(pos);
-          result2 = parse_parseTimeLiteral();
-          if (result2 === null) {
-            result2 = parse_bareLiteralArray();
-            if (result2 === null) {
-              result2 = parse_bareSymbol();
-            }
-          }
-          if (result2 !== null) {
-            result3 = parse_ws();
-            if (result3 !== null) {
-              result2 = [result2, result3];
+      } else {
+        peg$currPos = s1;
+        s1 = peg$c1;
+      }
+      if (s1 !== peg$FAILED) {
+        while (s1 !== peg$FAILED) {
+          s0.push(s1);
+          s1 = peg$currPos;
+          if (peg$c4.test(input.charAt(peg$currPos))) {
+            s2 = input.charAt(peg$currPos);
+            peg$currPos++;
+          } else {
+            s2 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c5); }
+          }
+          if (s2 !== peg$FAILED) {
+            s3 = [];
+            if (peg$c6.test(input.charAt(peg$currPos))) {
+              s4 = input.charAt(peg$currPos);
+              peg$currPos++;
             } else {
-              result2 = null;
-              pos = clone(pos3);
-            }
-          } else {
-            result2 = null;
-            pos = clone(pos3);
-          }
-          if (result2 !== null) {
-            result2 = (function(offset, line, column, lit) {return lit._value();})(pos2.offset, pos2.line, pos2.column, result2[0]);
-          }
-          if (result2 === null) {
-            pos = clone(pos2);
-          }
-          while (result2 !== null) {
-            result1.push(result2);
-            pos2 = clone(pos);
-            pos3 = clone(pos);
-            result2 = parse_parseTimeLiteral();
-            if (result2 === null) {
-              result2 = parse_bareLiteralArray();
-              if (result2 === null) {
-                result2 = parse_bareSymbol();
-              }
-            }
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                result2 = [result2, result3];
+              s4 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c7); }
+            }
+            while (s4 !== peg$FAILED) {
+              s3.push(s4);
+              if (peg$c6.test(input.charAt(peg$currPos))) {
+                s4 = input.charAt(peg$currPos);
+                peg$currPos++;
               } else {
-                result2 = null;
-                pos = clone(pos3);
+                s4 = peg$FAILED;
+                if (peg$silentFails === 0) { peg$fail(peg$c7); }
               }
-            } else {
-              result2 = null;
-              pos = clone(pos3);
-            }
-            if (result2 !== null) {
-              result2 = (function(offset, line, column, lit) {return lit._value();})(pos2.offset, pos2.line, pos2.column, result2[0]);
             }
-            if (result2 === null) {
-              pos = clone(pos2);
-            }
-          }
-          if (result1 !== null) {
-            result2 = parse_ws();
-            if (result2 !== null) {
-              if (input.charCodeAt(pos.offset) === 41) {
-                result3 = ")";
-                advance(pos, 1);
+            if (s3 !== peg$FAILED) {
+              if (peg$c4.test(input.charAt(peg$currPos))) {
+                s4 = input.charAt(peg$currPos);
+                peg$currPos++;
               } else {
-                result3 = null;
-                if (reportFailures === 0) {
-                  matchFailed("\")\"");
-                }
+                s4 = peg$FAILED;
+                if (peg$silentFails === 0) { peg$fail(peg$c5); }
               }
-              if (result3 !== null) {
-                result0 = [result0, result1, result2, result3];
+              if (s4 !== peg$FAILED) {
+                s2 = [s2, s3, s4];
+                s1 = s2;
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                peg$currPos = s1;
+                s1 = peg$c1;
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s1;
+              s1 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s1;
+            s1 = peg$c1;
           }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, lits) {
-                             return smalltalk.ValueNode._new()
-                                    ._position_((line).__at(column))
-                                    ._value_(lits);
-                         })(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_dynamicArray() {
-        var cacheKey = "dynamicArray@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
         }
-        
-        var result0, result1, result2, result3, result4, result5;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.charCodeAt(pos.offset) === 123) {
-          result0 = "{";
-          advance(pos, 1);
+      } else {
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsews() {
+      var s0, s1;
+
+      var key    = peg$currPos * 56 + 3,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = [];
+      s1 = peg$parseseparator();
+      if (s1 === peg$FAILED) {
+        s1 = peg$parsecomments();
+      }
+      while (s1 !== peg$FAILED) {
+        s0.push(s1);
+        s1 = peg$parseseparator();
+        if (s1 === peg$FAILED) {
+          s1 = peg$parsecomments();
+        }
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseidentifier() {
+      var s0, s1, s2, s3;
+
+      var key    = peg$currPos * 56 + 4,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (peg$c8.test(input.charAt(peg$currPos))) {
+        s1 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c9); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        if (peg$c10.test(input.charAt(peg$currPos))) {
+          s3 = input.charAt(peg$currPos);
+          peg$currPos++;
         } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"{\"");
-          }
+          s3 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c11); }
         }
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_expressions();
-            result2 = result2 !== null ? result2 : "";
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                if (input.charCodeAt(pos.offset) === 46) {
-                  result4 = ".";
-                  advance(pos, 1);
-                } else {
-                  result4 = null;
-                  if (reportFailures === 0) {
-                    matchFailed("\".\"");
-                  }
-                }
-                result4 = result4 !== null ? result4 : "";
-                if (result4 !== null) {
-                  if (input.charCodeAt(pos.offset) === 125) {
-                    result5 = "}";
-                    advance(pos, 1);
-                  } else {
-                    result5 = null;
-                    if (reportFailures === 0) {
-                      matchFailed("\"}\"");
-                    }
-                  }
-                  if (result5 !== null) {
-                    result0 = [result0, result1, result2, result3, result4, result5];
-                  } else {
-                    result0 = null;
-                    pos = clone(pos1);
-                  }
-                } else {
-                  result0 = null;
-                  pos = clone(pos1);
-                }
-              } else {
-                result0 = null;
-                pos = clone(pos1);
-              }
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          if (peg$c10.test(input.charAt(peg$currPos))) {
+            s3 = input.charAt(peg$currPos);
+            peg$currPos++;
           } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, expressions) {
-                             return smalltalk.DynamicArrayNode._new()
-                                    ._position_((line).__at(column))
-                                    ._nodes_(expressions);
-                         })(pos0.offset, pos0.line, pos0.column, result0[2]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_dynamicDictionary() {
-        var cacheKey = "dynamicDictionary@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.substr(pos.offset, 2) === "#{") {
-          result0 = "#{";
-          advance(pos, 2);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"#{\"");
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c11); }
           }
         }
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_expressions();
-            result2 = result2 !== null ? result2 : "";
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                if (input.charCodeAt(pos.offset) === 125) {
-                  result4 = "}";
-                  advance(pos, 1);
-                } else {
-                  result4 = null;
-                  if (reportFailures === 0) {
-                    matchFailed("\"}\"");
-                  }
-                }
-                if (result4 !== null) {
-                  result0 = [result0, result1, result2, result3, result4];
-                } else {
-                  result0 = null;
-                  pos = clone(pos1);
-                }
-              } else {
-                result0 = null;
-                pos = clone(pos1);
-              }
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c12(s1, s2);
+          s0 = s1;
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, expressions) {
-                                return smalltalk.DynamicDictionaryNode._new()
-                                       ._position_((line).__at(column))
-                                       ._nodes_(expressions);
-                            })(pos0.offset, pos0.line, pos0.column, result0[2]);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_pseudoVariable() {
-        var cacheKey = "pseudoVariable@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsekeyword() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 5,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseidentifier();
+      if (s1 !== peg$FAILED) {
+        if (peg$c13.test(input.charAt(peg$currPos))) {
+          s2 = input.charAt(peg$currPos);
+          peg$currPos++;
+        } else {
+          s2 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c14); }
+        }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c15(s1, s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        var result0;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.substr(pos.offset, 4) === "true") {
-          result0 = "true";
-          advance(pos, 4);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseselector() {
+      var s0, s1, s2, s3;
+
+      var key    = peg$currPos * 56 + 6,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (peg$c8.test(input.charAt(peg$currPos))) {
+        s1 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c9); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        if (peg$c16.test(input.charAt(peg$currPos))) {
+          s3 = input.charAt(peg$currPos);
+          peg$currPos++;
         } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"true\"");
-          }
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column) {return true;})(pos1.offset, pos1.line, pos1.column);
-        }
-        if (result0 === null) {
-          pos = clone(pos1);
+          s3 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c17); }
         }
-        if (result0 === null) {
-          pos1 = clone(pos);
-          if (input.substr(pos.offset, 5) === "false") {
-            result0 = "false";
-            advance(pos, 5);
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          if (peg$c16.test(input.charAt(peg$currPos))) {
+            s3 = input.charAt(peg$currPos);
+            peg$currPos++;
           } else {
-            result0 = null;
-            if (reportFailures === 0) {
-              matchFailed("\"false\"");
-            }
-          }
-          if (result0 !== null) {
-            result0 = (function(offset, line, column) {return false;})(pos1.offset, pos1.line, pos1.column);
-          }
-          if (result0 === null) {
-            pos = clone(pos1);
-          }
-          if (result0 === null) {
-            pos1 = clone(pos);
-            if (input.substr(pos.offset, 3) === "nil") {
-              result0 = "nil";
-              advance(pos, 3);
-            } else {
-              result0 = null;
-              if (reportFailures === 0) {
-                matchFailed("\"nil\"");
-              }
-            }
-            if (result0 !== null) {
-              result0 = (function(offset, line, column) {return nil;})(pos1.offset, pos1.line, pos1.column);
-            }
-            if (result0 === null) {
-              pos = clone(pos1);
-            }
-          }
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, val) {
-                               return smalltalk.ValueNode._new()
-                                      ._position_((line).__at(column))
-                                      ._value_(val);
-                           })(pos0.offset, pos0.line, pos0.column, result0);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_parseTimeLiteral() {
-        var cacheKey = "parseTimeLiteral@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        
-        result0 = parse_pseudoVariable();
-        if (result0 === null) {
-          result0 = parse_number();
-          if (result0 === null) {
-            result0 = parse_literalArray();
-            if (result0 === null) {
-              result0 = parse_string();
-              if (result0 === null) {
-                result0 = parse_symbol();
-              }
-            }
-          }
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_runtimeLiteral() {
-        var cacheKey = "runtimeLiteral@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        
-        result0 = parse_dynamicDictionary();
-        if (result0 === null) {
-          result0 = parse_dynamicArray();
-          if (result0 === null) {
-            result0 = parse_block();
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c17); }
           }
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_literal() {
-        var cacheKey = "literal@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        
-        result0 = parse_runtimeLiteral();
-        if (result0 === null) {
-          result0 = parse_parseTimeLiteral();
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_variable() {
-        var cacheKey = "variable@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        var pos0;
-        
-        pos0 = clone(pos);
-        result0 = parse_identifier();
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, identifier) {
-                             return smalltalk.VariableNode._new()
-                                    ._position_((line).__at(column))
-                                    ._value_(identifier);
-                         })(pos0.offset, pos0.line, pos0.column, result0);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c12(s1, s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_keywordPair() {
-        var cacheKey = "keywordPair@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseclassName() {
+      var s0, s1, s2, s3;
+
+      var key    = peg$currPos * 56 + 7,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (peg$c18.test(input.charAt(peg$currPos))) {
+        s1 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c19); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        if (peg$c10.test(input.charAt(peg$currPos))) {
+          s3 = input.charAt(peg$currPos);
+          peg$currPos++;
+        } else {
+          s3 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c11); }
         }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_keyword();
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_binarySend();
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                result0 = [result0, result1, result2, result3];
-              } else {
-                result0 = null;
-                pos = clone(pos1);
-              }
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          if (peg$c10.test(input.charAt(peg$currPos))) {
+            s3 = input.charAt(peg$currPos);
+            peg$currPos++;
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c11); }
           }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, key, arg) {return {key:key, arg: arg};})(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_binarySelector() {
-        var cacheKey = "binarySelector@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
         }
-        
-        var result0, result1;
-        var pos0;
-        
-        pos0 = clone(pos);
-        if (/^[\\+*\/=><,@%~|&\-]/.test(input.charAt(pos.offset))) {
-          result1 = input.charAt(pos.offset);
-          advance(pos, 1);
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c12(s1, s2);
+          s0 = s1;
         } else {
-          result1 = null;
-          if (reportFailures === 0) {
-            matchFailed("[\\\\+*\\/=><,@%~|&\\-]");
-          }
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result1 !== null) {
-          result0 = [];
-          while (result1 !== null) {
-            result0.push(result1);
-            if (/^[\\+*\/=><,@%~|&\-]/.test(input.charAt(pos.offset))) {
-              result1 = input.charAt(pos.offset);
-              advance(pos, 1);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsestring() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 8,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (peg$c20.test(input.charAt(peg$currPos))) {
+        s1 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c21); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        s3 = peg$currPos;
+        if (input.substr(peg$currPos, 2) === peg$c22) {
+          s4 = peg$c22;
+          peg$currPos += 2;
+        } else {
+          s4 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c23); }
+        }
+        if (s4 !== peg$FAILED) {
+          peg$reportedPos = s3;
+          s4 = peg$c24();
+        }
+        s3 = s4;
+        if (s3 === peg$FAILED) {
+          if (peg$c25.test(input.charAt(peg$currPos))) {
+            s3 = input.charAt(peg$currPos);
+            peg$currPos++;
+          } else {
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c26); }
+          }
+        }
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          s3 = peg$currPos;
+          if (input.substr(peg$currPos, 2) === peg$c22) {
+            s4 = peg$c22;
+            peg$currPos += 2;
+          } else {
+            s4 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c23); }
+          }
+          if (s4 !== peg$FAILED) {
+            peg$reportedPos = s3;
+            s4 = peg$c24();
+          }
+          s3 = s4;
+          if (s3 === peg$FAILED) {
+            if (peg$c25.test(input.charAt(peg$currPos))) {
+              s3 = input.charAt(peg$currPos);
+              peg$currPos++;
             } else {
-              result1 = null;
-              if (reportFailures === 0) {
-                matchFailed("[\\\\+*\\/=><,@%~|&\\-]");
-              }
+              s3 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c26); }
             }
           }
-        } else {
-          result0 = null;
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, bin) {return bin.join("");})(pos0.offset, pos0.line, pos0.column, result0);
         }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_keywordPattern() {
-        var cacheKey = "keywordPattern@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1, pos2;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        pos2 = clone(pos);
-        result1 = parse_ws();
-        if (result1 !== null) {
-          result2 = parse_keyword();
-          if (result2 !== null) {
-            result3 = parse_ws();
-            if (result3 !== null) {
-              result4 = parse_identifier();
-              if (result4 !== null) {
-                result1 = [result1, result2, result3, result4];
-              } else {
-                result1 = null;
-                pos = clone(pos2);
-              }
-            } else {
-              result1 = null;
-              pos = clone(pos2);
-            }
+        if (s2 !== peg$FAILED) {
+          if (peg$c20.test(input.charAt(peg$currPos))) {
+            s3 = input.charAt(peg$currPos);
+            peg$currPos++;
           } else {
-            result1 = null;
-            pos = clone(pos2);
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c21); }
           }
-        } else {
-          result1 = null;
-          pos = clone(pos2);
-        }
-        if (result1 !== null) {
-          result1 = (function(offset, line, column, key, arg) {return {key:key, arg: arg};})(pos1.offset, pos1.line, pos1.column, result1[1], result1[3]);
-        }
-        if (result1 === null) {
-          pos = clone(pos1);
-        }
-        if (result1 !== null) {
-          result0 = [];
-          while (result1 !== null) {
-            result0.push(result1);
-            pos1 = clone(pos);
-            pos2 = clone(pos);
-            result1 = parse_ws();
-            if (result1 !== null) {
-              result2 = parse_keyword();
-              if (result2 !== null) {
-                result3 = parse_ws();
-                if (result3 !== null) {
-                  result4 = parse_identifier();
-                  if (result4 !== null) {
-                    result1 = [result1, result2, result3, result4];
-                  } else {
-                    result1 = null;
-                    pos = clone(pos2);
-                  }
-                } else {
-                  result1 = null;
-                  pos = clone(pos2);
-                }
-              } else {
-                result1 = null;
-                pos = clone(pos2);
-              }
-            } else {
-              result1 = null;
-              pos = clone(pos2);
-            }
-            if (result1 !== null) {
-              result1 = (function(offset, line, column, key, arg) {return {key:key, arg: arg};})(pos1.offset, pos1.line, pos1.column, result1[1], result1[3]);
-            }
-            if (result1 === null) {
-              pos = clone(pos1);
-            }
+          if (s3 !== peg$FAILED) {
+            peg$reportedPos = s0;
+            s1 = peg$c27(s2);
+            s0 = s1;
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, pairs) {
-                             var keywords = [];
-                             var params = [];
-                             var i = 0;
-                             for(i = 0; i < pairs.length; i++){
-                                 keywords.push(pairs[i].key);
-                             }
-                             for(i = 0; i < pairs.length; i++){
-                                 params.push(pairs[i].arg);
-                             }
-                             return [keywords.join(""), params];
-                         })(pos0.offset, pos0.line, pos0.column, result0);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 === null) {
-          pos = clone(pos0);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsesymbol() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 9,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.charCodeAt(peg$currPos) === 35) {
+        s1 = peg$c28;
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c29); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsebareSymbol();
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c30(s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_binaryPattern() {
-        var cacheKey = "binaryPattern@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsebareSymbol() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 10,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseselector();
+      if (s1 === peg$FAILED) {
+        s1 = peg$parsebinarySelector();
+        if (s1 === peg$FAILED) {
+          s1 = peg$currPos;
+          s2 = peg$parsestring();
+          if (s2 !== peg$FAILED) {
+            peg$reportedPos = s1;
+            s2 = peg$c31(s2);
+          }
+          s1 = s2;
+        }
+      }
+      if (s1 !== peg$FAILED) {
+        peg$reportedPos = s0;
+        s1 = peg$c32(s1);
+      }
+      s0 = s1;
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsenumber() {
+      var s0, s1;
+
+      var key    = peg$currPos * 56 + 11,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsenumberExp();
+      if (s1 === peg$FAILED) {
+        s1 = peg$parsehex();
+        if (s1 === peg$FAILED) {
+          s1 = peg$parsefloat();
+          if (s1 === peg$FAILED) {
+            s1 = peg$parseinteger();
+          }
+        }
+      }
+      if (s1 !== peg$FAILED) {
+        peg$reportedPos = s0;
+        s1 = peg$c33(s1);
+      }
+      s0 = s1;
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsenumberExp() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 12,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$currPos;
+      s2 = peg$parsefloat();
+      if (s2 === peg$FAILED) {
+        s2 = peg$parseinteger();
+      }
+      if (s2 !== peg$FAILED) {
+        if (input.charCodeAt(peg$currPos) === 101) {
+          s3 = peg$c34;
+          peg$currPos++;
+        } else {
+          s3 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c35); }
+        }
+        if (s3 !== peg$FAILED) {
+          s4 = peg$parseinteger();
+          if (s4 !== peg$FAILED) {
+            s2 = [s2, s3, s4];
+            s1 = s2;
+          } else {
+            peg$currPos = s1;
+            s1 = peg$c1;
+          }
+        } else {
+          peg$currPos = s1;
+          s1 = peg$c1;
         }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          result1 = parse_binarySelector();
-          if (result1 !== null) {
-            result2 = parse_ws();
-            if (result2 !== null) {
-              result3 = parse_identifier();
-              if (result3 !== null) {
-                result0 = [result0, result1, result2, result3];
+      } else {
+        peg$currPos = s1;
+        s1 = peg$c1;
+      }
+      if (s1 !== peg$FAILED) {
+        peg$reportedPos = s0;
+        s1 = peg$c36(s1);
+      }
+      s0 = s1;
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsehex() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 13,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (peg$c38.test(input.charAt(peg$currPos))) {
+        s1 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c39); }
+      }
+      if (s1 === peg$FAILED) {
+        s1 = peg$c37;
+      }
+      if (s1 !== peg$FAILED) {
+        if (input.substr(peg$currPos, 3) === peg$c40) {
+          s2 = peg$c40;
+          peg$currPos += 3;
+        } else {
+          s2 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c41); }
+        }
+        if (s2 !== peg$FAILED) {
+          s3 = [];
+          if (peg$c42.test(input.charAt(peg$currPos))) {
+            s4 = input.charAt(peg$currPos);
+            peg$currPos++;
+          } else {
+            s4 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c43); }
+          }
+          if (s4 !== peg$FAILED) {
+            while (s4 !== peg$FAILED) {
+              s3.push(s4);
+              if (peg$c42.test(input.charAt(peg$currPos))) {
+                s4 = input.charAt(peg$currPos);
+                peg$currPos++;
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                s4 = peg$FAILED;
+                if (peg$silentFails === 0) { peg$fail(peg$c43); }
               }
-            } else {
-              result0 = null;
-              pos = clone(pos1);
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            s3 = peg$c1;
           }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, selector, arg) {return [selector, [arg]];})(pos0.offset, pos0.line, pos0.column, result0[1], result0[3]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_unaryPattern() {
-        var cacheKey = "unaryPattern@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          result1 = parse_identifier();
-          if (result1 !== null) {
-            result0 = [result0, result1];
+          if (s3 !== peg$FAILED) {
+            peg$reportedPos = s0;
+            s1 = peg$c44(s1, s3);
+            s0 = s1;
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, selector) {return [selector, []];})(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_expression() {
-        var cacheKey = "expression@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        
-        result0 = parse_assignment();
-        if (result0 === null) {
-          result0 = parse_cascade();
-          if (result0 === null) {
-            result0 = parse_keywordSend();
-            if (result0 === null) {
-              result0 = parse_binarySend();
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsefloat() {
+      var s0, s1, s2, s3, s4, s5;
+
+      var key    = peg$currPos * 56 + 14,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (peg$c38.test(input.charAt(peg$currPos))) {
+        s1 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c39); }
+      }
+      if (s1 === peg$FAILED) {
+        s1 = peg$c37;
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        if (peg$c45.test(input.charAt(peg$currPos))) {
+          s3 = input.charAt(peg$currPos);
+          peg$currPos++;
+        } else {
+          s3 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c46); }
+        }
+        if (s3 !== peg$FAILED) {
+          while (s3 !== peg$FAILED) {
+            s2.push(s3);
+            if (peg$c45.test(input.charAt(peg$currPos))) {
+              s3 = input.charAt(peg$currPos);
+              peg$currPos++;
+            } else {
+              s3 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c46); }
             }
           }
+        } else {
+          s2 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_expressionList() {
-        var cacheKey = "expressionList@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          if (input.charCodeAt(pos.offset) === 46) {
-            result1 = ".";
-            advance(pos, 1);
+        if (s2 !== peg$FAILED) {
+          if (input.charCodeAt(peg$currPos) === 46) {
+            s3 = peg$c47;
+            peg$currPos++;
           } else {
-            result1 = null;
-            if (reportFailures === 0) {
-              matchFailed("\".\"");
-            }
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c48); }
           }
-          if (result1 !== null) {
-            result2 = parse_ws();
-            if (result2 !== null) {
-              result3 = parse_expression();
-              if (result3 !== null) {
-                result0 = [result0, result1, result2, result3];
-              } else {
-                result0 = null;
-                pos = clone(pos1);
+          if (s3 !== peg$FAILED) {
+            s4 = [];
+            if (peg$c45.test(input.charAt(peg$currPos))) {
+              s5 = input.charAt(peg$currPos);
+              peg$currPos++;
+            } else {
+              s5 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c46); }
+            }
+            if (s5 !== peg$FAILED) {
+              while (s5 !== peg$FAILED) {
+                s4.push(s5);
+                if (peg$c45.test(input.charAt(peg$currPos))) {
+                  s5 = input.charAt(peg$currPos);
+                  peg$currPos++;
+                } else {
+                  s5 = peg$FAILED;
+                  if (peg$silentFails === 0) { peg$fail(peg$c46); }
+                }
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              s4 = peg$c1;
+            }
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c49(s1, s2, s4);
+              s0 = s1;
+            } else {
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, expression) {return expression;})(pos0.offset, pos0.line, pos0.column, result0[3]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_expressions() {
-        var cacheKey = "expressions@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        var result0, result1, result2;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_expression();
-        if (result0 !== null) {
-          result1 = [];
-          result2 = parse_expressionList();
-          while (result2 !== null) {
-            result1.push(result2);
-            result2 = parse_expressionList();
-          }
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseinteger() {
+      var s0, s1, s2, s3;
+
+      var key    = peg$currPos * 56 + 15,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (peg$c38.test(input.charAt(peg$currPos))) {
+        s1 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c39); }
+      }
+      if (s1 === peg$FAILED) {
+        s1 = peg$c37;
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        if (peg$c45.test(input.charAt(peg$currPos))) {
+          s3 = input.charAt(peg$currPos);
+          peg$currPos++;
+        } else {
+          s3 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c46); }
+        }
+        if (s3 !== peg$FAILED) {
+          while (s3 !== peg$FAILED) {
+            s2.push(s3);
+            if (peg$c45.test(input.charAt(peg$currPos))) {
+              s3 = input.charAt(peg$currPos);
+              peg$currPos++;
+            } else {
+              s3 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c46); }
+            }
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
+          s2 = peg$c1;
         }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, first, others) {
-                             var result = [first];
-                             for(var i = 0; i < others.length; i++) {
-                                 result.push(others[i]);
-                             }
-                             return result;
-                         })(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c50(s1, s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 === null) {
-          pos = clone(pos0);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseliteralArray() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 16,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.substr(peg$currPos, 2) === peg$c51) {
+        s1 = peg$c51;
+        peg$currPos += 2;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c52); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parseliteralArrayRest();
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c30(s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_assignment() {
-        var cacheKey = "assignment@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsebareLiteralArray() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 17,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.charCodeAt(peg$currPos) === 40) {
+        s1 = peg$c53;
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c54); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parseliteralArrayRest();
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c30(s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_variable();
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            if (input.substr(pos.offset, 2) === ":=") {
-              result2 = ":=";
-              advance(pos, 2);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseliteralArrayRest() {
+      var s0, s1, s2, s3, s4, s5;
+
+      var key    = peg$currPos * 56 + 18,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        s3 = peg$currPos;
+        s4 = peg$parseparseTimeLiteral();
+        if (s4 === peg$FAILED) {
+          s4 = peg$parsebareLiteralArray();
+          if (s4 === peg$FAILED) {
+            s4 = peg$parsebareSymbol();
+          }
+        }
+        if (s4 !== peg$FAILED) {
+          s5 = peg$parsews();
+          if (s5 !== peg$FAILED) {
+            peg$reportedPos = s3;
+            s4 = peg$c55(s4);
+            s3 = s4;
+          } else {
+            peg$currPos = s3;
+            s3 = peg$c1;
+          }
+        } else {
+          peg$currPos = s3;
+          s3 = peg$c1;
+        }
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          s3 = peg$currPos;
+          s4 = peg$parseparseTimeLiteral();
+          if (s4 === peg$FAILED) {
+            s4 = peg$parsebareLiteralArray();
+            if (s4 === peg$FAILED) {
+              s4 = peg$parsebareSymbol();
+            }
+          }
+          if (s4 !== peg$FAILED) {
+            s5 = peg$parsews();
+            if (s5 !== peg$FAILED) {
+              peg$reportedPos = s3;
+              s4 = peg$c55(s4);
+              s3 = s4;
             } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("\":=\"");
-              }
+              peg$currPos = s3;
+              s3 = peg$c1;
             }
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                result4 = parse_expression();
-                if (result4 !== null) {
-                  result0 = [result0, result1, result2, result3, result4];
-                } else {
-                  result0 = null;
-                  pos = clone(pos1);
-                }
-              } else {
-                result0 = null;
-                pos = clone(pos1);
-              }
+          } else {
+            peg$currPos = s3;
+            s3 = peg$c1;
+          }
+        }
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parsews();
+          if (s3 !== peg$FAILED) {
+            if (input.charCodeAt(peg$currPos) === 41) {
+              s4 = peg$c56;
+              peg$currPos++;
+            } else {
+              s4 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c57); }
+            }
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c58(s2);
+              s0 = s1;
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, variable, expression) {
-                             return smalltalk.AssignmentNode._new()
-                                    ._position_((line).__at(column))
-                                    ._left_(variable)
-                                    ._right_(expression);
-                         })(pos0.offset, pos0.line, pos0.column, result0[0], result0[4]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_ret() {
-        var cacheKey = "ret@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.charCodeAt(pos.offset) === 94) {
-          result0 = "^";
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"^\"");
-          }
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_expression();
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                if (input.charCodeAt(pos.offset) === 46) {
-                  result4 = ".";
-                  advance(pos, 1);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsedynamicArray() {
+      var s0, s1, s2, s3, s4, s5, s6;
+
+      var key    = peg$currPos * 56 + 19,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.charCodeAt(peg$currPos) === 123) {
+        s1 = peg$c59;
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c60); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parseexpressions();
+          if (s3 === peg$FAILED) {
+            s3 = peg$c37;
+          }
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              if (input.charCodeAt(peg$currPos) === 46) {
+                s5 = peg$c47;
+                peg$currPos++;
+              } else {
+                s5 = peg$FAILED;
+                if (peg$silentFails === 0) { peg$fail(peg$c48); }
+              }
+              if (s5 === peg$FAILED) {
+                s5 = peg$c37;
+              }
+              if (s5 !== peg$FAILED) {
+                if (input.charCodeAt(peg$currPos) === 125) {
+                  s6 = peg$c61;
+                  peg$currPos++;
                 } else {
-                  result4 = null;
-                  if (reportFailures === 0) {
-                    matchFailed("\".\"");
-                  }
+                  s6 = peg$FAILED;
+                  if (peg$silentFails === 0) { peg$fail(peg$c62); }
                 }
-                result4 = result4 !== null ? result4 : "";
-                if (result4 !== null) {
-                  result0 = [result0, result1, result2, result3, result4];
+                if (s6 !== peg$FAILED) {
+                  peg$reportedPos = s0;
+                  s1 = peg$c63(s3);
+                  s0 = s1;
                 } else {
-                  result0 = null;
-                  pos = clone(pos1);
+                  peg$currPos = s0;
+                  s0 = peg$c1;
                 }
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                peg$currPos = s0;
+                s0 = peg$c1;
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, expression) {
-                             return smalltalk.ReturnNode._new()
-                                    ._position_((line).__at(column))
-                                    ._nodes_([expression]);
-                         })(pos0.offset, pos0.line, pos0.column, result0[2]);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsedynamicDictionary() {
+      var s0, s1, s2, s3, s4, s5;
+
+      var key    = peg$currPos * 56 + 20,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.substr(peg$currPos, 2) === peg$c64) {
+        s1 = peg$c64;
+        peg$currPos += 2;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c65); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parseexpressions();
+          if (s3 === peg$FAILED) {
+            s3 = peg$c37;
+          }
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              if (input.charCodeAt(peg$currPos) === 125) {
+                s5 = peg$c61;
+                peg$currPos++;
+              } else {
+                s5 = peg$FAILED;
+                if (peg$silentFails === 0) { peg$fail(peg$c62); }
+              }
+              if (s5 !== peg$FAILED) {
+                peg$reportedPos = s0;
+                s1 = peg$c66(s3);
+                s0 = s1;
+              } else {
+                peg$currPos = s0;
+                s0 = peg$c1;
+              }
+            } else {
+              peg$currPos = s0;
+              s0 = peg$c1;
+            }
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
+          }
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 === null) {
-          pos = clone(pos0);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsepseudoVariable() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 21,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$currPos;
+      if (input.substr(peg$currPos, 4) === peg$c67) {
+        s2 = peg$c67;
+        peg$currPos += 4;
+      } else {
+        s2 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c68); }
+      }
+      if (s2 !== peg$FAILED) {
+        peg$reportedPos = s1;
+        s2 = peg$c69();
+      }
+      s1 = s2;
+      if (s1 === peg$FAILED) {
+        s1 = peg$currPos;
+        if (input.substr(peg$currPos, 5) === peg$c70) {
+          s2 = peg$c70;
+          peg$currPos += 5;
+        } else {
+          s2 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c71); }
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_temps() {
-        var cacheKey = "temps@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s1;
+          s2 = peg$c72();
         }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1, pos2, pos3;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.charCodeAt(pos.offset) === 124) {
-          result0 = "|";
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"|\"");
+        s1 = s2;
+        if (s1 === peg$FAILED) {
+          s1 = peg$currPos;
+          if (input.substr(peg$currPos, 3) === peg$c73) {
+            s2 = peg$c73;
+            peg$currPos += 3;
+          } else {
+            s2 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c74); }
           }
+          if (s2 !== peg$FAILED) {
+            peg$reportedPos = s1;
+            s2 = peg$c75();
+          }
+          s1 = s2;
         }
-        if (result0 !== null) {
-          result1 = [];
-          pos2 = clone(pos);
-          pos3 = clone(pos);
-          result2 = parse_ws();
-          if (result2 !== null) {
-            result3 = parse_identifier();
-            if (result3 !== null) {
-              result4 = parse_ws();
-              if (result4 !== null) {
-                result2 = [result2, result3, result4];
-              } else {
-                result2 = null;
-                pos = clone(pos3);
-              }
+      }
+      if (s1 !== peg$FAILED) {
+        peg$reportedPos = s0;
+        s1 = peg$c76(s1);
+      }
+      s0 = s1;
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseparseTimeLiteral() {
+      var s0;
+
+      var key    = peg$currPos * 56 + 22,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$parsepseudoVariable();
+      if (s0 === peg$FAILED) {
+        s0 = peg$parsenumber();
+        if (s0 === peg$FAILED) {
+          s0 = peg$parseliteralArray();
+          if (s0 === peg$FAILED) {
+            s0 = peg$parsestring();
+            if (s0 === peg$FAILED) {
+              s0 = peg$parsesymbol();
+            }
+          }
+        }
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseruntimeLiteral() {
+      var s0;
+
+      var key    = peg$currPos * 56 + 23,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$parsedynamicDictionary();
+      if (s0 === peg$FAILED) {
+        s0 = peg$parsedynamicArray();
+        if (s0 === peg$FAILED) {
+          s0 = peg$parseblock();
+        }
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseliteral() {
+      var s0;
+
+      var key    = peg$currPos * 56 + 24,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$parseruntimeLiteral();
+      if (s0 === peg$FAILED) {
+        s0 = peg$parseparseTimeLiteral();
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsevariable() {
+      var s0, s1;
+
+      var key    = peg$currPos * 56 + 25,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseidentifier();
+      if (s1 !== peg$FAILED) {
+        peg$reportedPos = s0;
+        s1 = peg$c77(s1);
+      }
+      s0 = s1;
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsekeywordPair() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 26,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsekeyword();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parsebinarySend();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c78(s1, s3);
+              s0 = s1;
             } else {
-              result2 = null;
-              pos = clone(pos3);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result2 = null;
-            pos = clone(pos3);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
-          if (result2 !== null) {
-            result2 = (function(offset, line, column, variable) {return variable;})(pos2.offset, pos2.line, pos2.column, result2[1]);
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
+        }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsebinarySelector() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 27,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = [];
+      if (peg$c79.test(input.charAt(peg$currPos))) {
+        s2 = input.charAt(peg$currPos);
+        peg$currPos++;
+      } else {
+        s2 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c80); }
+      }
+      if (s2 !== peg$FAILED) {
+        while (s2 !== peg$FAILED) {
+          s1.push(s2);
+          if (peg$c79.test(input.charAt(peg$currPos))) {
+            s2 = input.charAt(peg$currPos);
+            peg$currPos++;
+          } else {
+            s2 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c80); }
           }
-          if (result2 === null) {
-            pos = clone(pos2);
+        }
+      } else {
+        s1 = peg$c1;
+      }
+      if (s1 !== peg$FAILED) {
+        peg$reportedPos = s0;
+        s1 = peg$c81(s1);
+      }
+      s0 = s1;
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsekeywordPattern() {
+      var s0, s1, s2, s3, s4, s5, s6;
+
+      var key    = peg$currPos * 56 + 28,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = [];
+      s2 = peg$currPos;
+      s3 = peg$parsews();
+      if (s3 !== peg$FAILED) {
+        s4 = peg$parsekeyword();
+        if (s4 !== peg$FAILED) {
+          s5 = peg$parsews();
+          if (s5 !== peg$FAILED) {
+            s6 = peg$parseidentifier();
+            if (s6 !== peg$FAILED) {
+              peg$reportedPos = s2;
+              s3 = peg$c78(s4, s6);
+              s2 = s3;
+            } else {
+              peg$currPos = s2;
+              s2 = peg$c1;
+            }
+          } else {
+            peg$currPos = s2;
+            s2 = peg$c1;
           }
-          while (result2 !== null) {
-            result1.push(result2);
-            pos2 = clone(pos);
-            pos3 = clone(pos);
-            result2 = parse_ws();
-            if (result2 !== null) {
-              result3 = parse_identifier();
-              if (result3 !== null) {
-                result4 = parse_ws();
-                if (result4 !== null) {
-                  result2 = [result2, result3, result4];
+        } else {
+          peg$currPos = s2;
+          s2 = peg$c1;
+        }
+      } else {
+        peg$currPos = s2;
+        s2 = peg$c1;
+      }
+      if (s2 !== peg$FAILED) {
+        while (s2 !== peg$FAILED) {
+          s1.push(s2);
+          s2 = peg$currPos;
+          s3 = peg$parsews();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsekeyword();
+            if (s4 !== peg$FAILED) {
+              s5 = peg$parsews();
+              if (s5 !== peg$FAILED) {
+                s6 = peg$parseidentifier();
+                if (s6 !== peg$FAILED) {
+                  peg$reportedPos = s2;
+                  s3 = peg$c78(s4, s6);
+                  s2 = s3;
                 } else {
-                  result2 = null;
-                  pos = clone(pos3);
+                  peg$currPos = s2;
+                  s2 = peg$c1;
                 }
               } else {
-                result2 = null;
-                pos = clone(pos3);
+                peg$currPos = s2;
+                s2 = peg$c1;
               }
             } else {
-              result2 = null;
-              pos = clone(pos3);
-            }
-            if (result2 !== null) {
-              result2 = (function(offset, line, column, variable) {return variable;})(pos2.offset, pos2.line, pos2.column, result2[1]);
-            }
-            if (result2 === null) {
-              pos = clone(pos2);
+              peg$currPos = s2;
+              s2 = peg$c1;
             }
+          } else {
+            peg$currPos = s2;
+            s2 = peg$c1;
           }
-          if (result1 !== null) {
-            if (input.charCodeAt(pos.offset) === 124) {
-              result2 = "|";
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("\"|\"");
-              }
-            }
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
+        }
+      } else {
+        s1 = peg$c1;
+      }
+      if (s1 !== peg$FAILED) {
+        peg$reportedPos = s0;
+        s1 = peg$c82(s1);
+      }
+      s0 = s1;
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsebinaryPattern() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 29,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsebinarySelector();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parsews();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parseidentifier();
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c83(s2, s4);
+              s0 = s1;
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, vars) {return vars;})(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_blockParamList() {
-        var cacheKey = "blockParamList@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseunaryPattern() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 30,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parseidentifier();
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c84(s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1, pos2, pos3;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        pos2 = clone(pos);
-        pos3 = clone(pos);
-        result1 = parse_ws();
-        if (result1 !== null) {
-          if (input.charCodeAt(pos.offset) === 58) {
-            result2 = ":";
-            advance(pos, 1);
-          } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("\":\"");
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseexpression() {
+      var s0;
+
+      var key    = peg$currPos * 56 + 31,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$parseassignment();
+      if (s0 === peg$FAILED) {
+        s0 = peg$parsecascade();
+        if (s0 === peg$FAILED) {
+          s0 = peg$parsekeywordSend();
+          if (s0 === peg$FAILED) {
+            s0 = peg$parsebinarySend();
+          }
+        }
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseexpressionList() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 32,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        if (input.charCodeAt(peg$currPos) === 46) {
+          s2 = peg$c47;
+          peg$currPos++;
+        } else {
+          s2 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c48); }
+        }
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parsews();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parseexpression();
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c85(s4);
+              s0 = s1;
+            } else {
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
-          if (result2 !== null) {
-            result3 = parse_ws();
-            if (result3 !== null) {
-              result4 = parse_identifier();
-              if (result4 !== null) {
-                result1 = [result1, result2, result3, result4];
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
+        }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseexpressions() {
+      var s0, s1, s2, s3;
+
+      var key    = peg$currPos * 56 + 33,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseexpression();
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        s3 = peg$parseexpressionList();
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          s3 = peg$parseexpressionList();
+        }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c86(s1, s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
+        }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseassignment() {
+      var s0, s1, s2, s3, s4, s5;
+
+      var key    = peg$currPos * 56 + 34,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsevariable();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          if (input.substr(peg$currPos, 2) === peg$c87) {
+            s3 = peg$c87;
+            peg$currPos += 2;
+          } else {
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c88); }
+          }
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              s5 = peg$parseexpression();
+              if (s5 !== peg$FAILED) {
+                peg$reportedPos = s0;
+                s1 = peg$c89(s1, s5);
+                s0 = s1;
               } else {
-                result1 = null;
-                pos = clone(pos3);
+                peg$currPos = s0;
+                s0 = peg$c1;
               }
             } else {
-              result1 = null;
-              pos = clone(pos3);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result1 = null;
-            pos = clone(pos3);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result1 = null;
-          pos = clone(pos3);
-        }
-        if (result1 !== null) {
-          result1 = (function(offset, line, column, param) {return param;})(pos2.offset, pos2.line, pos2.column, result1[3]);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result1 === null) {
-          pos = clone(pos2);
-        }
-        if (result1 !== null) {
-          result0 = [];
-          while (result1 !== null) {
-            result0.push(result1);
-            pos2 = clone(pos);
-            pos3 = clone(pos);
-            result1 = parse_ws();
-            if (result1 !== null) {
-              if (input.charCodeAt(pos.offset) === 58) {
-                result2 = ":";
-                advance(pos, 1);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseret() {
+      var s0, s1, s2, s3, s4, s5;
+
+      var key    = peg$currPos * 56 + 35,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.charCodeAt(peg$currPos) === 94) {
+        s1 = peg$c90;
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c91); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parseexpression();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              if (input.charCodeAt(peg$currPos) === 46) {
+                s5 = peg$c47;
+                peg$currPos++;
               } else {
-                result2 = null;
-                if (reportFailures === 0) {
-                  matchFailed("\":\"");
-                }
+                s5 = peg$FAILED;
+                if (peg$silentFails === 0) { peg$fail(peg$c48); }
               }
-              if (result2 !== null) {
-                result3 = parse_ws();
-                if (result3 !== null) {
-                  result4 = parse_identifier();
-                  if (result4 !== null) {
-                    result1 = [result1, result2, result3, result4];
-                  } else {
-                    result1 = null;
-                    pos = clone(pos3);
-                  }
-                } else {
-                  result1 = null;
-                  pos = clone(pos3);
-                }
+              if (s5 === peg$FAILED) {
+                s5 = peg$c37;
+              }
+              if (s5 !== peg$FAILED) {
+                peg$reportedPos = s0;
+                s1 = peg$c92(s3);
+                s0 = s1;
               } else {
-                result1 = null;
-                pos = clone(pos3);
+                peg$currPos = s0;
+                s0 = peg$c1;
               }
             } else {
-              result1 = null;
-              pos = clone(pos3);
-            }
-            if (result1 !== null) {
-              result1 = (function(offset, line, column, param) {return param;})(pos2.offset, pos2.line, pos2.column, result1[3]);
-            }
-            if (result1 === null) {
-              pos = clone(pos2);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            if (input.charCodeAt(pos.offset) === 124) {
-              result2 = "|";
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("\"|\"");
-              }
-            }
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsetemps() {
+      var s0, s1, s2, s3, s4, s5, s6;
+
+      var key    = peg$currPos * 56 + 36,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.charCodeAt(peg$currPos) === 124) {
+        s1 = peg$c93;
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c94); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        s3 = peg$currPos;
+        s4 = peg$parsews();
+        if (s4 !== peg$FAILED) {
+          s5 = peg$parseidentifier();
+          if (s5 !== peg$FAILED) {
+            s6 = peg$parsews();
+            if (s6 !== peg$FAILED) {
+              peg$reportedPos = s3;
+              s4 = peg$c95(s5);
+              s3 = s4;
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s3;
+              s3 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s3;
+            s3 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, params) {return params;})(pos0.offset, pos0.line, pos0.column, result0[0]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_subexpression() {
-        var cacheKey = "subexpression@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.charCodeAt(pos.offset) === 40) {
-          result0 = "(";
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"(\"");
-          }
+          peg$currPos = s3;
+          s3 = peg$c1;
         }
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_expression();
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                if (input.charCodeAt(pos.offset) === 41) {
-                  result4 = ")";
-                  advance(pos, 1);
-                } else {
-                  result4 = null;
-                  if (reportFailures === 0) {
-                    matchFailed("\")\"");
-                  }
-                }
-                if (result4 !== null) {
-                  result0 = [result0, result1, result2, result3, result4];
-                } else {
-                  result0 = null;
-                  pos = clone(pos1);
-                }
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          s3 = peg$currPos;
+          s4 = peg$parsews();
+          if (s4 !== peg$FAILED) {
+            s5 = peg$parseidentifier();
+            if (s5 !== peg$FAILED) {
+              s6 = peg$parsews();
+              if (s6 !== peg$FAILED) {
+                peg$reportedPos = s3;
+                s4 = peg$c95(s5);
+                s3 = s4;
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                peg$currPos = s3;
+                s3 = peg$c1;
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s3;
+              s3 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s3;
+            s3 = peg$c1;
           }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, expression) {return expression;})(pos0.offset, pos0.line, pos0.column, result0[2]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_statements() {
-        var cacheKey = "statements@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
         }
-        
-        var result0, result1, result2, result3, result4, result5, result6;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ret();
-        if (result0 !== null) {
-          result1 = [];
-          if (/^[.]/.test(input.charAt(pos.offset))) {
-            result2 = input.charAt(pos.offset);
-            advance(pos, 1);
+        if (s2 !== peg$FAILED) {
+          if (input.charCodeAt(peg$currPos) === 124) {
+            s3 = peg$c93;
+            peg$currPos++;
           } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("[.]");
-            }
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c94); }
+          }
+          if (s3 !== peg$FAILED) {
+            peg$reportedPos = s0;
+            s1 = peg$c96(s2);
+            s0 = s1;
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
-          while (result2 !== null) {
-            result1.push(result2);
-            if (/^[.]/.test(input.charAt(pos.offset))) {
-              result2 = input.charAt(pos.offset);
-              advance(pos, 1);
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
+        }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseblockParamList() {
+      var s0, s1, s2, s3, s4, s5, s6;
+
+      var key    = peg$currPos * 56 + 37,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = [];
+      s2 = peg$currPos;
+      s3 = peg$parsews();
+      if (s3 !== peg$FAILED) {
+        if (input.charCodeAt(peg$currPos) === 58) {
+          s4 = peg$c97;
+          peg$currPos++;
+        } else {
+          s4 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c98); }
+        }
+        if (s4 !== peg$FAILED) {
+          s5 = peg$parsews();
+          if (s5 !== peg$FAILED) {
+            s6 = peg$parseidentifier();
+            if (s6 !== peg$FAILED) {
+              peg$reportedPos = s2;
+              s3 = peg$c99(s6);
+              s2 = s3;
             } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("[.]");
-              }
+              peg$currPos = s2;
+              s2 = peg$c1;
             }
-          }
-          if (result1 !== null) {
-            result0 = [result0, result1];
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s2;
+            s2 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, ret) {return [ret];})(pos0.offset, pos0.line, pos0.column, result0[0]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
+          peg$currPos = s2;
+          s2 = peg$c1;
         }
-        if (result0 === null) {
-          pos0 = clone(pos);
-          pos1 = clone(pos);
-          result0 = parse_expressions();
-          if (result0 !== null) {
-            result1 = parse_ws();
-            if (result1 !== null) {
-              if (/^[.]/.test(input.charAt(pos.offset))) {
-                result3 = input.charAt(pos.offset);
-                advance(pos, 1);
-              } else {
-                result3 = null;
-                if (reportFailures === 0) {
-                  matchFailed("[.]");
-                }
-              }
-              if (result3 !== null) {
-                result2 = [];
-                while (result3 !== null) {
-                  result2.push(result3);
-                  if (/^[.]/.test(input.charAt(pos.offset))) {
-                    result3 = input.charAt(pos.offset);
-                    advance(pos, 1);
-                  } else {
-                    result3 = null;
-                    if (reportFailures === 0) {
-                      matchFailed("[.]");
-                    }
-                  }
-                }
-              } else {
-                result2 = null;
-              }
-              if (result2 !== null) {
-                result3 = parse_ws();
-                if (result3 !== null) {
-                  result4 = parse_ret();
-                  if (result4 !== null) {
-                    result5 = [];
-                    if (/^[.]/.test(input.charAt(pos.offset))) {
-                      result6 = input.charAt(pos.offset);
-                      advance(pos, 1);
-                    } else {
-                      result6 = null;
-                      if (reportFailures === 0) {
-                        matchFailed("[.]");
-                      }
-                    }
-                    while (result6 !== null) {
-                      result5.push(result6);
-                      if (/^[.]/.test(input.charAt(pos.offset))) {
-                        result6 = input.charAt(pos.offset);
-                        advance(pos, 1);
-                      } else {
-                        result6 = null;
-                        if (reportFailures === 0) {
-                          matchFailed("[.]");
-                        }
-                      }
-                    }
-                    if (result5 !== null) {
-                      result0 = [result0, result1, result2, result3, result4, result5];
-                    } else {
-                      result0 = null;
-                      pos = clone(pos1);
-                    }
-                  } else {
-                    result0 = null;
-                    pos = clone(pos1);
-                  }
+      } else {
+        peg$currPos = s2;
+        s2 = peg$c1;
+      }
+      if (s2 !== peg$FAILED) {
+        while (s2 !== peg$FAILED) {
+          s1.push(s2);
+          s2 = peg$currPos;
+          s3 = peg$parsews();
+          if (s3 !== peg$FAILED) {
+            if (input.charCodeAt(peg$currPos) === 58) {
+              s4 = peg$c97;
+              peg$currPos++;
+            } else {
+              s4 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c98); }
+            }
+            if (s4 !== peg$FAILED) {
+              s5 = peg$parsews();
+              if (s5 !== peg$FAILED) {
+                s6 = peg$parseidentifier();
+                if (s6 !== peg$FAILED) {
+                  peg$reportedPos = s2;
+                  s3 = peg$c99(s6);
+                  s2 = s3;
                 } else {
-                  result0 = null;
-                  pos = clone(pos1);
+                  peg$currPos = s2;
+                  s2 = peg$c1;
                 }
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                peg$currPos = s2;
+                s2 = peg$c1;
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s2;
+              s2 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-          if (result0 !== null) {
-            result0 = (function(offset, line, column, exps, ret) {
-                                 var expressions = exps;
-                                 expressions.push(ret);
-                                 return expressions;
-                             })(pos0.offset, pos0.line, pos0.column, result0[0], result0[4]);
+            peg$currPos = s2;
+            s2 = peg$c1;
           }
-          if (result0 === null) {
-            pos = clone(pos0);
+        }
+      } else {
+        s1 = peg$c1;
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          if (input.charCodeAt(peg$currPos) === 124) {
+            s3 = peg$c93;
+            peg$currPos++;
+          } else {
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c94); }
           }
-          if (result0 === null) {
-            pos0 = clone(pos);
-            pos1 = clone(pos);
-            result0 = parse_expressions();
-            result0 = result0 !== null ? result0 : "";
-            if (result0 !== null) {
-              result1 = [];
-              if (/^[.]/.test(input.charAt(pos.offset))) {
-                result2 = input.charAt(pos.offset);
-                advance(pos, 1);
-              } else {
-                result2 = null;
-                if (reportFailures === 0) {
-                  matchFailed("[.]");
-                }
-              }
-              while (result2 !== null) {
-                result1.push(result2);
-                if (/^[.]/.test(input.charAt(pos.offset))) {
-                  result2 = input.charAt(pos.offset);
-                  advance(pos, 1);
-                } else {
-                  result2 = null;
-                  if (reportFailures === 0) {
-                    matchFailed("[.]");
-                  }
-                }
-              }
-              if (result1 !== null) {
-                result0 = [result0, result1];
-              } else {
-                result0 = null;
-                pos = clone(pos1);
-              }
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
-            if (result0 !== null) {
-              result0 = (function(offset, line, column, expressions) {
-                                   return expressions || [];
-                               })(pos0.offset, pos0.line, pos0.column, result0[0]);
-            }
-            if (result0 === null) {
-              pos = clone(pos0);
-            }
+          if (s3 !== peg$FAILED) {
+            peg$reportedPos = s0;
+            s1 = peg$c100(s1);
+            s0 = s1;
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_sequence() {
-        var cacheKey = "sequence@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        
-        result0 = parse_jsStatement();
-        if (result0 === null) {
-          result0 = parse_stSequence();
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_stSequence() {
-        var cacheKey = "stSequence@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_temps();
-        result0 = result0 !== null ? result0 : "";
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_statements();
-            result2 = result2 !== null ? result2 : "";
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                result0 = [result0, result1, result2, result3];
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsesubexpression() {
+      var s0, s1, s2, s3, s4, s5;
+
+      var key    = peg$currPos * 56 + 38,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.charCodeAt(peg$currPos) === 40) {
+        s1 = peg$c53;
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c54); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parseexpression();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              if (input.charCodeAt(peg$currPos) === 41) {
+                s5 = peg$c56;
+                peg$currPos++;
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                s5 = peg$FAILED;
+                if (peg$silentFails === 0) { peg$fail(peg$c57); }
+              }
+              if (s5 !== peg$FAILED) {
+                peg$reportedPos = s0;
+                s1 = peg$c85(s3);
+                s0 = s1;
+              } else {
+                peg$currPos = s0;
+                s0 = peg$c1;
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, temps, statements) {
-                             return smalltalk.SequenceNode._new()
-                                    ._position_((line).__at(column))
-                                    ._temps_(temps || [])
-                                    ._nodes_(statements || []);
-                         })(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_block() {
-        var cacheKey = "block@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3, result4, result5, result6;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.charCodeAt(pos.offset) === 91) {
-          result0 = "[";
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"[\"");
-          }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsestatements() {
+      var s0, s1, s2, s3, s4, s5, s6, s7;
+
+      var key    = peg$currPos * 56 + 39,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseret();
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        if (peg$c101.test(input.charAt(peg$currPos))) {
+          s3 = input.charAt(peg$currPos);
+          peg$currPos++;
+        } else {
+          s3 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c102); }
+        }
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          if (peg$c101.test(input.charAt(peg$currPos))) {
+            s3 = input.charAt(peg$currPos);
+            peg$currPos++;
+          } else {
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c102); }
+          }
+        }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c103(s1);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_blockParamList();
-            result2 = result2 !== null ? result2 : "";
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                result4 = parse_sequence();
-                result4 = result4 !== null ? result4 : "";
-                if (result4 !== null) {
-                  result5 = parse_ws();
-                  if (result5 !== null) {
-                    if (input.charCodeAt(pos.offset) === 93) {
-                      result6 = "]";
-                      advance(pos, 1);
-                    } else {
-                      result6 = null;
-                      if (reportFailures === 0) {
-                        matchFailed("\"]\"");
-                      }
-                    }
-                    if (result6 !== null) {
-                      result0 = [result0, result1, result2, result3, result4, result5, result6];
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+      if (s0 === peg$FAILED) {
+        s0 = peg$currPos;
+        s1 = peg$parseexpressions();
+        if (s1 !== peg$FAILED) {
+          s2 = peg$parsews();
+          if (s2 !== peg$FAILED) {
+            s3 = [];
+            if (peg$c101.test(input.charAt(peg$currPos))) {
+              s4 = input.charAt(peg$currPos);
+              peg$currPos++;
+            } else {
+              s4 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c102); }
+            }
+            if (s4 !== peg$FAILED) {
+              while (s4 !== peg$FAILED) {
+                s3.push(s4);
+                if (peg$c101.test(input.charAt(peg$currPos))) {
+                  s4 = input.charAt(peg$currPos);
+                  peg$currPos++;
+                } else {
+                  s4 = peg$FAILED;
+                  if (peg$silentFails === 0) { peg$fail(peg$c102); }
+                }
+              }
+            } else {
+              s3 = peg$c1;
+            }
+            if (s3 !== peg$FAILED) {
+              s4 = peg$parsews();
+              if (s4 !== peg$FAILED) {
+                s5 = peg$parseret();
+                if (s5 !== peg$FAILED) {
+                  s6 = [];
+                  if (peg$c101.test(input.charAt(peg$currPos))) {
+                    s7 = input.charAt(peg$currPos);
+                    peg$currPos++;
+                  } else {
+                    s7 = peg$FAILED;
+                    if (peg$silentFails === 0) { peg$fail(peg$c102); }
+                  }
+                  while (s7 !== peg$FAILED) {
+                    s6.push(s7);
+                    if (peg$c101.test(input.charAt(peg$currPos))) {
+                      s7 = input.charAt(peg$currPos);
+                      peg$currPos++;
                     } else {
-                      result0 = null;
-                      pos = clone(pos1);
+                      s7 = peg$FAILED;
+                      if (peg$silentFails === 0) { peg$fail(peg$c102); }
                     }
+                  }
+                  if (s6 !== peg$FAILED) {
+                    peg$reportedPos = s0;
+                    s1 = peg$c104(s1, s5);
+                    s0 = s1;
                   } else {
-                    result0 = null;
-                    pos = clone(pos1);
+                    peg$currPos = s0;
+                    s0 = peg$c1;
                   }
                 } else {
-                  result0 = null;
-                  pos = clone(pos1);
+                  peg$currPos = s0;
+                  s0 = peg$c1;
                 }
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                peg$currPos = s0;
+                s0 = peg$c1;
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, params, sequence) {
-                             return smalltalk.BlockNode._new()
-                                    ._position_((line).__at(column))
-                                    ._parameters_(params || [])
-                                    ._nodes_([sequence._asBlockSequenceNode()]);
-                         })(pos0.offset, pos0.line, pos0.column, result0[2], result0[4]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_operand() {
-        var cacheKey = "operand@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        
-        result0 = parse_literal();
-        if (result0 === null) {
-          result0 = parse_variable();
-          if (result0 === null) {
-            result0 = parse_subexpression();
+        if (s0 === peg$FAILED) {
+          s0 = peg$currPos;
+          s1 = peg$parseexpressions();
+          if (s1 === peg$FAILED) {
+            s1 = peg$c37;
           }
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_unaryMessage() {
-        var cacheKey = "unaryMessage@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2;
-        var pos0, pos1, pos2;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          result1 = parse_identifier();
-          if (result1 !== null) {
-            pos2 = clone(pos);
-            reportFailures++;
-            if (/^[:]/.test(input.charAt(pos.offset))) {
-              result2 = input.charAt(pos.offset);
-              advance(pos, 1);
+          if (s1 !== peg$FAILED) {
+            s2 = [];
+            if (peg$c101.test(input.charAt(peg$currPos))) {
+              s3 = input.charAt(peg$currPos);
+              peg$currPos++;
             } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("[:]");
+              s3 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c102); }
+            }
+            while (s3 !== peg$FAILED) {
+              s2.push(s3);
+              if (peg$c101.test(input.charAt(peg$currPos))) {
+                s3 = input.charAt(peg$currPos);
+                peg$currPos++;
+              } else {
+                s3 = peg$FAILED;
+                if (peg$silentFails === 0) { peg$fail(peg$c102); }
               }
             }
-            reportFailures--;
-            if (result2 === null) {
-              result2 = "";
+            if (s2 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c105(s1);
+              s0 = s1;
             } else {
-              result2 = null;
-              pos = clone(pos2);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
+          }
+        }
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsesequence() {
+      var s0;
+
+      var key    = peg$currPos * 56 + 40,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$parsejsStatement();
+      if (s0 === peg$FAILED) {
+        s0 = peg$parsestSequence();
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsestSequence() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 41,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsetemps();
+      if (s1 === peg$FAILED) {
+        s1 = peg$c37;
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parsestatements();
+          if (s3 === peg$FAILED) {
+            s3 = peg$c37;
+          }
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c106(s1, s3);
+              s0 = s1;
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, selector) {
-                             return smalltalk.SendNode._new()
-                                    ._position_((line).__at(column))
-                                    ._selector_(selector);
-                         })(pos0.offset, pos0.line, pos0.column, result0[1]);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_unaryTail() {
-        var cacheKey = "unaryTail@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_unaryMessage();
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_unaryTail();
-            result2 = result2 !== null ? result2 : "";
-            if (result2 !== null) {
-              result3 = parse_ws();
-              if (result3 !== null) {
-                result0 = [result0, result1, result2, result3];
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseblock() {
+      var s0, s1, s2, s3, s4, s5, s6, s7;
+
+      var key    = peg$currPos * 56 + 42,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.charCodeAt(peg$currPos) === 91) {
+        s1 = peg$c107;
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c108); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parseblockParamList();
+          if (s3 === peg$FAILED) {
+            s3 = peg$c37;
+          }
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              s5 = peg$parsesequence();
+              if (s5 === peg$FAILED) {
+                s5 = peg$c37;
+              }
+              if (s5 !== peg$FAILED) {
+                s6 = peg$parsews();
+                if (s6 !== peg$FAILED) {
+                  if (input.charCodeAt(peg$currPos) === 93) {
+                    s7 = peg$c109;
+                    peg$currPos++;
+                  } else {
+                    s7 = peg$FAILED;
+                    if (peg$silentFails === 0) { peg$fail(peg$c110); }
+                  }
+                  if (s7 !== peg$FAILED) {
+                    peg$reportedPos = s0;
+                    s1 = peg$c111(s3, s5);
+                    s0 = s1;
+                  } else {
+                    peg$currPos = s0;
+                    s0 = peg$c1;
+                  }
+                } else {
+                  peg$currPos = s0;
+                  s0 = peg$c1;
+                }
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                peg$currPos = s0;
+                s0 = peg$c1;
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, message, tail) {
-                             if(tail) {
-                                 return tail._valueForReceiver_(message);
-                             }
-                             else {
-                                 return message;
-                             }
-                         })(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_unarySend() {
-        var cacheKey = "unarySend@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseoperand() {
+      var s0;
+
+      var key    = peg$currPos * 56 + 43,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$parseliteral();
+      if (s0 === peg$FAILED) {
+        s0 = peg$parsevariable();
+        if (s0 === peg$FAILED) {
+          s0 = peg$parsesubexpression();
+        }
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseunaryMessage() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 44,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parseidentifier();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$currPos;
+          peg$silentFails++;
+          if (peg$c13.test(input.charAt(peg$currPos))) {
+            s4 = input.charAt(peg$currPos);
+            peg$currPos++;
+          } else {
+            s4 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c14); }
+          }
+          peg$silentFails--;
+          if (s4 === peg$FAILED) {
+            s3 = peg$c112;
+          } else {
+            peg$currPos = s3;
+            s3 = peg$c1;
+          }
+          if (s3 !== peg$FAILED) {
+            peg$reportedPos = s0;
+            s1 = peg$c113(s2);
+            s0 = s1;
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
+          }
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        var result0, result1, result2;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_operand();
-        if (result0 !== null) {
-          result1 = parse_ws();
-          if (result1 !== null) {
-            result2 = parse_unaryTail();
-            result2 = result2 !== null ? result2 : "";
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseunaryTail() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 45,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseunaryMessage();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parseunaryTail();
+          if (s3 === peg$FAILED) {
+            s3 = peg$c37;
+          }
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsews();
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c114(s1, s3);
+              s0 = s1;
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, receiver, tail) {
-                             if(tail) {
-                                 return tail._valueForReceiver_(receiver);
-                             }
-                             else {
-                                 return receiver;
-                             }
-                         })(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_binaryMessage() {
-        var cacheKey = "binaryMessage@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseunarySend() {
+      var s0, s1, s2, s3;
+
+      var key    = peg$currPos * 56 + 46,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseoperand();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsews();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parseunaryTail();
+          if (s3 === peg$FAILED) {
+            s3 = peg$c37;
+          }
+          if (s3 !== peg$FAILED) {
+            peg$reportedPos = s0;
+            s1 = peg$c115(s1, s3);
+            s0 = s1;
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
+          }
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          result1 = parse_binarySelector();
-          if (result1 !== null) {
-            result2 = parse_ws();
-            if (result2 !== null) {
-              result3 = parse_unarySend();
-              if (result3 === null) {
-                result3 = parse_operand();
-              }
-              if (result3 !== null) {
-                result0 = [result0, result1, result2, result3];
-              } else {
-                result0 = null;
-                pos = clone(pos1);
-              }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsebinaryMessage() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 47,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsebinarySelector();
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parsews();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parseunarySend();
+            if (s4 === peg$FAILED) {
+              s4 = peg$parseoperand();
+            }
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c116(s2, s4);
+              s0 = s1;
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, selector, arg) {
-                             return smalltalk.SendNode._new()
-                                    ._position_((line).__at(column))
-                                    ._selector_(selector)
-                                    ._arguments_([arg]);
-                         })(pos0.offset, pos0.line, pos0.column, result0[1], result0[3]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_binaryTail() {
-        var cacheKey = "binaryTail@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_binaryMessage();
-        if (result0 !== null) {
-          result1 = parse_binaryTail();
-          result1 = result1 !== null ? result1 : "";
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, message, tail) {
-                             if(tail) {
-                                 return tail._valueForReceiver_(message);
-                              }
-                             else {
-                                 return message;
-                             }
-                         })(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_binarySend() {
-        var cacheKey = "binarySend@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_unarySend();
-        if (result0 !== null) {
-          result1 = parse_binaryTail();
-          result1 = result1 !== null ? result1 : "";
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, receiver, tail) {
-                             if(tail) {
-                                 return tail._valueForReceiver_(receiver);
-                             }
-                             else {
-                                 return receiver;
-                             }
-                         })(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 === null) {
-          pos = clone(pos0);
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsebinaryTail() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 48,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsebinaryMessage();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsebinaryTail();
+        if (s2 === peg$FAILED) {
+          s2 = peg$c37;
+        }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c117(s1, s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_keywordMessage() {
-        var cacheKey = "keywordMessage@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsebinarySend() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 49,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseunarySend();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsebinaryTail();
+        if (s2 === peg$FAILED) {
+          s2 = peg$c37;
+        }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c115(s1, s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        var result0, result1, result2, result3;
-        var pos0, pos1, pos2, pos3;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          pos2 = clone(pos);
-          pos3 = clone(pos);
-          result2 = parse_keywordPair();
-          if (result2 !== null) {
-            result3 = parse_ws();
-            if (result3 !== null) {
-              result2 = [result2, result3];
-            } else {
-              result2 = null;
-              pos = clone(pos3);
-            }
-          } else {
-            result2 = null;
-            pos = clone(pos3);
-          }
-          if (result2 !== null) {
-            result2 = (function(offset, line, column, pair) {return pair;})(pos2.offset, pos2.line, pos2.column, result2[0]);
-          }
-          if (result2 === null) {
-            pos = clone(pos2);
-          }
-          if (result2 !== null) {
-            result1 = [];
-            while (result2 !== null) {
-              result1.push(result2);
-              pos2 = clone(pos);
-              pos3 = clone(pos);
-              result2 = parse_keywordPair();
-              if (result2 !== null) {
-                result3 = parse_ws();
-                if (result3 !== null) {
-                  result2 = [result2, result3];
-                } else {
-                  result2 = null;
-                  pos = clone(pos3);
-                }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsekeywordMessage() {
+      var s0, s1, s2, s3, s4, s5;
+
+      var key    = peg$currPos * 56 + 50,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        s3 = peg$currPos;
+        s4 = peg$parsekeywordPair();
+        if (s4 !== peg$FAILED) {
+          s5 = peg$parsews();
+          if (s5 !== peg$FAILED) {
+            peg$reportedPos = s3;
+            s4 = peg$c118(s4);
+            s3 = s4;
+          } else {
+            peg$currPos = s3;
+            s3 = peg$c1;
+          }
+        } else {
+          peg$currPos = s3;
+          s3 = peg$c1;
+        }
+        if (s3 !== peg$FAILED) {
+          while (s3 !== peg$FAILED) {
+            s2.push(s3);
+            s3 = peg$currPos;
+            s4 = peg$parsekeywordPair();
+            if (s4 !== peg$FAILED) {
+              s5 = peg$parsews();
+              if (s5 !== peg$FAILED) {
+                peg$reportedPos = s3;
+                s4 = peg$c118(s4);
+                s3 = s4;
               } else {
-                result2 = null;
-                pos = clone(pos3);
-              }
-              if (result2 !== null) {
-                result2 = (function(offset, line, column, pair) {return pair;})(pos2.offset, pos2.line, pos2.column, result2[0]);
-              }
-              if (result2 === null) {
-                pos = clone(pos2);
+                peg$currPos = s3;
+                s3 = peg$c1;
               }
+            } else {
+              peg$currPos = s3;
+              s3 = peg$c1;
             }
-          } else {
-            result1 = null;
-          }
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
+          s2 = peg$c1;
         }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, pairs) {
-                             var selector = [];
-                             var args = [];
-                              for(var i = 0; i < pairs.length; i++) {
-                                  selector.push(pairs[i].key);
-                                  args.push(pairs[i].arg);
-                              }
-                              return smalltalk.SendNode._new()
-                                     ._position_((line).__at(column))
-                                     ._selector_(selector.join(""))
-                                     ._arguments_(args);
-                         })(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_keywordSend() {
-        var cacheKey = "keywordSend@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_binarySend();
-        if (result0 !== null) {
-          result1 = parse_keywordMessage();
-          if (result1 !== null) {
-            result0 = [result0, result1];
-          } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c119(s2);
+          s0 = s1;
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, receiver, tail) {
-                             return tail._valueForReceiver_(receiver);
-                         })(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_message() {
-        var cacheKey = "message@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0;
-        
-        result0 = parse_binaryMessage();
-        if (result0 === null) {
-          result0 = parse_unaryMessage();
-          if (result0 === null) {
-            result0 = parse_keywordMessage();
-          }
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_cascade() {
-        var cacheKey = "cascade@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsekeywordSend() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 56 + 51,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsebinarySend();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsekeywordMessage();
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c120(s1, s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        
-        var result0, result1, result2, result3, result4, result5, result6, result7;
-        var pos0, pos1, pos2, pos3;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          result1 = parse_keywordSend();
-          if (result1 === null) {
-            result1 = parse_binarySend();
-          }
-          if (result1 !== null) {
-            pos2 = clone(pos);
-            pos3 = clone(pos);
-            result3 = parse_ws();
-            if (result3 !== null) {
-              if (input.charCodeAt(pos.offset) === 59) {
-                result4 = ";";
-                advance(pos, 1);
-              } else {
-                result4 = null;
-                if (reportFailures === 0) {
-                  matchFailed("\";\"");
-                }
-              }
-              if (result4 !== null) {
-                result5 = parse_ws();
-                if (result5 !== null) {
-                  result6 = parse_message();
-                  if (result6 !== null) {
-                    result7 = parse_ws();
-                    if (result7 !== null) {
-                      result3 = [result3, result4, result5, result6, result7];
-                    } else {
-                      result3 = null;
-                      pos = clone(pos3);
-                    }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsemessage() {
+      var s0;
+
+      var key    = peg$currPos * 56 + 52,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$parsebinaryMessage();
+      if (s0 === peg$FAILED) {
+        s0 = peg$parseunaryMessage();
+        if (s0 === peg$FAILED) {
+          s0 = peg$parsekeywordMessage();
+        }
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsecascade() {
+      var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
+
+      var key    = peg$currPos * 56 + 53,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsekeywordSend();
+        if (s2 === peg$FAILED) {
+          s2 = peg$parsebinarySend();
+        }
+        if (s2 !== peg$FAILED) {
+          s3 = [];
+          s4 = peg$currPos;
+          s5 = peg$parsews();
+          if (s5 !== peg$FAILED) {
+            if (input.charCodeAt(peg$currPos) === 59) {
+              s6 = peg$c121;
+              peg$currPos++;
+            } else {
+              s6 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c122); }
+            }
+            if (s6 !== peg$FAILED) {
+              s7 = peg$parsews();
+              if (s7 !== peg$FAILED) {
+                s8 = peg$parsemessage();
+                if (s8 !== peg$FAILED) {
+                  s9 = peg$parsews();
+                  if (s9 !== peg$FAILED) {
+                    peg$reportedPos = s4;
+                    s5 = peg$c123(s8);
+                    s4 = s5;
                   } else {
-                    result3 = null;
-                    pos = clone(pos3);
+                    peg$currPos = s4;
+                    s4 = peg$c1;
                   }
                 } else {
-                  result3 = null;
-                  pos = clone(pos3);
+                  peg$currPos = s4;
+                  s4 = peg$c1;
                 }
               } else {
-                result3 = null;
-                pos = clone(pos3);
+                peg$currPos = s4;
+                s4 = peg$c1;
               }
             } else {
-              result3 = null;
-              pos = clone(pos3);
-            }
-            if (result3 !== null) {
-              result3 = (function(offset, line, column, mess) {return mess;})(pos2.offset, pos2.line, pos2.column, result3[3]);
-            }
-            if (result3 === null) {
-              pos = clone(pos2);
-            }
-            if (result3 !== null) {
-              result2 = [];
-              while (result3 !== null) {
-                result2.push(result3);
-                pos2 = clone(pos);
-                pos3 = clone(pos);
-                result3 = parse_ws();
-                if (result3 !== null) {
-                  if (input.charCodeAt(pos.offset) === 59) {
-                    result4 = ";";
-                    advance(pos, 1);
-                  } else {
-                    result4 = null;
-                    if (reportFailures === 0) {
-                      matchFailed("\";\"");
-                    }
-                  }
-                  if (result4 !== null) {
-                    result5 = parse_ws();
-                    if (result5 !== null) {
-                      result6 = parse_message();
-                      if (result6 !== null) {
-                        result7 = parse_ws();
-                        if (result7 !== null) {
-                          result3 = [result3, result4, result5, result6, result7];
-                        } else {
-                          result3 = null;
-                          pos = clone(pos3);
-                        }
+              peg$currPos = s4;
+              s4 = peg$c1;
+            }
+          } else {
+            peg$currPos = s4;
+            s4 = peg$c1;
+          }
+          if (s4 !== peg$FAILED) {
+            while (s4 !== peg$FAILED) {
+              s3.push(s4);
+              s4 = peg$currPos;
+              s5 = peg$parsews();
+              if (s5 !== peg$FAILED) {
+                if (input.charCodeAt(peg$currPos) === 59) {
+                  s6 = peg$c121;
+                  peg$currPos++;
+                } else {
+                  s6 = peg$FAILED;
+                  if (peg$silentFails === 0) { peg$fail(peg$c122); }
+                }
+                if (s6 !== peg$FAILED) {
+                  s7 = peg$parsews();
+                  if (s7 !== peg$FAILED) {
+                    s8 = peg$parsemessage();
+                    if (s8 !== peg$FAILED) {
+                      s9 = peg$parsews();
+                      if (s9 !== peg$FAILED) {
+                        peg$reportedPos = s4;
+                        s5 = peg$c123(s8);
+                        s4 = s5;
                       } else {
-                        result3 = null;
-                        pos = clone(pos3);
+                        peg$currPos = s4;
+                        s4 = peg$c1;
                       }
                     } else {
-                      result3 = null;
-                      pos = clone(pos3);
+                      peg$currPos = s4;
+                      s4 = peg$c1;
                     }
                   } else {
-                    result3 = null;
-                    pos = clone(pos3);
+                    peg$currPos = s4;
+                    s4 = peg$c1;
                   }
                 } else {
-                  result3 = null;
-                  pos = clone(pos3);
-                }
-                if (result3 !== null) {
-                  result3 = (function(offset, line, column, mess) {return mess;})(pos2.offset, pos2.line, pos2.column, result3[3]);
-                }
-                if (result3 === null) {
-                  pos = clone(pos2);
+                  peg$currPos = s4;
+                  s4 = peg$c1;
                 }
+              } else {
+                peg$currPos = s4;
+                s4 = peg$c1;
               }
-            } else {
-              result2 = null;
-            }
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
-            } else {
-              result0 = null;
-              pos = clone(pos1);
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
-          }
-        } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, send, messages) {
-                             var cascade = [];
-                             cascade.push(send);
-                             for(var i = 0; i < messages.length; i++) {
-                                 cascade.push(messages[i]);
-                             }
-                             return smalltalk.CascadeNode._new()
-                                    ._position_((line).__at(column))
-                                    ._receiver_(send._receiver())
-                                    ._nodes_(cascade);
-                         })(pos0.offset, pos0.line, pos0.column, result0[1], result0[2]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_jsStatement() {
-        var cacheKey = "jsStatement@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2;
-        var pos0, pos1, pos2;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        if (input.charCodeAt(pos.offset) === 60) {
-          result0 = "<";
-          advance(pos, 1);
-        } else {
-          result0 = null;
-          if (reportFailures === 0) {
-            matchFailed("\"<\"");
+            s3 = peg$c1;
           }
-        }
-        if (result0 !== null) {
-          result1 = [];
-          pos2 = clone(pos);
-          if (input.substr(pos.offset, 2) === ">>") {
-            result2 = ">>";
-            advance(pos, 2);
+          if (s3 !== peg$FAILED) {
+            peg$reportedPos = s0;
+            s1 = peg$c124(s2, s3);
+            s0 = s1;
           } else {
-            result2 = null;
-            if (reportFailures === 0) {
-              matchFailed("\">>\"");
-            }
-          }
-          if (result2 !== null) {
-            result2 = (function(offset, line, column) {return ">";})(pos2.offset, pos2.line, pos2.column);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
-          if (result2 === null) {
-            pos = clone(pos2);
-          }
-          if (result2 === null) {
-            if (/^[^>]/.test(input.charAt(pos.offset))) {
-              result2 = input.charAt(pos.offset);
-              advance(pos, 1);
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
+        }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsejsStatement() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 56 + 54,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      if (input.charCodeAt(peg$currPos) === 60) {
+        s1 = peg$c125;
+        peg$currPos++;
+      } else {
+        s1 = peg$FAILED;
+        if (peg$silentFails === 0) { peg$fail(peg$c126); }
+      }
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        s3 = peg$currPos;
+        if (input.substr(peg$currPos, 2) === peg$c127) {
+          s4 = peg$c127;
+          peg$currPos += 2;
+        } else {
+          s4 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c128); }
+        }
+        if (s4 !== peg$FAILED) {
+          peg$reportedPos = s3;
+          s4 = peg$c129();
+        }
+        s3 = s4;
+        if (s3 === peg$FAILED) {
+          if (peg$c130.test(input.charAt(peg$currPos))) {
+            s3 = input.charAt(peg$currPos);
+            peg$currPos++;
+          } else {
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c131); }
+          }
+        }
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          s3 = peg$currPos;
+          if (input.substr(peg$currPos, 2) === peg$c127) {
+            s4 = peg$c127;
+            peg$currPos += 2;
+          } else {
+            s4 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c128); }
+          }
+          if (s4 !== peg$FAILED) {
+            peg$reportedPos = s3;
+            s4 = peg$c129();
+          }
+          s3 = s4;
+          if (s3 === peg$FAILED) {
+            if (peg$c130.test(input.charAt(peg$currPos))) {
+              s3 = input.charAt(peg$currPos);
+              peg$currPos++;
             } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("[^>]");
-              }
+              s3 = peg$FAILED;
+              if (peg$silentFails === 0) { peg$fail(peg$c131); }
             }
           }
-          while (result2 !== null) {
-            result1.push(result2);
-            pos2 = clone(pos);
-            if (input.substr(pos.offset, 2) === ">>") {
-              result2 = ">>";
-              advance(pos, 2);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("\">>\"");
-              }
-            }
-            if (result2 !== null) {
-              result2 = (function(offset, line, column) {return ">";})(pos2.offset, pos2.line, pos2.column);
-            }
-            if (result2 === null) {
-              pos = clone(pos2);
-            }
-            if (result2 === null) {
-              if (/^[^>]/.test(input.charAt(pos.offset))) {
-                result2 = input.charAt(pos.offset);
-                advance(pos, 1);
-              } else {
-                result2 = null;
-                if (reportFailures === 0) {
-                  matchFailed("[^>]");
-                }
-              }
-            }
+        }
+        if (s2 !== peg$FAILED) {
+          if (input.charCodeAt(peg$currPos) === 62) {
+            s3 = peg$c132;
+            peg$currPos++;
+          } else {
+            s3 = peg$FAILED;
+            if (peg$silentFails === 0) { peg$fail(peg$c133); }
           }
-          if (result1 !== null) {
-            if (input.charCodeAt(pos.offset) === 62) {
-              result2 = ">";
-              advance(pos, 1);
-            } else {
-              result2 = null;
-              if (reportFailures === 0) {
-                matchFailed("\">\"");
-              }
-            }
-            if (result2 !== null) {
-              result0 = [result0, result1, result2];
-            } else {
-              result0 = null;
-              pos = clone(pos1);
-            }
+          if (s3 !== peg$FAILED) {
+            peg$reportedPos = s0;
+            s1 = peg$c134(s2);
+            s0 = s1;
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, val) {
-                             return smalltalk.JSStatementNode._new()
-                                    ._position_((line).__at(column))
-                                    ._source_(val.join(""));
-                         })(pos0.offset, pos0.line, pos0.column, result0[1]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      function parse_method() {
-        var cacheKey = "method@" + pos.offset;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = clone(cachedResult.nextPos);
-          return cachedResult.result;
-        }
-        
-        var result0, result1, result2, result3, result4;
-        var pos0, pos1;
-        
-        pos0 = clone(pos);
-        pos1 = clone(pos);
-        result0 = parse_ws();
-        if (result0 !== null) {
-          result1 = parse_keywordPattern();
-          if (result1 === null) {
-            result1 = parse_binaryPattern();
-            if (result1 === null) {
-              result1 = parse_unaryPattern();
-            }
-          }
-          if (result1 !== null) {
-            result2 = parse_ws();
-            if (result2 !== null) {
-              result3 = parse_sequence();
-              result3 = result3 !== null ? result3 : "";
-              if (result3 !== null) {
-                result4 = parse_ws();
-                if (result4 !== null) {
-                  result0 = [result0, result1, result2, result3, result4];
-                } else {
-                  result0 = null;
-                  pos = clone(pos1);
-                }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parsemethod() {
+      var s0, s1, s2, s3, s4, s5;
+
+      var key    = peg$currPos * 56 + 55,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        s2 = peg$parsekeywordPattern();
+        if (s2 === peg$FAILED) {
+          s2 = peg$parsebinaryPattern();
+          if (s2 === peg$FAILED) {
+            s2 = peg$parseunaryPattern();
+          }
+        }
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parsews();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parsesequence();
+            if (s4 === peg$FAILED) {
+              s4 = peg$c37;
+            }
+            if (s4 !== peg$FAILED) {
+              s5 = peg$parsews();
+              if (s5 !== peg$FAILED) {
+                peg$reportedPos = s0;
+                s1 = peg$c135(s2, s4);
+                s0 = s1;
               } else {
-                result0 = null;
-                pos = clone(pos1);
+                peg$currPos = s0;
+                s0 = peg$c1;
               }
             } else {
-              result0 = null;
-              pos = clone(pos1);
+              peg$currPos = s0;
+              s0 = peg$c1;
             }
           } else {
-            result0 = null;
-            pos = clone(pos1);
+            peg$currPos = s0;
+            s0 = peg$c1;
           }
         } else {
-          result0 = null;
-          pos = clone(pos1);
-        }
-        if (result0 !== null) {
-          result0 = (function(offset, line, column, pattern, sequence) {
-                              return smalltalk.MethodNode._new()
-                                     ._position_((line).__at(column))
-                                     ._selector_(pattern[0])
-                                     ._arguments_(pattern[1])
-                                     ._nodes_([sequence]);
-                         })(pos0.offset, pos0.line, pos0.column, result0[1], result0[3]);
-        }
-        if (result0 === null) {
-          pos = clone(pos0);
-        }
-        
-        cache[cacheKey] = {
-          nextPos: clone(pos),
-          result:  result0
-        };
-        return result0;
-      }
-      
-      
-      function cleanupExpected(expected) {
-        expected.sort();
-        
-        var lastExpected = null;
-        var cleanExpected = [];
-        for (var i = 0; i < expected.length; i++) {
-          if (expected[i] !== lastExpected) {
-            cleanExpected.push(expected[i]);
-            lastExpected = expected[i];
-          }
+          peg$currPos = s0;
+          s0 = peg$c1;
         }
-        return cleanExpected;
-      }
-      
-      
-      
-      var result = parseFunctions[startRule]();
-      
-      /*
-       * The parser is now in one of the following three states:
-       *
-       * 1. The parser successfully parsed the whole input.
-       *
-       *    - |result !== null|
-       *    - |pos.offset === input.length|
-       *    - |rightmostFailuresExpected| may or may not contain something
-       *
-       * 2. The parser successfully parsed only a part of the input.
-       *
-       *    - |result !== null|
-       *    - |pos.offset < input.length|
-       *    - |rightmostFailuresExpected| may or may not contain something
-       *
-       * 3. The parser did not successfully parse any part of the input.
-       *
-       *   - |result === null|
-       *   - |pos.offset === 0|
-       *   - |rightmostFailuresExpected| contains at least one failure
-       *
-       * All code following this comment (including called functions) must
-       * handle these states.
-       */
-      if (result === null || pos.offset !== input.length) {
-        var offset = Math.max(pos.offset, rightmostFailuresPos.offset);
-        var found = offset < input.length ? input.charAt(offset) : null;
-        var errorPosition = pos.offset > rightmostFailuresPos.offset ? pos : rightmostFailuresPos;
-        
-        throw new this.SyntaxError(
-          cleanupExpected(rightmostFailuresExpected),
-          found,
-          offset,
-          errorPosition.line,
-          errorPosition.column
-        );
-      }
-      
-      return result;
-    },
-    
-    /* Returns the parser source code. */
-    toSource: function() { return this._source; }
-  };
-  
-  /* Thrown when a parser encounters a syntax error. */
-  
-  result.SyntaxError = function(expected, found, offset, line, column) {
-    function buildMessage(expected, found) {
-      var expectedHumanized, foundHumanized;
-      
-      switch (expected.length) {
-        case 0:
-          expectedHumanized = "end of input";
-          break;
-        case 1:
-          expectedHumanized = expected[0];
-          break;
-        default:
-          expectedHumanized = expected.slice(0, expected.length - 1).join(", ")
-            + " or "
-            + expected[expected.length - 1];
-      }
-      
-      foundHumanized = found ? quote(found) : "end of input";
-      
-      return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
     }
-    
-    this.name = "SyntaxError";
-    this.expected = expected;
-    this.found = found;
-    this.message = buildMessage(expected, found);
-    this.offset = offset;
-    this.line = line;
-    this.column = column;
+
+    peg$result = peg$startRuleFunction();
+
+    if (peg$result !== peg$FAILED && peg$currPos === input.length) {
+      return peg$result;
+    } else {
+      if (peg$result !== peg$FAILED && peg$currPos < input.length) {
+        peg$fail({ type: "end", description: "end of input" });
+      }
+
+      throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
+    }
+  }
+
+  return {
+    SyntaxError: SyntaxError,
+    parse:       parse
   };
-  
-  result.SyntaxError.prototype = Error.prototype;
-  
-  return result;
 })();
 });

+ 59 - 42
support/parser.pegjs

@@ -8,51 +8,58 @@ keyword        = first:identifier last:[:] {return first + last;}
 selector      = first:[a-zA-Z] others:[a-zA-Z0-9\:]* {return first + others.join("");}
 className      = first:[A-Z] others:[a-zA-Z0-9]* {return first + others.join("");}
 string         = ['] val:(("''" {return "'";} / [^'])*) ['] {
-                     return smalltalk.ValueNode._new()
-                            ._position_((line).__at(column))
+                     return globals.ValueNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._value_(val.join("").replace(/\"/ig, '"'));
                  }
 
 symbol         = "#" rest:bareSymbol {return rest;}
 bareSymbol         = val:(selector / binarySelector / node:string {return node._value();})
                   {
-                      return smalltalk.ValueNode._new()
-                             ._position_((line).__at(column))
+                      return globals.ValueNode._new()
+                             ._position_((line()).__at(column()))
+                             ._source_(text())
                              ._value_(val);
                   }
 number         = n:(numberExp / hex / float / integer) {
-                     return smalltalk.ValueNode._new()
-                            ._position_((line).__at(column))
+                     return globals.ValueNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._value_(n);
                  }
 numberExp      = n:((float / integer) "e" integer) {return parseFloat(n.join(""));}
-hex            = neg:[-]? "16r" num:[0-9a-fA-F]+ {return parseInt((neg + num.join("")), 16);}
-float          = neg:[-]?digits:[0-9]+ "." dec:[0-9]+ {return parseFloat((neg + digits.join("") + "." + dec.join("")), 10);}
-integer        = neg:[-]?digits:[0-9]+ {return (parseInt(neg+digits.join(""), 10));}
+hex            = neg:[-]? "16r" num:[0-9a-fA-F]+ {return parseInt(((neg || '') + num.join("")), 16);}
+float          = neg:[-]?digits:[0-9]+ "." dec:[0-9]+ {return parseFloat(((neg || '') + digits.join("") + "." + dec.join("")), 10);}
+integer        = neg:[-]?digits:[0-9]+ {return (parseInt((neg || '') +digits.join(""), 10));}
 
 literalArray   = "#(" rest:literalArrayRest {return rest;}
 bareLiteralArray   = "(" rest:literalArrayRest {return rest;}
 literalArrayRest   = ws lits:(lit:(parseTimeLiteral / bareLiteralArray / bareSymbol) ws {return lit._value();})* ws ")" {
-                     return smalltalk.ValueNode._new()
-                            ._position_((line).__at(column))
+                     return globals.ValueNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._value_(lits);
                  }
 dynamicArray   = "{" ws expressions:expressions? ws "."? "}" {
-                     return smalltalk.DynamicArrayNode._new()
-                            ._position_((line).__at(column))
-                            ._nodes_(expressions);
+                     return globals.DynamicArrayNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
+                            ._nodes_(expressions || []);
                  }
 dynamicDictionary = "#{" ws expressions: expressions? ws "}" {
-                        return smalltalk.DynamicDictionaryNode._new()
-                               ._position_((line).__at(column))
-                               ._nodes_(expressions);
+                        return globals.DynamicDictionaryNode._new()
+                               ._position_((line()).__at(column()))
+                               ._source_(text())
+                               ._nodes_(expressions || []);
                     }
 pseudoVariable = val:(
                    'true' {return true;}
                  / 'false' {return false;}
                  / 'nil' {return nil;}) {
-                       return smalltalk.ValueNode._new()
-                              ._position_((line).__at(column))
+                       return globals.ValueNode._new()
+                              ._position_((line()).__at(column()))
+                              ._source_(text())
                               ._value_(val);
                    }
 parseTimeLiteral        = pseudoVariable / number / literalArray / string / symbol
@@ -61,8 +68,9 @@ literal        = runtimeLiteral / parseTimeLiteral
 
 
 variable       = identifier:identifier {
-                     return smalltalk.VariableNode._new()
-                            ._position_((line).__at(column))
+                     return globals.VariableNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._value_(identifier);
                  }
 
@@ -100,15 +108,17 @@ expressions    = first:expression others:expressionList* {
                  }
 
 assignment     = variable:variable ws ':=' ws expression:expression {
-                     return smalltalk.AssignmentNode._new()
-                            ._position_((line).__at(column))
+                     return globals.AssignmentNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._left_(variable)
                             ._right_(expression);
                  }
 
 ret            = '^' ws expression:expression ws '.'? {
-                     return smalltalk.ReturnNode._new()
-                            ._position_((line).__at(column))
+                     return globals.ReturnNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._nodes_([expression]);
                  }
   
@@ -131,8 +141,9 @@ statements     = ret:ret [.]* {return [ret];}
 sequence       = jsSequence / stSequence
 
 stSequence     = temps:temps? ws statements:statements? ws {
-                     return smalltalk.SequenceNode._new()
-                            ._position_((line).__at(column))
+                     return globals.SequenceNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._temps_(temps || [])
                             ._nodes_(statements || []);
                  }
@@ -140,8 +151,9 @@ stSequence     = temps:temps? ws statements:statements? ws {
 jsSequence     = jsStatement
 
 block          = '[' ws params:blockParamList? ws sequence:sequence? ws ']' {
-                     return smalltalk.BlockNode._new()
-                            ._position_((line).__at(column))
+                     return globals.BlockNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._parameters_(params || [])
                             ._nodes_([sequence._asBlockSequenceNode()]);
                  }
@@ -151,8 +163,9 @@ operand        = literal / reference / subexpression
 
 
 unaryMessage   = ws selector:unarySelector ![:] {
-                     return smalltalk.SendNode._new()
-                            ._position_((line).__at(column))
+                     return globals.SendNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._selector_(selector);
                  }
 
@@ -175,8 +188,9 @@ unarySend      = receiver:operand ws tail:unaryTail? {
                  }
 
 binaryMessage  = ws selector:binarySelector ws arg:(unarySend / operand) {
-                     return smalltalk.SendNode._new()
-                            ._position_((line).__at(column))
+                     return globals.SendNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._selector_(selector)
                             ._arguments_([arg]);
                  }
@@ -207,8 +221,9 @@ keywordMessage = ws pairs:(pair:keywordPair ws {return pair;})+ {
                           selector.push(pairs[i].key);
                           args.push(pairs[i].arg);
                       }
-                      return smalltalk.SendNode._new()
-                             ._position_((line).__at(column))
+                      return globals.SendNode._new()
+                             ._position_((line()).__at(column()))
+                             ._source_(text())
                              ._selector_(selector.join(""))
                              ._arguments_(args);
                  }
@@ -225,22 +240,24 @@ cascade        = ws send:(keywordSend / binarySend) messages:(ws ";" ws mess:mes
                      for(var i = 0; i < messages.length; i++) {
                          cascade.push(messages[i]);
                      }
-                     return smalltalk.CascadeNode._new()
-                            ._position_((line).__at(column))
+                     return globals.CascadeNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(text())
                             ._receiver_(send._receiver())
                             ._nodes_(cascade);
                  }
 
 jsStatement    = "<" val:((">>" {return ">";} / [^>])*) ">" {
-                     return smalltalk.JSStatementNode._new()
-                            ._position_((line).__at(column))
-                            ._source_(val.join(""));
+                     return globals.JSStatementNode._new()
+                            ._position_((line()).__at(column()))
+                            ._source_(val.join(""))
                  }
 
 
 method         = ws pattern:(keywordPattern / binaryPattern / unaryPattern) ws sequence:sequence? ws {
-                      return smalltalk.MethodNode._new()
-                             ._position_((line).__at(column))
+                      return globals.MethodNode._new()
+                             ._position_((line()).__at(column()))
+                             ._source_(text())
                              ._selector_(pattern[0])
                              ._arguments_(pattern[1])
                              ._nodes_([sequence]);

+ 1 - 1
support/smalltalk.js

@@ -1,4 +1,4 @@
 define("amber_vm/smalltalk", ["./boot"], function (boot) {
-    return boot.smalltalk;
+    return boot.vm;
 });
 

Some files were not shown because too many files changed in this diff