Browse Source

Merge branch 'master' into helios

Nicolas Petton 12 years ago
parent
commit
60e5eaffe8
22 changed files with 3308 additions and 2701 deletions
  1. 1 2
      .travis.yml
  2. 2 2
      CHANGELOG
  3. 6 2
      bin/amberc.js
  4. 0 353
      bin/amberc.sh
  5. 0 33
      bin/nodecompile.js
  6. 34 15
      grunt.js
  7. 35 7
      js/Compiler-Core.deploy.js
  8. 48 10
      js/Compiler-Core.js
  9. 26 2
      js/IDE.deploy.js
  10. 38 4
      js/IDE.js
  11. 0 12
      js/boot.js
  12. 179 110
      js/lib/CodeMirror/codemirror.css
  13. 2873 1913
      js/lib/CodeMirror/codemirror.js
  14. 5 5
      package.json
  15. 0 8
      repl/Makefile
  16. 0 8
      server/Makefile
  17. 16 5
      st/Compiler-Core.st
  18. 14 2
      st/IDE.st
  19. 7 1
      st/Kernel-Methods.st
  20. 0 129
      st/Makefile
  21. 0 53
      test/Test.deploy.js
  22. 24 25
      test/Test.js

+ 1 - 2
.travis.yml

@@ -1,4 +1,3 @@
 language: node_js
 node_js:
-  - 0.8
-script: ./test/run_build.sh
+  - 0.8

+ 2 - 2
CHANGELOG

@@ -17,9 +17,9 @@ Here's a summary of change since the 0.9.1 release:
   - support for blocks contexts
 
 - SUnit improvements and cleanup, with support for async assertions
-- New build system based on gruntjs, replacing the old makefiles
+- New build system based on grunt.js, replacing the old makefiles
 - Improved ClassBuilder with better class migration support
-- New bin/amberc compiler written in Amber
+- New bin/amberc compiler written in Amber/Node.js
 - Improved loader for third party packages
 - New IDE on it's way for Amber 1.0
 

+ 6 - 2
bin/amberc.js

@@ -316,7 +316,7 @@ AmberC.prototype.collect_js_files = function(jsFiles, callback) {
 AmberC.prototype.resolve_libraries = function() {
 	// Resolve libraries listed in this.kernel_libraries
 	var self = this;
-	var all_resolved = new Combo(function(resolved_library_files, resolved_compiler_files) {
+	var all_resolved = new Combo(function(resolved_kernel_files, resolved_compiler_files) {
 		self.resolve_init(resolved_compiler_files[0]);
 	});
 	this.resolve_kernel(all_resolved.add());
@@ -332,11 +332,15 @@ AmberC.prototype.resolve_kernel = function(callback) {
 	var self = this;
 	var kernel_files = this.kernel_libraries.concat(this.defaults.load);
 	var kernel_resolved = new Combo(function() {
+		var foundLibraries = [];
 		Array.prototype.slice.call(arguments).forEach(function(file) {
 			if (undefined !== file[0]) {
-				self.defaults.libraries.push(file[0]);
+				foundLibraries.push(file[0]);
 			}
 		});
+		// boot.js and Kernel files need to be used first
+		// otherwise the global smalltalk object is undefined
+		self.defaults.libraries = foundLibraries.concat(self.defaults.libraries);
 		callback(null);
 	});
 

+ 0 - 353
bin/amberc.sh

@@ -1,353 +0,0 @@
-#!/bin/bash
-#
-# This is a "compiler" for Amber code. Run without arguments for help.
-#
-# Get Amber root directory from the location of this script so that
-# we can find the st and js directories etc.
-
-# Earlier we used this but it does not work on Mac
-# Amber=$(readlink -f `dirname ${0}`/..)
-TARGET=`dirname ${0}`/..
-pushd . >/dev/null
-cd $TARGET
-AMBER="`\pwd -P`"
-popd >/dev/null
-
-function usage {
-	cat <<ENDOFHELP
-Usage: $0 [-l lib1,lib2...] [-i file] [-m class] [-M file]
-          [-o] [-O|-A] [-d] [-s suffix] [-S suffix] [file1 [file2 ...]] [Program]
-
-   Will compile Amber files - either separately or into a runnable complete
-   program. If no .st files are listed only a linking stage is performed.
-   Files listed will be handled using these rules:
-
-   *.js
-     Files are linked (concatenated) in listed order.
-     If not found we look in $AMBER/js
-
-   *.st
-     Files are compiled into .js files before concatenated.
-     If not found we look in $AMBER/st.
-
-     NOTE: Each file is currently considered to be a fileout of a single class
-     category of the same name as the file!
-
-   If no Program is specified each given .st file will be compiled into
-   a .js file. Otherwise a <Program>.js file is linked together based on
-   the options:
-
-  -l library1,library2
-     Additionally add listed libraries (no spaces or .js) in listed order.
-
-  -i file
-     Add library initializer <file> instead of default $AMBER/js/init.js 
-
-  -m class
-     Add at end a call to #main in class <class>. 
-
-  -M file
-     Add at end javascript file <file> acting as main.
-        
-  -o
-     Optimize each js file using the Google closure compiler.
-     Using Closure compiler found at ~/compiler.jar    
-
-  -O
-     Optimize final <Program>.js using the Google closure compiler.
-     Using Closure compiler found at ~/compiler.jar
-
-  -A Same as -O but use --compilation_level ADVANCED_OPTIMIZATIONS
-
-  -d
-     Additionally export code for deploy - stripped from source etc.
-     Uses suffix ".deploy.js" in addition to any explicit given suffic using -s.
-
-  -s suffix
-     Add <suffix> to compiled js files so that File.st is compiled into
-     File.<suffix>.js.
-
-  -S suffix
-     Use <suffix> for all libraries accessed using -L or -l. This makes it possible
-     to have multiple flavors of Amber and libraries in the same place.
-
-
-     Example invocations:
-
-     Just compile Kernel-Objects.st to Kernel-Objects.js:
-
-        amberc Kernel-Objects.st
-
-     Compile Hello.st to Hello.js and create complete program called
-     Program.js and adding a call to class method #main in class Hello:
-
-        amberc -m Hello Hello.st Program
-
-     Compile two .st files into corresponding .js files,
-     and link with specific myboot.js, myKernel.js, myinit.js
-     and main.js and create complete program called Program.js:
-
-        amberc -M main.js myinit.js myboot.js myKernel.js Cat1.st Cat2.st Program
-
-ENDOFHELP
-	exit 1;
-}
-
-# Check we at least got one argument
-if [ -z $1 ] ; then
-   usage
-fi
-
-# Define our predefined library combinations
-KERNEL="boot Kernel-Objects Kernel-Classes Kernel-Methods Kernel-Collections Kernel-Exceptions Kernel-Transcript Kernel-Announcements"
-COMPILER="$KERNEL parser Compiler Compiler-Exceptions"
-
-# Predefined initializer
-INITIALIZER="$AMBER/js/init.js"
-
-# Default values
-ENV=
-INIT=$INITIALIZER
-MAIN=
-MAINFILE=
-BASE=$KERNEL
-LOAD=
-CLOSUREOPTS=
-# Ok, bad coding practice but hey, who would use such a suffix?
-SUFFIX=no-silly-suffix
-SUFFIXUSED=
-DEPLOY=false
-NODECOMPILE=nodecompile
-
-# Read options and shift them away
-while getopts "l:i:m:M:oOAds:S:h?" o; do
-case "$o" in
-   l) LOAD=$OPTARG;;
-   i) INIT=$OPTARG;;
-   m) MAIN=$OPTARG;;
-   M) MAINFILE=$OPTARG;;
-   o) CLOSURE=true
-      CLOSUREPARTS=true;;
-   O) CLOSURE=true
-      CLOSUREFULL=true;;
-   A) CLOSURE=true
-      CLOSUREOPTS="$CLOSUREOPTS --compilation_level ADVANCED_OPTIMIZATIONS"
-      CLOSUREFULL=true;;
-   d) DEPLOY=true;;
-   s) SUFFIX=$OPTARG
-      SUFFIXUSED=$SUFFIX;;
-   S) LOADSUFFIX=$OPTARG
-      SUFFIXUSED=$SUFFIX;;
-   h) usage;;
-   [?])  usage;;
-   esac
-done
-shift $(($OPTIND - 1))
-
-# Check for Closure compiler and Java
-if [ ! -z $CLOSURE ]; then
-  java > /dev/null
-  if [ $? -eq 0 ]; then 
-    if [ ! -f ~/compiler.jar ]; then
-      echo "Can not find Closure compiler at ~/compiler.jar"
-      exit 1
-    fi
-  else
-   echo "java is not installed and is needed for -O, -A or -o (Closure compiler)."
-   exit 1
-  fi
-fi
-
-# Function for looking up listed js files
-function resolvejs {
-  FNAME="$1$LOADSUFFIX.js"
-  if [ -f $FNAME ]; then
-    RESOLVED="$FNAME" 
-  else
-    if [ -f $AMBER/js/$FNAME ]; then
-      RESOLVED="$AMBER/js/$FNAME"
-    else
-      echo "Javascript file not found: $FNAME"
-      exit 1
-    fi
-  fi
-}
-
-# Resolve listed libraries in $BASE deparated by spaces
-for FILE in $BASE
-do
-   resolvejs $FILE
-   TOBASE="$TOBASE $RESOLVED"
-done
-
-# Resolve listed libraries in $LOAD separated by ,
-LOAD=${LOAD//,/\ }
-for FILE in $LOAD
-do
-   resolvejs $FILE
-   TOLOAD="$TOLOAD $RESOLVED"
-done
-
-# Resolve COMPILER
-for FILE in $COMPILER
-do
-   resolvejs $FILE
-   TOCOMPILER="$TOCOMPILER $RESOLVED"
-done
-
-# Add supplied libraries we have not already loaded (they are already resolved)
-#for FILE in $EXTRA
-#do
-#   resolvejs $FILE
-#   TOEXTRA="$TOEXTRA $RESOLVED"
-#done
-
-TOCOMPILER="$TOCOMPILER$TOLOAD"
-
-# Resolve init and nodecompile
-THEREST="init $AMBER/bin/$NODECOMPILE"
-for FILE in $THEREST
-do
-   resolvejs $FILE
-   TOCOMPILER="$TOCOMPILER $RESOLVED"
-done
-
-# Add supplied libraries
-LIBS="$TOBASE $TOLOAD"
-
-# Get a unique tempdir and make it get auto removed on exit
-TMPDIR=`mktemp -d amberc.XXXXXX 2>>/dev/null` ||\
-    TMPDIR=/tmp/amberc.$$.`date +%s` && mkdir -p $TMPDIR
-trap "rm -rf $TMPDIR" EXIT
-
-
-# --------------------------------------------------
-# Collect libraries and Smalltalk files looking
-# both locally and in $AMBER/js and $AMBER/st 
-# --------------------------------------------------
-PROGRAM=
-until [ "$*" = "" ]
-do
-  case $1 in
-     *.st)
-        CATEGORY=`basename $1 .st`
-        if [ -f "$1" ]; then
-           COMPILE="$COMPILE $1 $CATEGORY"
-           COMPILED="$COMPILED $CATEGORY$SUFFIXUSED.js"
-        else
-           if [ -f $AMBER/st/$1 ]; then
-             COMPILE="$COMPILE $AMBER/st/$1 $CATEGORY"
-             COMPILED="$COMPILED $CATEGORY$SUFFIXUSED.js"
-           else
-             echo "Amber file not found: $1"
-             exit 1
-           fi
-        fi
-        ;;
-
-     *.js)
-        resolvejs $1
-	LIBS="$LIBS $RESOLVED" 
-        ;;
-      *)
-        # Will end up being the last non js/st argument
-        PROGRAM=$1
-        ;;
-  esac
-  shift
-done
-
-# --------------------------------------------------
-# Actual compilation phase of collected .st files
-# --------------------------------------------------
-
-# Create compiler dynamically
-cat $TOCOMPILER > $TMPDIR/compiler.js
- 
-# Compile all collected .st files to .js
-echo "Loading libraries$TOCOMPILER and compiling ..."
-node $TMPDIR/compiler.js $DEPLOY $SUFFIX $COMPILE
-
-# Verify all .js files corresponding to .st files were created, otherwise exit
-IFS=" "
-for FILE in $COMPILED
-do
-  if [ ! -f "$FILE" ]; then
-    echo "Failed compilation of $FILE, exiting."
-    exit 1
-  fi 
-done
-
-if [ ! -z $CLOSUREPARTS ]; then
-  echo "Compiling all js files using Google closure compiler."
-
-  ALLJSFILES="$COMPILED $LIBS"
-  for FILE in $ALLJSFILES
-  do
-    mv $FILE $FILE.original
-    java -jar ~/compiler.jar $CLOSUREOPTS --js $FILE.original --js_output_file $FILE
-    rm $FILE.original
-  done
-fi
-
-
-if [ -z $PROGRAM ]; then
-  echo "Done."
-  exit 0
-fi
-
-# --------------------------------------------------
-# Now we start composing resulting javascript file.
-# --------------------------------------------------
-
-# Add collected libraries to libs.js file.
-if [ ! -z "$LIBS" ]; then
-  echo "Adding libraries $LIBS ..."
-  cat $LIBS > $TMPDIR/libs.js
-  LIBS=$TMPDIR/libs.js
-fi
-
-echo "Adding Amber code$COMPILED ..."
-
-# Check for init file
-if [ ! -z "$INIT" ]; then
-   if [ -f "$INIT" ]; then
-      echo "Adding initializer $INIT ..."
-   else
-      echo "Can not find init file $INIT, exiting."
-      exit 1
-   fi 
-fi
-
-# Check for adding main
-if [ ! -z "$MAIN" ]; then
-  echo "Adding call to $MAIN class >> main ..."
-  echo "smalltalk.$MAIN._main()" > $TMPDIR/main.js
-  MAIN=$TMPDIR/main.js
-fi
-
-# Check for adding main file
-if [ ! -z "$MAINFILE" ]; then
-   if [ -f "$MAINFILE" ]; then
-      echo "Adding main as $MAINFILE ..."
-   else
-      echo "Can not find main file $MAINFILE, exiting."
-      exit 1
-   fi 
-   MAIN=$MAINFILE
-fi
-
-# And finally concatenate Program.js
-echo "Writing $PROGRAM.js ..."
-cat $LIBS $COMPILED $INIT $MAIN > $PROGRAM.js
-echo "Done."
-
-
-if [ ! -z $CLOSUREFULL ]; then
-  echo "Compiling $PROGRAM.js file using Google closure compiler."
-  mv $PROGRAM.js $PROGRAM.js.original
-  java -jar ~/compiler.jar $CLOSUREOPTS --js $PROGRAM.js.original --js_output_file $PROGRAM.js
-  rm $PROGRAM.js.original
-  echo "Done."
-fi
-

+ 0 - 33
bin/nodecompile.js

@@ -1,33 +0,0 @@
-// NOTE: This code is called using the amberc bash script - do not use directly.
-// The arguments variable is a series of .st filenames and category names.
-// If it is a .st file we import it, if it is a category name we export it
-// as aCategoryName.js.
-var util = require('util'), fs = require('fs');
-
-// Only care about our arguments, strip away node, all.js and debug flag.
-var arguments = process.argv.splice(4);
-
-// First argument is also produce deploy files: "true" or "false"
-var deploy = (process.argv[2] == "true");
-
-// Second argument is suffix: "no-silly-suffix" means none
-suffix = process.argv[3];
-if (suffix == "no-silly-suffix") {
-  suffix = "";
-}
-
-// If it ends with .st, import it, otherwise export category as .js
-arguments.forEach(function(val, index, array) {
-  if (/\.st/.test(val)) {
-    util.puts("Reading file " + val);
-    code = fs.readFileSync(val, "utf8");
-    smalltalk.Importer._new()._import_(code._stream());
-  } else {
-    util.puts("Exporting " + (deploy ? "(debug + deploy)" : "(debug)") + " category "
-		+ val + " as " + val + suffix + ".js" + (deploy ? " and " + val + suffix + ".deploy.js" : ""));
-    fs.writeFileSync(val + suffix + ".js", smalltalk.Exporter._new()._exportPackage_(val));
-    if (deploy) {
-	fs.writeFileSync(val + suffix + ".deploy.js", smalltalk.StrippedExporter._new()._exportPackage_(val));
-    }
-  }
-});

+ 34 - 15
grunt.js

@@ -5,10 +5,7 @@ module.exports = function(grunt) {
   grunt.loadNpmTasks('grunt-image-embed');
   grunt.loadNpmTasks('grunt-contrib-mincss');
 
-  grunt.registerTask('build:deploy', 'shell:compileDeploy concat:deploy min');
-  grunt.registerTask('build:dev', 'shell:compileDev concat:css imageEmbed mincss css2js concat:dev');
-//  grunt.registerTask('default', 'build:deploy build:dev');
-  grunt.registerTask('default', 'amberc');
+  grunt.registerTask('default', 'pegjs amberc:all');
 
   grunt.initConfig({
     pkg: '<json:package.json>',
@@ -22,7 +19,7 @@ module.exports = function(grunt) {
         src: 'js/parser.pegjs',
         dest: 'js/parser.js',
         trackLineAndColumn: true,
-        cache: false,
+        cache: true,
         export_var: 'smalltalk.parser'
       }
     },
@@ -32,6 +29,18 @@ module.exports = function(grunt) {
         amber_dir: process.cwd(),
         closure_jar: ''
       },
+      all: {
+        working_dir: 'st',
+        target_dir : 'js',
+        src: ['Kernel-Objects.st', 'Kernel-Classes.st', 'Kernel-Methods.st', 'Kernel-Collections.st',
+              'Kernel-Exceptions.st', 'Kernel-Transcript.st', 'Kernel-Announcements.st',
+              'Importer-Exporter.st', 'Compiler-Exceptions.st', 'Compiler-Core.st', 'Compiler-AST.st',
+              'Compiler-IR.st', 'Compiler-Inlining.st', 'Compiler-Semantic.st',
+              'Canvas.st', 'SUnit.st', 'IDE.st',
+              'Kernel-Tests.st', 'Compiler-Tests.st', 'SUnit-Tests.st'
+              ],
+        deploy: true
+      },
       amber_kernel: {
         working_dir: 'st',
         target_dir : 'js',
@@ -42,7 +51,7 @@ module.exports = function(grunt) {
       amber_compiler: {
         working_dir: 'st',
         target_dir : 'js',
-        src: ['Importer-Exporter.st', 'Compiler.st', 'Compiler-Exceptions.st', 'Compiler-Core.st', 'Compiler-AST.st',
+        src: ['Importer-Exporter.st', 'Compiler-Exceptions.st', 'Compiler-Core.st', 'Compiler-AST.st',
               'Compiler-IR.st', 'Compiler-Inlining.st', 'Compiler-Semantic.st'],
         output_name: 'Compiler',
         deploy: true
@@ -56,25 +65,34 @@ module.exports = function(grunt) {
       amber_IDE: {
         working_dir: 'st',
         target_dir : 'js',
-        src: ['IDE.st', 'Documentation.st'],
+        src: ['IDE.st'],
         libraries: ['Canvas'],
         deploy: true
       },
       amber_tests: {
         working_dir: 'st',
         target_dir : 'js',
-        src: ['Kernel-Tests.st', 'Compiler-Tests.st'],
+        src: ['Kernel-Tests.st', 'Compiler-Tests.st', 'SUnit-Tests.st'],
         libraries: ['SUnit']
       },
+      amber_test_runner: {
+        working_dir: 'test',
+        src: ['Test.st'],
+        libraries: [
+        'Compiler-Exceptions', 'Compiler-Core', 'Compiler-AST',
+        'Compiler-IR', 'Compiler-Inlining', 'Compiler-Semantic', 'Compiler-Interpreter', 'parser',
+        'SUnit',
+        'Kernel-Tests', 'Compiler-Tests', 'SUnit-Tests'],
+        output_name: 'amber_test_runner'
+      },
       amber_dev: {
         working_dir: 'js',
-        src: ['Kernel-Objects.js', 'Kernel-Classes.js', 'Kernel-Methods.js', 'Kernel-Collections.js',
-              'Kernel-Exceptions.js', 'Kernel-Transcript.js', 'Kernel-Announcements.js',
-              'Compiler.js', 'Compiler-Exceptions.js', 'Compiler-Core.js', 'Compiler-AST.js',
+        src: [
+              'Compiler-Exceptions.js', 'Compiler-Core.js', 'Compiler-AST.js',
               'Compiler-IR.js', 'Compiler-Inlining.js', 'Compiler-Semantic.js',
-              'Kernel-Tests.js', 'Compiler-Tests.js',
-              'Canvas.js', 'IDE.js', 'SUnit.js', 'Documentation.js'],
-        output_name: 'amber_lib'
+              'Canvas.js', 'IDE.js', 'SUnit.js',
+              'Kernel-Tests.js', 'Compiler-Tests.js', 'SUnit-Tests.js'],
+        output_name: 'amber_dev'
       },
       server: {
         working_dir: 'server',
@@ -97,7 +115,7 @@ module.exports = function(grunt) {
       tests: ['test/*.js'],
       grunt: ['grunt.js', 'grunt/**/*.js']
     },
-
+/*
     concat: {
       deploy: {
         src: ['tmp/amber-compiled.deploy.js'],
@@ -154,6 +172,7 @@ module.exports = function(grunt) {
         dest: 'dist/amber-<%= pkg.version %>.deploy.min.js'
       }
     }
+*/
   });
 
   grunt.registerMultiTask('css2js', 'Embed CSS into JS', function() {

+ 35 - 7
js/Compiler-Core.deploy.js

@@ -72,6 +72,21 @@ return $1;
 messageSends: ["currentClass:", "source:", ",", "compileNode:", "parse:", "source"]}),
 smalltalk.Compiler);
 
+smalltalk.addMethod(
+"_compileExpression_on_",
+smalltalk.method({
+selector: "compileExpression:on:",
+fn: function (aString,anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st(self)._currentClass_(_st(anObject)._class());
+_st(self)._source_(_st(_st("xxxDoIt ^[").__comma(aString)).__comma("] value"));
+$1=_st(self)._compileNode_(_st(self)._parse_(_st(self)._source()));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"compileExpression:on:",{aString:aString,anObject:anObject}, smalltalk.Compiler)})},
+messageSends: ["currentClass:", "class", "source:", ",", "compileNode:", "parse:", "source"]}),
+smalltalk.Compiler);
+
 smalltalk.addMethod(
 "_compileNode_",
 smalltalk.method({
@@ -133,17 +148,30 @@ smalltalk.method({
 selector: "evaluateExpression:",
 fn: function (aString){
 var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._evaluateExpression_on_(aString,_st((smalltalk.DoIt || DoIt))._new());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:",{aString:aString}, smalltalk.Compiler)})},
+messageSends: ["evaluateExpression:on:", "new"]}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+"_evaluateExpression_on_",
+smalltalk.method({
+selector: "evaluateExpression:on:",
+fn: function (aString,anObject){
+var self=this;
 var result,method;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-method=_st(self)._eval_(_st(self)._compileExpression_(aString));
-_st(method)._category_("doIt");
-_st((smalltalk.DoIt || DoIt))._addCompiledMethod_(method);
-result=_st(_st((smalltalk.DoIt || DoIt))._new())._doIt();
-_st((smalltalk.DoIt || DoIt))._removeCompiledMethod_(method);
+method=_st(self)._eval_(_st(self)._compileExpression_on_(aString,anObject));
+_st(method)._category_("xxxDoIt");
+_st(_st(anObject)._class())._addCompiledMethod_(method);
+result=_st(anObject)._xxxDoIt();
+_st(_st(anObject)._class())._removeCompiledMethod_(method);
 $1=result;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:",{aString:aString,result:result,method:method}, smalltalk.Compiler)})},
-messageSends: ["eval:", "compileExpression:", "category:", "addCompiledMethod:", "doIt", "new", "removeCompiledMethod:"]}),
+}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:on:",{aString:aString,anObject:anObject,result:result,method:method}, smalltalk.Compiler)})},
+messageSends: ["eval:", "compileExpression:on:", "category:", "addCompiledMethod:", "class", "xxxDoIt", "removeCompiledMethod:"]}),
 smalltalk.Compiler);
 
 smalltalk.addMethod(

+ 48 - 10
js/Compiler-Core.js

@@ -98,6 +98,26 @@ referencedClasses: ["DoIt"]
 }),
 smalltalk.Compiler);
 
+smalltalk.addMethod(
+"_compileExpression_on_",
+smalltalk.method({
+selector: "compileExpression:on:",
+category: 'compiling',
+fn: function (aString,anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st(self)._currentClass_(_st(anObject)._class());
+_st(self)._source_(_st(_st("xxxDoIt ^[").__comma(aString)).__comma("] value"));
+$1=_st(self)._compileNode_(_st(self)._parse_(_st(self)._source()));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"compileExpression:on:",{aString:aString,anObject:anObject}, smalltalk.Compiler)})},
+args: ["aString", "anObject"],
+source: "compileExpression: aString on: anObject\x0a\x09self currentClass: anObject class.\x0a\x09self source: 'xxxDoIt ^[', aString, '] value'.\x0a\x09^self compileNode: (self parse: self source)",
+messageSends: ["currentClass:", "class", "source:", ",", "compileNode:", "parse:", "source"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
 smalltalk.addMethod(
 "_compileNode_",
 smalltalk.method({
@@ -180,23 +200,41 @@ selector: "evaluateExpression:",
 category: 'compiling',
 fn: function (aString){
 var self=this;
-var result,method;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-method=_st(self)._eval_(_st(self)._compileExpression_(aString));
-_st(method)._category_("doIt");
-_st((smalltalk.DoIt || DoIt))._addCompiledMethod_(method);
-result=_st(_st((smalltalk.DoIt || DoIt))._new())._doIt();
-_st((smalltalk.DoIt || DoIt))._removeCompiledMethod_(method);
-$1=result;
+$1=_st(self)._evaluateExpression_on_(aString,_st((smalltalk.DoIt || DoIt))._new());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:",{aString:aString,result:result,method:method}, smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:",{aString:aString}, smalltalk.Compiler)})},
 args: ["aString"],
-source: "evaluateExpression: aString\x0a\x09\x22Unlike #eval: evaluate a Smalltalk expression and answer the returned object\x22\x0a\x09| result method |\x0a    method := self eval: (self compileExpression: aString).\x0a    method category: 'doIt'.\x0a\x09DoIt addCompiledMethod: method.\x0a\x09result := DoIt new doIt.\x0a\x09DoIt removeCompiledMethod: method.\x0a\x09^result",
-messageSends: ["eval:", "compileExpression:", "category:", "addCompiledMethod:", "doIt", "new", "removeCompiledMethod:"],
+source: "evaluateExpression: aString\x0a\x09\x22Unlike #eval: evaluate a Smalltalk expression and answer the returned object\x22\x0a\x09^ self evaluateExpression: aString on: DoIt new",
+messageSends: ["evaluateExpression:on:", "new"],
 referencedClasses: ["DoIt"]
 }),
 smalltalk.Compiler);
 
+smalltalk.addMethod(
+"_evaluateExpression_on_",
+smalltalk.method({
+selector: "evaluateExpression:on:",
+category: 'compiling',
+fn: function (aString,anObject){
+var self=this;
+var result,method;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+method=_st(self)._eval_(_st(self)._compileExpression_on_(aString,anObject));
+_st(method)._category_("xxxDoIt");
+_st(_st(anObject)._class())._addCompiledMethod_(method);
+result=_st(anObject)._xxxDoIt();
+_st(_st(anObject)._class())._removeCompiledMethod_(method);
+$1=result;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:on:",{aString:aString,anObject:anObject,result:result,method:method}, smalltalk.Compiler)})},
+args: ["aString", "anObject"],
+source: "evaluateExpression: aString on: anObject\x0a\x09\x22Unlike #eval: evaluate a Smalltalk expression with anObject as the receiver and answer the returned object\x22\x0a\x09| result method |\x0a    method := self eval: (self compileExpression: aString on: anObject).\x0a    method category: 'xxxDoIt'.\x0a\x09anObject class addCompiledMethod: method.\x0a\x09result := anObject xxxDoIt.\x0a\x09anObject class removeCompiledMethod: method.\x0a\x09^result",
+messageSends: ["eval:", "compileExpression:on:", "category:", "addCompiledMethod:", "class", "xxxDoIt", "removeCompiledMethod:"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
 smalltalk.addMethod(
 "_install_forClass_category_",
 smalltalk.method({

+ 26 - 2
js/IDE.deploy.js

@@ -453,12 +453,12 @@ return smalltalk.withContext(function($ctx2) {
return _st(compiler)._parseExpres
 return smalltalk.withContext(function($ctx2) {
$1=_st(window)._alert_(_st(ex)._messageText());
 throw $early=[$1];
 }, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
-$2=_st(compiler)._evaluateExpression_(aString);
+$2=_st(compiler)._evaluateExpression_on_(aString,_st(self)._receiver());
 return $2;
 }
 catch(e) {if(e===$early)return e[0]; throw e}
 }, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString,compiler:compiler}, smalltalk.SourceArea)})},
-messageSends: ["new", "on:do:", "alert:", "messageText", "parseExpression:", "evaluateExpression:"]}),
+messageSends: ["new", "on:do:", "alert:", "messageText", "parseExpression:", "evaluateExpression:on:", "receiver"]}),
 smalltalk.SourceArea);
 
 smalltalk.addMethod(
@@ -676,6 +676,7 @@ return smalltalk.withContext(function($ctx1) { 
self['@editor'] = CodeMirror.fro
 		theme: 'amber',
                 lineNumbers: true,
                 enterMode: 'flat',
+                indentWithTabs: true,
                 matchBrackets: true,
                 electricChars: false
 	});
@@ -708,6 +709,29 @@ messageSends: ["setValue:"]}),
 smalltalk.SourceArea);
 
 
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Widget.klass.fn.prototype._initialize.apply(_st(self), []);
+_st(self)._setupCodeMirror();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.SourceArea.klass)})},
+messageSends: ["initialize", "setupCodeMirror"]}),
+smalltalk.SourceArea.klass);
+
+smalltalk.addMethod(
+"_setupCodeMirror",
+smalltalk.method({
+selector: "setupCodeMirror",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
 CodeMirror.keyMap.default.fallthrough = ["basic"] ;
+return self}, function($ctx1) {$ctx1.fill(self,"setupCodeMirror",{}, smalltalk.SourceArea.klass)})},
+messageSends: []}),
+smalltalk.SourceArea.klass);
+
 
 smalltalk.addClass('TabManager', smalltalk.Widget, ['selectedTab', 'tabs', 'opened', 'ul', 'input'], 'IDE');
 smalltalk.addMethod(

+ 38 - 4
js/IDE.js

@@ -589,14 +589,14 @@ return smalltalk.withContext(function($ctx2) {
return _st(compiler)._parseExpres
 return smalltalk.withContext(function($ctx2) {
$1=_st(window)._alert_(_st(ex)._messageText());
 throw $early=[$1];
 }, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
-$2=_st(compiler)._evaluateExpression_(aString);
+$2=_st(compiler)._evaluateExpression_on_(aString,_st(self)._receiver());
 return $2;
 }
 catch(e) {if(e===$early)return e[0]; throw e}
 }, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString,compiler:compiler}, smalltalk.SourceArea)})},
 args: ["aString"],
-source: "eval: aString\x0a\x09| compiler  |\x0a\x09compiler := Compiler new.\x0a\x09[compiler parseExpression: aString] on: Error do: [:ex |\x0a\x09\x09^window alert: ex messageText].\x0a\x09^compiler evaluateExpression: aString",
-messageSends: ["new", "on:do:", "alert:", "messageText", "parseExpression:", "evaluateExpression:"],
+source: "eval: aString\x0a\x09| compiler  |\x0a\x09compiler := Compiler new.\x0a\x09[ compiler parseExpression: aString ] on: Error do: [:ex |\x0a\x09\x09^window alert: ex messageText].\x0a\x09^compiler evaluateExpression: aString on: self receiver",
+messageSends: ["new", "on:do:", "alert:", "messageText", "parseExpression:", "evaluateExpression:on:", "receiver"],
 referencedClasses: ["Compiler", "Error"]
 }),
 smalltalk.SourceArea);
@@ -887,12 +887,13 @@ return smalltalk.withContext(function($ctx1) { 
self['@editor'] = CodeMirror.fro
 		theme: 'amber',
                 lineNumbers: true,
                 enterMode: 'flat',
+                indentWithTabs: true,
                 matchBrackets: true,
                 electricChars: false
 	});
 return self}, function($ctx1) {$ctx1.fill(self,"setEditorOn:",{aTextarea:aTextarea}, smalltalk.SourceArea)})},
 args: ["aTextarea"],
-source: "setEditorOn: aTextarea\x0a\x09<self['@editor'] = CodeMirror.fromTextArea(aTextarea, {\x0a\x09\x09theme: 'amber',\x0a                lineNumbers: true,\x0a                enterMode: 'flat',\x0a                matchBrackets: true,\x0a                electricChars: false\x0a\x09})>",
+source: "setEditorOn: aTextarea\x0a\x09<self['@editor'] = CodeMirror.fromTextArea(aTextarea, {\x0a\x09\x09theme: 'amber',\x0a                lineNumbers: true,\x0a                enterMode: 'flat',\x0a                indentWithTabs: true,\x0a                matchBrackets: true,\x0a                electricChars: false\x0a\x09})>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -933,6 +934,39 @@ referencedClasses: []
 smalltalk.SourceArea);
 
 
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Widget.klass.fn.prototype._initialize.apply(_st(self), []);
+_st(self)._setupCodeMirror();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.SourceArea.klass)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09self setupCodeMirror",
+messageSends: ["initialize", "setupCodeMirror"],
+referencedClasses: []
+}),
+smalltalk.SourceArea.klass);
+
+smalltalk.addMethod(
+"_setupCodeMirror",
+smalltalk.method({
+selector: "setupCodeMirror",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
 CodeMirror.keyMap.default.fallthrough = ["basic"] ;
+return self}, function($ctx1) {$ctx1.fill(self,"setupCodeMirror",{}, smalltalk.SourceArea.klass)})},
+args: [],
+source: "setupCodeMirror\x0a\x09< CodeMirror.keyMap.default.fallthrough = [\x22basic\x22] >",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SourceArea.klass);
+
 
 smalltalk.addClass('TabManager', smalltalk.Widget, ['selectedTab', 'tabs', 'opened', 'ul', 'input'], 'IDE');
 smalltalk.addMethod(

+ 0 - 12
js/boot.js

@@ -507,18 +507,6 @@ function Smalltalk() {
 		var selectors = Object.keys(klass.methods);
         // Do *not* delete protocols from here.
         // This is handled by #removeCompiledMethod
-        //
-		// var shouldDeleteProtocol = true;
-
-		// for(var i = 0, l = selectors.length; i<l; i++) {
-        //     if(klass.methods[selectors[i]].category === protocol) {
-        //         shouldDeleteProtocol = false;
-		// 		break;
-        //     };
-        // };
-        // if(shouldDeleteProtocol) {
-        //     klass.organization.elements.removeElement(protocol)
-        // };
     };
 
 	/* Handles unhandled errors during message sends */

+ 179 - 110
js/lib/CodeMirror/codemirror.css

@@ -1,176 +1,245 @@
+/* BASICS */
+
 .CodeMirror {
-  line-height: 1em;
+  /* Set height, width, borders, and global font properties here */
   font-family: monospace;
+  height: 300px;
+}
+.CodeMirror-scroll {
+  /* Set scrolling behaviour here */
+  overflow: auto;
+}
+
+/* PADDING */
+
+.CodeMirror-lines {
+  padding: 4px 0; /* Vertical padding around content */
+}
+.CodeMirror pre {
+  padding: 0 4px; /* Horizontal padding of content */
+}
 
-  /* Necessary so the scrollbar can be absolutely positioned within the wrapper on Lion. */
+.CodeMirror-scrollbar-filler {
+  background-color: white; /* The little square between H and V scrollbars */
+}
+
+/* GUTTER */
+
+.CodeMirror-gutters {
+  border-right: 1px solid #ddd;
+  background-color: #f7f7f7;
+}
+.CodeMirror-linenumbers {}
+.CodeMirror-linenumber {
+  padding: 0 3px 0 5px;
+  min-width: 20px;
+  text-align: right;
+  color: #999;
+}
+
+/* CURSOR */
+
+.CodeMirror div.CodeMirror-cursor {
+  border-left: 1px solid black;
+}
+/* Shown when moving in bi-directional text */
+.CodeMirror div.CodeMirror-secondarycursor {
+  border-left: 1px solid silver;
+}
+.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
+  width: auto;
+  border: 0;
+  background: transparent;
+  background: rgba(0, 200, 0, .4);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
+}
+/* Kludge to turn off filter in ie9+, which also accepts rgba */
+.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor:not(#nonsense_id) {
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+/* Can style cursor different in overwrite (non-insert) mode */
+.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
+
+/* DEFAULT THEME */
+
+.cm-s-default .cm-keyword {color: #708;}
+.cm-s-default .cm-atom {color: #219;}
+.cm-s-default .cm-number {color: #164;}
+.cm-s-default .cm-def {color: #00f;}
+.cm-s-default .cm-variable {color: black;}
+.cm-s-default .cm-variable-2 {color: #05a;}
+.cm-s-default .cm-variable-3 {color: #085;}
+.cm-s-default .cm-property {color: black;}
+.cm-s-default .cm-operator {color: black;}
+.cm-s-default .cm-comment {color: #a50;}
+.cm-s-default .cm-string {color: #a11;}
+.cm-s-default .cm-string-2 {color: #f50;}
+.cm-s-default .cm-meta {color: #555;}
+.cm-s-default .cm-error {color: #f00;}
+.cm-s-default .cm-qualifier {color: #555;}
+.cm-s-default .cm-builtin {color: #30a;}
+.cm-s-default .cm-bracket {color: #997;}
+.cm-s-default .cm-tag {color: #170;}
+.cm-s-default .cm-attribute {color: #00c;}
+.cm-s-default .cm-header {color: blue;}
+.cm-s-default .cm-quote {color: #090;}
+.cm-s-default .cm-hr {color: #999;}
+.cm-s-default .cm-link {color: #00c;}
+
+.cm-negative {color: #d44;}
+.cm-positive {color: #292;}
+.cm-header, .cm-strong {font-weight: bold;}
+.cm-em {font-style: italic;}
+.cm-emstrong {font-style: italic; font-weight: bold;}
+.cm-link {text-decoration: underline;}
+
+.cm-invalidchar {color: #f00;}
+
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+
+/* STOP */
+
+/* The rest of this file contains styles related to the mechanics of
+   the editor. You probably shouldn't touch them. */
+
+.CodeMirror {
+  line-height: 1;
   position: relative;
-  /* This prevents unwanted scrollbars from showing up on the body and wrapper in IE. */
   overflow: hidden;
 }
 
 .CodeMirror-scroll {
-  overflow: auto;
-  height: 300px;
-  /* This is needed to prevent an IE[67] bug where the scrolled content
-     is visible outside of the scrolling box. */
+  /* 30px is the magic margin used to hide the element's real scrollbars */
+  /* See overflow: hidden in .CodeMirror, and the paddings in .CodeMirror-sizer */
+  margin-bottom: -30px; margin-right: -30px;
+  padding-bottom: 30px; padding-right: 30px;
+  height: 100%;
+  outline: none; /* Prevent dragging from highlighting the element */
+  position: relative;
+}
+.CodeMirror-sizer {
   position: relative;
-  outline: none;
 }
 
-/* Vertical scrollbar */
-.CodeMirror-scrollbar {
+/* The fake, visible scrollbars. Used to force redraw during scrolling
+   before actuall scrolling happens, thus preventing shaking and
+   flickering artifacts. */
+.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler {
   position: absolute;
+  z-index: 6;
+  display: none;
+}
+.CodeMirror-vscrollbar {
   right: 0; top: 0;
   overflow-x: hidden;
   overflow-y: scroll;
-  z-index: 5;
-}
-.CodeMirror-scrollbar-inner {
-  /* This needs to have a nonzero width in order for the scrollbar to appear
-     in Firefox and IE9. */
-  width: 1px;
-}
-.CodeMirror-scrollbar.cm-sb-overlap {
-  /* Ensure that the scrollbar appears in Lion, and that it overlaps the content
-     rather than sitting to the right of it. */
-  position: absolute;
-  z-index: 1;
-  float: none;
-  right: 0;
-  min-width: 12px;
 }
-.CodeMirror-scrollbar.cm-sb-nonoverlap {
-  min-width: 12px;
+.CodeMirror-hscrollbar {
+  bottom: 0; left: 0;
+  overflow-y: hidden;
+  overflow-x: scroll;
 }
-.CodeMirror-scrollbar.cm-sb-ie7 {
-  min-width: 18px;
+.CodeMirror-scrollbar-filler {
+  right: 0; bottom: 0;
+  z-index: 6;
 }
 
-.CodeMirror-gutter {
+.CodeMirror-gutters {
   position: absolute; left: 0; top: 0;
-  z-index: 10;
-  background-color: #f7f7f7;
-  border-right: 1px solid #eee;
-  min-width: 2em;
   height: 100%;
+  padding-bottom: 30px;
+  z-index: 3;
 }
-.CodeMirror-gutter-text {
-  color: #aaa;
-  text-align: right;
-  padding: .4em .2em .4em .4em;
-  white-space: pre !important;
+.CodeMirror-gutter {
+  height: 100%;
+  display: inline-block;
+  /* Hack to make IE7 behave */
+  *zoom:1;
+  *display:inline;
+}
+.CodeMirror-gutter-elt {
+  position: absolute;
   cursor: default;
+  z-index: 4;
 }
+
 .CodeMirror-lines {
-  padding: .4em;
-  white-space: pre;
   cursor: text;
 }
-
 .CodeMirror pre {
-  -moz-border-radius: 0;
-  -webkit-border-radius: 0;
-  -o-border-radius: 0;
-  border-radius: 0;
-  border-width: 0; margin: 0; padding: 0; background: transparent;
+  /* Reset some styles that the rest of the page might have set */
+  -moz-border-radius: 0; -webkit-border-radius: 0; -o-border-radius: 0; border-radius: 0;
+  border-width: 0;
+  background: transparent;
   font-family: inherit;
   font-size: inherit;
-  padding: 0; margin: 0;
+  margin: 0;
   white-space: pre;
   word-wrap: normal;
   line-height: inherit;
   color: inherit;
+  z-index: 2;
+  position: relative;
   overflow: visible;
 }
-
 .CodeMirror-wrap pre {
   word-wrap: break-word;
   white-space: pre-wrap;
   word-break: normal;
 }
+.CodeMirror-linebackground {
+  position: absolute;
+  left: 0; right: 0; top: 0; bottom: 0;
+  z-index: 0;
+}
+
+.CodeMirror-linewidget {
+  position: relative;
+  z-index: 2;
+  overflow: auto;
+}
+
+.CodeMirror-widget {
+  display: inline-block;
+}
+
 .CodeMirror-wrap .CodeMirror-scroll {
   overflow-x: hidden;
 }
 
-.CodeMirror textarea {
-  outline: none !important;
+.CodeMirror-measure {
+  position: absolute;
+  width: 100%; height: 0px;
+  overflow: hidden;
+  visibility: hidden;
 }
+.CodeMirror-measure pre { position: static; }
 
-.CodeMirror pre.CodeMirror-cursor {
-  z-index: 10;
+.CodeMirror div.CodeMirror-cursor {
   position: absolute;
   visibility: hidden;
-  border-left: 1px solid black;
   border-right: none;
   width: 0;
 }
-.cm-keymap-fat-cursor pre.CodeMirror-cursor {
-  width: auto;
-  border: 0;
-  background: transparent;
-  background: rgba(0, 200, 0, .4);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
-}
-/* Kludge to turn off filter in ie9+, which also accepts rgba */
-.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
-.CodeMirror-focused pre.CodeMirror-cursor {
+.CodeMirror-focused div.CodeMirror-cursor {
   visibility: visible;
 }
 
-div.CodeMirror-selected { background: #d9d9d9; }
-.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
+.CodeMirror-selected { background: #d9d9d9; }
+.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
 
-.CodeMirror-searching {
+.cm-searching {
   background: #ffa;
   background: rgba(255, 255, 0, .4);
 }
 
-/* Default theme */
-
-.cm-s-default span.cm-keyword {color: #708;}
-.cm-s-default span.cm-atom {color: #219;}
-.cm-s-default span.cm-number {color: #164;}
-.cm-s-default span.cm-def {color: #00f;}
-.cm-s-default span.cm-variable {color: black;}
-.cm-s-default span.cm-variable-2 {color: #05a;}
-.cm-s-default span.cm-variable-3 {color: #085;}
-.cm-s-default span.cm-property {color: black;}
-.cm-s-default span.cm-operator {color: black;}
-.cm-s-default span.cm-comment {color: #a50;}
-.cm-s-default span.cm-string {color: #a11;}
-.cm-s-default span.cm-string-2 {color: #f50;}
-.cm-s-default span.cm-meta {color: #555;}
-.cm-s-default span.cm-error {color: #f00;}
-.cm-s-default span.cm-qualifier {color: #555;}
-.cm-s-default span.cm-builtin {color: #30a;}
-.cm-s-default span.cm-bracket {color: #997;}
-.cm-s-default span.cm-tag {color: #170;}
-.cm-s-default span.cm-attribute {color: #00c;}
-.cm-s-default span.cm-header {color: blue;}
-.cm-s-default span.cm-quote {color: #090;}
-.cm-s-default span.cm-hr {color: #999;}
-.cm-s-default span.cm-link {color: #00c;}
-span.cm-negative {color: #d44;}
-span.cm-positive {color: #292;}
-
-span.cm-header, span.cm-strong {font-weight: bold;}
-span.cm-em {font-style: italic;}
-span.cm-emstrong {font-style: italic; font-weight: bold;}
-span.cm-link {text-decoration: underline;}
-
-span.cm-invalidchar {color: #f00;}
-
-div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
-div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+/* IE7 hack to prevent it from returning funny offsetTops on the spans */
+.CodeMirror span { *vertical-align: text-bottom; }
 
 @media print {
-
   /* Hide the cursor when printing */
-  .CodeMirror pre.CodeMirror-cursor {
+  .CodeMirror div.CodeMirror-cursor {
     visibility: hidden;
   }
-
 }

File diff suppressed because it is too large
+ 2873 - 1913
js/lib/CodeMirror/codemirror.js


+ 5 - 5
package.json

@@ -23,12 +23,12 @@
         "ambers": "./bin/server"
     },
     "scripts": {
-        "test": "./test/run_build.sh"
+        "test": "./node_modules/grunt/bin/grunt amberc:amber_test_runner; node ./test/amber_test_runner.js"
     },
     "devDependencies": {
-      "pegjs": "~0.7.0",
-      "grunt": "~0.3.17",
-      "grunt-image-embed": "~0.1.3",
-      "grunt-contrib-mincss": "~0.3.2"
+        "pegjs": "~0.7.0",
+        "grunt": "~0.3.17",
+        "grunt-image-embed": "~0.1.3",
+        "grunt-contrib-mincss": "~0.3.2"
     }
 }

+ 0 - 8
repl/Makefile

@@ -1,8 +0,0 @@
-repl.js: REPL.st
-	../bin/amberc -m Repl -l Compiler-Core,Compiler-Exceptions,Compiler-AST,Compiler-IR,Compiler-Inlining,Compiler-Semantic,parser REPL.st amber
-
-run: repl.js
-	../bin/amber
-
-clean:
-	rm -f amber.js REPL.js

+ 0 - 8
server/Makefile

@@ -1,8 +0,0 @@
-server.js: FileServer.st
-	../bin/amberc -m FileServer FileServer.st server
-
-run: server.js
-	./server
-
-clean:
-	rm -f FileServer.js

+ 16 - 5
st/Compiler-Core.st

@@ -60,6 +60,12 @@ compileExpression: aString
 	^self compileNode: (self parse: self source)
 !
 
+compileExpression: aString on: anObject
+	self currentClass: anObject class.
+	self source: 'xxxDoIt ^[', aString, '] value'.
+	^self compileNode: (self parse: self source)
+!
+
 compileNode: aNode
 	| generator result |
 	generator := self codeGeneratorClass new.
@@ -77,12 +83,17 @@ eval: aString
 
 evaluateExpression: aString
 	"Unlike #eval: evaluate a Smalltalk expression and answer the returned object"
+	^ self evaluateExpression: aString on: DoIt new
+!
+
+evaluateExpression: aString on: anObject
+	"Unlike #eval: evaluate a Smalltalk expression with anObject as the receiver and answer the returned object"
 	| result method |
-    method := self eval: (self compileExpression: aString).
-    method category: 'doIt'.
-	DoIt addCompiledMethod: method.
-	result := DoIt new doIt.
-	DoIt removeCompiledMethod: method.
+    method := self eval: (self compileExpression: aString on: anObject).
+    method category: 'xxxDoIt'.
+	anObject class addCompiledMethod: method.
+	result := anObject xxxDoIt.
+	anObject class removeCompiledMethod: method.
 	^result
 !
 

+ 14 - 2
st/IDE.st

@@ -213,6 +213,7 @@ setEditorOn: aTextarea
 		theme: 'amber',
                 lineNumbers: true,
                 enterMode: 'flat',
+                indentWithTabs: true,
                 matchBrackets: true,
                 electricChars: false
 	})>
@@ -242,9 +243,9 @@ doIt
 eval: aString
 	| compiler  |
 	compiler := Compiler new.
-	[compiler parseExpression: aString] on: Error do: [:ex |
+	[ compiler parseExpression: aString ] on: Error do: [:ex |
 		^window alert: ex messageText].
-	^compiler evaluateExpression: aString
+	^compiler evaluateExpression: aString on: self receiver
 !
 
 fileIn
@@ -324,6 +325,17 @@ renderOn: html
     div onKeyDown: [:e | self handleKeyDown: e]
 ! !
 
+!SourceArea class methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	self setupCodeMirror
+!
+
+setupCodeMirror
+	< CodeMirror.keyMap.default.fallthrough = ["basic"] >
+! !
+
 Widget subclass: #TabManager
 	instanceVariableNames: 'selectedTab tabs opened ul input'
 	package: 'IDE'!

+ 7 - 1
st/Kernel-Methods.st

@@ -187,7 +187,7 @@ arguments
 !
 
 category
-	^(self basicAt: 'category') ifNil: ['']
+	^(self basicAt: 'category') ifNil: [ self defaultCategory ]
 !
 
 category: aString
@@ -243,6 +243,12 @@ source: aString
 	self basicAt: 'source' put: aString
 ! !
 
+!CompiledMethod methodsFor: 'defaults'!
+
+defaultCategory
+	^ 'as yet unclassified'
+! !
+
 Object subclass: #ForkPool
 	instanceVariableNames: 'poolSize maxPoolSize queue worker'
 	package: 'Kernel-Methods'!

+ 0 - 129
st/Makefile

@@ -1,129 +0,0 @@
-#
-# This Makefile takes .st files in the amber/st directory and produces compiled
-# javascript files from them, for both debug and deployment.
-#
-# Where we find the current runnable code and where we put our js files on install
-JS      := ../js/
-
-# The compiler script
-AMBERC  := ../bin/amberc
-
-# Generic flags to AMBERC
-FLAGS   := -d
-
-# All corresponding js filenames for every st file available
-# In other words, if we have Kernel.st and Compiler.st, then OBJECTS will be "Kernel.js Compiler.js"
-OBJECTS := $(patsubst %.st,%.js,$(wildcard *.st))
-
-# Default make target since it is the first target in this Makefile
-all: $(OBJECTS)
-
-# Step by step
-#
-# First we copy the core javascript files from current working files
-# into this directory. These files are hand written or generated using
-# other tools (parser.js). $@ is the target name.
-boot.js init.js:
-	cp ../js/$@ .
-
-# generate the parser
-# $@ is the target
-# $< is the prerequisite
-parser.js: ../js/parser.pegjs
-	pegjs --track-line-and-column --cache -e smalltalk.parser $< $@
-
-# Then we compile Kernel-*.st files depending on having boot.js, init.js and parser.js
-# $< means the first dependency - in other words Kernel-*.st
-Kernel-Objects.js: Kernel-Objects.st boot.js init.js parser.js
-	$(AMBERC) $(FLAGS) $<
-
-Kernel-Classes.js: Kernel-Classes.st boot.js init.js parser.js
-	$(AMBERC) $(FLAGS) $<
-
-Kernel-Methods.js: Kernel-Methods.st boot.js init.js parser.js
-	$(AMBERC) $(FLAGS) $<
-
-Kernel-Collections.js: Kernel-Collections.st boot.js init.js parser.js
-	$(AMBERC) $(FLAGS) $<
-
-Kernel-Exceptions.js: Kernel-Exceptions.st boot.js init.js parser.js
-	$(AMBERC) $(FLAGS) $<
-
-Kernel-Transcript.js: Kernel-Transcript.st boot.js init.js parser.js
-	$(AMBERC) $(FLAGS) $<
-
-Kernel-Announcements.js: Kernel-Announcements.st boot.js init.js parser.js
-	$(AMBERC) $(FLAGS) $<
-
-# ...and Compiler, but using the new Kernel from above.
-# We only need to depend on Kernel js files since it in turn depends on boot.js etc
-Compiler.st: Importer-Exporter.st Compiler-Exceptions.st Compiler-Core.st \
-    Compiler-AST.st Compiler-Semantic.st Compiler-IR.st Compiler-Inlining.st \
-    Compiler-Interpreter.st
-	echo "Smalltalk current createPackage: 'Compiler' properties: #{}!" >$@
-	sed -e '/^Smalltalk current createPackage:.*!$$/ d' \
-      -e 's/package: '"'[^':]*'"'!/package:'"'Compiler'"'!/' \
-      -e 's/ methodsFor: '"'[^']*'"'!$$/ methodsFor: '"'"'*Compiler'"'"'!/' \
-      $^ >>$@
-
-Compiler.js: Compiler.st Kernel-Objects.js Kernel-Classes.js Kernel-Methods.js Kernel-Collections.js \
-	Kernel-Exceptions.js Kernel-Transcript.js
-	$(AMBERC) $(FLAGS) -l Importer-Exporter,Compiler-Exceptions,Compiler-Core,Compiler-AST,Compiler-Semantic,Compiler-IR,Compiler-Inlining $<
-
-# ...now that we have a new Kernel and Compiler we use them
-# to compile the rest of st files presuming that they only depend on Kernel, like
-# for example Canvas.js and Benchfib.js.
-%.js: %.st Compiler.js
-	$(AMBERC) $(FLAGS) $<
-
-# But for some libraries there are more dependencies to care for. Then
-# we need to use -l so that the compiler first loads that library
-# before compiling the .st file. Otherwise bindings will fail.
-#
-# NOTE: With the new dependency model in class Package etc this will change!
-#
-Canvas.js: Canvas.st Compiler.js
-	$(AMBERC) $(FLAGS) $<
-
-# IDE uses JQuery
-IDE.js: IDE.st Canvas.js Compiler.js
-	$(AMBERC) $(FLAGS) -l Canvas $<
-
-TrySmalltalk.js: TrySmalltalk.st IDE.js Compiler.js
-	$(AMBERC) $(FLAGS) -l Canvas,IDE $<
-
-# Some Examples use SUnit and also IDE
-Examples.js: Examples.st SUnit.js IDE.js Compiler.js
-	$(AMBERC) $(FLAGS) -l SUnit,Canvas,IDE $<
-
-# Tests typically also use SUnit
-Kernel-Tests.js: Kernel-Tests.st SUnit.js Compiler.js
-	$(AMBERC) $(FLAGS) -l SUnit $<
-
-Compiler-Tests.js: Compiler-Tests.st SUnit.js Compiler.js
-	$(AMBERC) $(FLAGS) -l SUnit $<
-
-SUnit-Tests.js: SUnit-Tests.st SUnit.js Compiler.js
-	$(AMBERC) $(FLAGS) -l SUnit $<
-
-# Documentation
-Documentation.js: Documentation.st Canvas.js Compiler.js
-	$(AMBERC) $(FLAGS) -l Canvas $<;
-
-#Helios
-Helios-Core.js: Helios-Core.st Canvas.js Compiler.js
-	$(AMBERC) $(FLAGS) -l Canvas $<;
-
-Helios-Browser.js: Helios-Browser.st Helios-Core.js Compiler.js
-	$(AMBERC) $(FLAGS) -l Helios-Core $<;
-
-# Installing is simply copying all js files to js directory.
-install: all
-	cp *.js $(JS)
-
-# And cleaning is trivial also
-clean:
-	rm -f *.js
-
-# These three are phony
-.PHONY: all install clean

+ 0 - 53
test/Test.deploy.js

@@ -1,53 +0,0 @@
-smalltalk.addPackage('Test', {});
-smalltalk.addClass('NodeTestRunner', smalltalk.Object, [], 'Test');
-
-smalltalk.addMethod(
-"_initialize",
-smalltalk.method({
-selector: "initialize",
-fn: function (){
-var self=this;
-smalltalk.send(self, "_runTestSuite", []);
-return self;}
-}),
-smalltalk.NodeTestRunner.klass);
-
-smalltalk.addMethod(
-"_runTestSuite",
-smalltalk.method({
-selector: "runTestSuite",
-fn: function (){
-var self=this;
-var $1,$2,$3;
-var suite;
-var worker;
-suite=smalltalk.send((smalltalk.OrderedCollection || OrderedCollection),"_new",[]);
-smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.TestCase || TestCase),"_allSubclasses",[]),"_select_",[(function(each){
-return smalltalk.send(smalltalk.send(each,"_isAbstract",[]),"_not",[]);
-})]),"_do_",[(function(each){
-return smalltalk.send(suite,"_addAll_",[smalltalk.send(each,"_buildSuite",[])]);
-})]);
-worker=smalltalk.send((smalltalk.TestSuiteRunner || TestSuiteRunner),"_on_",[suite]);
-smalltalk.send(smalltalk.send(worker,"_announcer",[]),"_on_do_",[(smalltalk.ResultAnnouncement || ResultAnnouncement),(function(ann){
-var result;
-result=smalltalk.send(ann,"_result",[]);
-result;
-$1=smalltalk.send(smalltalk.send(result,"_runs",[]),"__eq",[smalltalk.send(result,"_total",[])]);
-if(smalltalk.assert($1)){
-smalltalk.send(console,"_log_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(result,"_runs",[]),"_asString",[]),"__comma",[" tests run, "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(result,"_failures",[]),"_size",[]),"_asString",[])]),"__comma",[" failures, "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(result,"_errors",[]),"_size",[]),"_asString",[])]),"__comma",[" errors."])]);
-$2=smalltalk.send(smalltalk.send(result,"_failures",[]),"_isEmpty",[]);
-if(! smalltalk.assert($2)){
-smalltalk.send(self,"_throw_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(result,"_failures",[]),"_first",[]),"_class",[]),"_name",[]),"__comma",[" >> "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(result,"_failures",[]),"_first",[]),"_selector",[])]),"__comma",[" is failing!"])]);
-};
-$3=smalltalk.send(smalltalk.send(result,"_errors",[]),"_isEmpty",[]);
-if(! smalltalk.assert($3)){
-return smalltalk.send(self,"_throw_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(result,"_errors",[]),"_first",[]),"_class",[]),"_name",[]),"__comma",[" >> "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(result,"_errors",[]),"_first",[]),"_selector",[])]),"__comma",[" has errors!"])]);
-};
-};
-})]);
-smalltalk.send(worker,"_run",[]);
-return self}
-}),
-smalltalk.NodeTestRunner.klass);
-
-

+ 24 - 25
test/Test.js

@@ -1,4 +1,4 @@
-smalltalk.addPackage('Test', {});
+smalltalk.addPackage('Test');
 smalltalk.addClass('NodeTestRunner', smalltalk.Object, [], 'Test');
 
 smalltalk.addMethod(
@@ -8,10 +8,10 @@ selector: "initialize",
 category: 'not yet classified',
 fn: function (){
 var self=this;
-smalltalk.send(self, "_runTestSuite", []);
-return self;},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._runTestSuite();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.NodeTestRunner.klass)})},
 args: [],
-source: "initialize\x0d\x0a\x09self runTestSuite",
+source: "initialize\x0a\x09self runTestSuite",
 messageSends: ["runTestSuite"],
 referencedClasses: []
 }),
@@ -24,35 +24,34 @@ selector: "runTestSuite",
 category: 'not yet classified',
 fn: function (){
 var self=this;
-var $1,$2,$3;
-var suite;
-var worker;
-suite=smalltalk.send((smalltalk.OrderedCollection || OrderedCollection),"_new",[]);
-smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.TestCase || TestCase),"_allSubclasses",[]),"_select_",[(function(each){
-return smalltalk.send(smalltalk.send(each,"_isAbstract",[]),"_not",[]);
-})]),"_do_",[(function(each){
-return smalltalk.send(suite,"_addAll_",[smalltalk.send(each,"_buildSuite",[])]);
-})]);
-worker=smalltalk.send((smalltalk.TestSuiteRunner || TestSuiteRunner),"_on_",[suite]);
-smalltalk.send(smalltalk.send(worker,"_announcer",[]),"_on_do_",[(smalltalk.ResultAnnouncement || ResultAnnouncement),(function(ann){
+var suite,worker;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+suite=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
+_st(_st(_st((smalltalk.TestCase || TestCase))._allSubclasses())._select_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(each)._isAbstract())._not();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})})))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(suite)._addAll_(_st(each)._buildSuite());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+worker=_st((smalltalk.TestSuiteRunner || TestSuiteRunner))._on_(suite);
+_st(_st(worker)._announcer())._on_do_((smalltalk.ResultAnnouncement || ResultAnnouncement),(function(ann){
 var result;
-result=smalltalk.send(ann,"_result",[]);
+return smalltalk.withContext(function($ctx2) {
result=_st(ann)._result();
 result;
-$1=smalltalk.send(smalltalk.send(result,"_runs",[]),"__eq",[smalltalk.send(result,"_total",[])]);
+$1=_st(_st(result)._runs()).__eq(_st(result)._total());
 if(smalltalk.assert($1)){
-smalltalk.send(console,"_log_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(result,"_runs",[]),"_asString",[]),"__comma",[" tests run, "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(result,"_failures",[]),"_size",[]),"_asString",[])]),"__comma",[" failures, "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(result,"_errors",[]),"_size",[]),"_asString",[])]),"__comma",[" errors."])]);
-$2=smalltalk.send(smalltalk.send(result,"_failures",[]),"_isEmpty",[]);
+_st(console)._log_(_st(_st(_st(_st(_st(_st(_st(result)._runs())._asString()).__comma(" tests run, ")).__comma(_st(_st(_st(result)._failures())._size())._asString())).__comma(" failures, ")).__comma(_st(_st(_st(result)._errors())._size())._asString())).__comma(" errors."));
+$2=_st(_st(result)._failures())._isEmpty();
 if(! smalltalk.assert($2)){
-smalltalk.send(self,"_throw_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(result,"_failures",[]),"_first",[]),"_class",[]),"_name",[]),"__comma",[" >> "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(result,"_failures",[]),"_first",[]),"_selector",[])]),"__comma",[" is failing!"])]);
+_st(self)._throw_(_st(_st(_st(_st(_st(_st(_st(result)._failures())._first())._class())._name()).__comma(" >> ")).__comma(_st(_st(_st(result)._failures())._first())._selector())).__comma(" is failing!"));
 };
-$3=smalltalk.send(smalltalk.send(result,"_errors",[]),"_isEmpty",[]);
+$3=_st(_st(result)._errors())._isEmpty();
 if(! smalltalk.assert($3)){
-return smalltalk.send(self,"_throw_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(result,"_errors",[]),"_first",[]),"_class",[]),"_name",[]),"__comma",[" >> "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(result,"_errors",[]),"_first",[]),"_selector",[])]),"__comma",[" has errors!"])]);
+return _st(self)._throw_(_st(_st(_st(_st(_st(_st(_st(result)._errors())._first())._class())._name()).__comma(" >> ")).__comma(_st(_st(_st(result)._errors())._first())._selector())).__comma(" has errors!"));
 };
 };
-})]);
-smalltalk.send(worker,"_run",[]);
-return self},
+}, function($ctx2) {$ctx2.fillBlock({ann:ann,result:result},$ctx1)})}));
+_st(worker)._run();
+return self}, function($ctx1) {$ctx1.fill(self,"runTestSuite",{suite:suite,worker:worker}, smalltalk.NodeTestRunner.klass)})},
 args: [],
 source: "runTestSuite\x0a\x09| suite worker |\x0a\x0a\x09suite := OrderedCollection new.\x0a    (TestCase allSubclasses select: [ :each | each isAbstract not ])\x0a\x09do: [ :each | suite addAll: each buildSuite ].\x0a\x0a\x09worker := TestSuiteRunner on: suite.\x0a\x09worker announcer on: ResultAnnouncement do:\x0a\x09[ :ann | | result |\x0a    \x09result := ann result.\x0a        result runs = result total ifTrue: [\x0a\x09        console log: result runs asString, ' tests run, ', result failures size asString, ' failures, ', result errors size asString, ' errors.'.\x0a\x0a            result failures isEmpty ifFalse: [\x0a                self throw: result failures first class name, ' >> ', result failures first selector, ' is failing!' ].\x0a            result errors isEmpty ifFalse: [\x0a                self throw: result errors first class name, ' >> ', result errors first selector, ' has errors!' ].\x0a    ]].\x0a    worker run",
 messageSends: ["new", "do:", "addAll:", "buildSuite", "select:", "not", "isAbstract", "allSubclasses", "on:", "on:do:", "result", "ifTrue:", "log:", ",", "asString", "size", "errors", "failures", "runs", "ifFalse:", "throw:", "selector", "first", "name", "class", "isEmpty", "=", "total", "announcer", "run"],

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