Browse Source

Merge branch 'master' into helios

Nicolas Petton 13 năm trước cách đây
mục cha
commit
60e5eaffe8
22 tập tin đã thay đổi với 3308 bổ sung và 2701 xóa
  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;
   }
-
 }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 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"],

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác