Browse Source

Simple REPL

Nicolas Petton 12 years ago
parent
commit
62a9ac7809
9 changed files with 3628 additions and 1 deletions
  1. 3 0
      bin/amber
  2. 11 0
      js/Kernel.deploy.js
  3. 16 0
      js/Kernel.js
  4. 8 0
      repl/Makefile
  5. 125 0
      repl/REPL.js
  6. 58 0
      repl/REPL.st
  7. 3397 0
      repl/repl.js
  8. 1 1
      server/Makefile
  9. 9 0
      st/Kernel.st

+ 3 - 0
bin/amber

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

+ 11 - 0
js/Kernel.deploy.js

@@ -2256,6 +2256,17 @@ return self;}
 }),
 smalltalk.BlockClosure);
 
+smalltalk.addMethod(
+'_numArgs',
+smalltalk.method({
+selector: 'numArgs',
+fn: function (){
+var self=this;
+return self.length;
+return self;}
+}),
+smalltalk.BlockClosure);
+
 
 
 smalltalk.addClass('Boolean', smalltalk.Object, [], 'Kernel');

+ 16 - 0
js/Kernel.js

@@ -3217,6 +3217,22 @@ referencedClasses: ["Date"]
 }),
 smalltalk.BlockClosure);
 
+smalltalk.addMethod(
+unescape('_numArgs'),
+smalltalk.method({
+selector: unescape('numArgs'),
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.length;
+return self;},
+args: [],
+source: unescape('numArgs%0A%09%3Creturn%20self.length%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BlockClosure);
+
 
 
 smalltalk.addClass('Boolean', smalltalk.Object, [], 'Kernel');

+ 8 - 0
repl/Makefile

@@ -0,0 +1,8 @@
+repl.js: REPL.st
+	../bin/amberc -m Repl -l Compiler,parser REPL.st repl
+
+run: repl.js
+	./repl
+
+clean:
+	rm -f repl.js

+ 125 - 0
repl/REPL.js

@@ -0,0 +1,125 @@
+smalltalk.addPackage('REPL', []);
+smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util'], 'REPL');
+smalltalk.addMethod(
+unescape('_prompt'),
+smalltalk.method({
+selector: unescape('prompt'),
+category: 'accessing',
+fn: function (){
+var self=this;
+return unescape("amber%20%3E%3E%20");
+return self;},
+args: [],
+source: unescape('prompt%0A%09%5E%27amber%20%3E%3E%20%27'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_createInterface'),
+smalltalk.method({
+selector: unescape('createInterface'),
+category: 'actions',
+fn: function (){
+var self=this;
+self['@interface']=smalltalk.send(self['@readline'], "_createInterface_stdout_", [smalltalk.send((typeof process == 'undefined' ? nil : process), "_stdin", []), smalltalk.send((typeof process == 'undefined' ? nil : process), "_stdout", [])]);
+smalltalk.send(self['@interface'], "_on_do_", ["line", (function(buffer){return smalltalk.send(self, "_eval_", [buffer]);})]);
+smalltalk.send(self['@interface'], "_on_do_", ["close", (function(){return smalltalk.send(self, "_close", []);})]);
+smalltalk.send(self, "_setPrompt", []);
+smalltalk.send(self['@interface'], "_prompt", []);
+return self;},
+args: [],
+source: unescape('createInterface%0A%09%22No%20completion%20for%20now%22%0A%09%22%28readline%20createInterface%20numArgs%20%3C%203%29%20%0A%09%09ifTrue%3A%20%5B%0A%09%09%09console%20log%3A%20%270.4...%27.%0A%09%09%09interface%20%3A%3D%20readline%20createInterface%3A%20process%20stdin%20autocomplete%3A%20null.%0A%09%09%09stdin%20on%3A%20%27data%27%20do%3A%20%5B%3Abuffer%20%7C%20interface%20write%3A%20buffer%5D%5D%0A%09%09ifFalse%3A%20%5B%22%0A%09%09%09interface%20%3A%3D%20readline%20createInterface%3A%20process%20stdin%20stdout%3A%20process%20stdout%22%20autocomplete%3A%20null%5D%22.%0A%09interface%20on%3A%20%27line%27%20do%3A%20%5B%3Abuffer%20%20%7C%20self%20eval%3A%20buffer%5D.%0A%09interface%20on%3A%20%27close%27%20do%3A%20%5Bself%20close%5D.%0A%09self%20setPrompt.%0A%09interface%20prompt'),
+messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "eval:", "close", "setPrompt", "prompt"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_setPrompt'),
+smalltalk.method({
+selector: unescape('setPrompt'),
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(self['@interface'], "_setPrompt_", [smalltalk.send(self, "_prompt", [])]);
+return self;},
+args: [],
+source: unescape('setPrompt%0A%09interface%20setPrompt%3A%20self%20prompt'),
+messageSends: ["setPrompt:", "prompt"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_close'),
+smalltalk.method({
+selector: unescape('close'),
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send((typeof process == 'undefined' ? nil : process), "_stdin", []), "_destroy", []);
+return self;},
+args: [],
+source: unescape('close%0A%09process%20stdin%20destroy'),
+messageSends: ["destroy", "stdin"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_eval_'),
+smalltalk.method({
+selector: unescape('eval%3A'),
+category: 'actions',
+fn: function (buffer){
+var self=this;
+var result=nil;
+((($receiver = smalltalk.send(buffer, "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_loadExpression_", [buffer]);return smalltalk.send((smalltalk.Transcript || Transcript), "_show_", [result]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_loadExpression_", [buffer]);return smalltalk.send((smalltalk.Transcript || Transcript), "_show_", [result]);})]));
+smalltalk.send(self, "_setPrompt", []);
+smalltalk.send(self['@interface'], "_prompt", []);
+return self;},
+args: ["buffer"],
+source: unescape('eval%3A%20buffer%0A%09%7C%20result%20%7C%0A%09buffer%20isEmpty%20ifFalse%3A%20%5B%0A%09%09result%20%3A%3D%20Compiler%20new%20loadExpression%3A%20buffer.%0A%09%09Transcript%20show%3A%20result%5D.%0A%09self%20setPrompt.%0A%09interface%20prompt'),
+messageSends: ["ifFalse:", "isEmpty", "loadExpression:", "new", "show:", "setPrompt", "prompt"],
+referencedClasses: ["Compiler", "Transcript"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_initialize'),
+smalltalk.method({
+selector: unescape('initialize'),
+category: 'initialization',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.Object);
+self['@readline']=smalltalk.send((typeof require == 'undefined' ? nil : require), "_value_", ["readline"]);
+self['@util']=smalltalk.send((typeof require == 'undefined' ? nil : require), "_value_", ["util"]);
+return self;},
+args: [],
+source: unescape('initialize%0A%09super%20initialize.%0A%09readline%20%3A%3D%20require%20value%3A%20%27readline%27.%0A%09util%20%3A%3D%20require%20value%3A%20%27util%27'),
+messageSends: ["initialize", "value:"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+
+smalltalk.addMethod(
+unescape('_main'),
+smalltalk.method({
+selector: unescape('main'),
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_new", []), "_createInterface", []);
+return self;},
+args: [],
+source: unescape('main%0A%09self%20new%20createInterface'),
+messageSends: ["createInterface", "new"],
+referencedClasses: []
+}),
+smalltalk.Repl.klass);
+
+

+ 58 - 0
repl/REPL.st

@@ -0,0 +1,58 @@
+Object subclass: #Repl
+	instanceVariableNames: 'readline interface util'
+	category: 'REPL'!
+
+!Repl methodsFor: 'accessing'!
+
+prompt
+	^'amber >> '
+! !
+
+!Repl methodsFor: 'actions'!
+
+createInterface
+	"No completion for now"
+	"(readline createInterface numArgs < 3) 
+		ifTrue: [
+			console log: '0.4...'.
+			interface := readline createInterface: process stdin autocomplete: null.
+			stdin on: 'data' do: [:buffer | interface write: buffer]]
+		ifFalse: ["
+			interface := readline createInterface: process stdin stdout: process stdout" autocomplete: null]".
+	interface on: 'line' do: [:buffer  | self eval: buffer].
+	interface on: 'close' do: [self close].
+	self setPrompt.
+	interface prompt
+!
+
+setPrompt
+	interface setPrompt: self prompt
+!
+
+close
+	process stdin destroy
+!
+
+eval: buffer
+	| result |
+	buffer isEmpty ifFalse: [
+		result := Compiler new loadExpression: buffer.
+		Transcript show: result].
+	self setPrompt.
+	interface prompt
+! !
+
+!Repl methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	readline := require value: 'readline'.
+	util := require value: 'util'
+! !
+
+!Repl class methodsFor: 'not yet classified'!
+
+main
+	self new createInterface
+! !
+

File diff suppressed because it is too large
+ 3397 - 0
repl/repl.js


+ 1 - 1
server/Makefile

@@ -5,4 +5,4 @@ run: server.js
 	./server
 
 clean:
-	rm -f FileServer.js server.js
+	rm -f FileServer.js

+ 9 - 0
st/Kernel.st

@@ -806,6 +806,11 @@ Object subclass: #Number
 	instanceVariableNames: ''
 	category: 'Kernel'!
 
+!Number methodsFor: ''!
+
+
+! !
+
 !Number methodsFor: 'arithmetic'!
 
 + aNumber
@@ -1047,6 +1052,10 @@ Object subclass: #BlockClosure
 
 compiledSource
 	<return self.toString()>
+!
+
+numArgs
+	<return self.length>
 ! !
 
 !BlockClosure methodsFor: 'controlling'!

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