|
@@ -1105,8 +1105,26 @@ smalltalk.AmdExporter);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-smalltalk.addClass('ChunkParser', smalltalk.Object, ['stream'], 'Kernel-ImportExport');
|
|
|
|
|
|
+smalltalk.addClass('ChunkParser', smalltalk.Object, ['stream', 'last'], 'Kernel-ImportExport');
|
|
smalltalk.ChunkParser.comment="I am responsible for parsing aStream contents in the chunk format.\x0a\x0a## API\x0a\x0a ChunkParser new\x0a stream: aStream;\x0a nextChunk";
|
|
smalltalk.ChunkParser.comment="I am responsible for parsing aStream contents in the chunk format.\x0a\x0a## API\x0a\x0a ChunkParser new\x0a stream: aStream;\x0a nextChunk";
|
|
|
|
+smalltalk.addMethod(
|
|
|
|
+smalltalk.method({
|
|
|
|
+selector: "last",
|
|
|
|
+protocol: 'accessing',
|
|
|
|
+fn: function (){
|
|
|
|
+var self=this;
|
|
|
|
+return smalltalk.withContext(function($ctx1) {
|
|
|
|
+var $1;
|
|
|
|
+$1=self["@last"];
|
|
|
|
+return $1;
|
|
|
|
+}, function($ctx1) {$ctx1.fill(self,"last",{},smalltalk.ChunkParser)})},
|
|
|
|
+args: [],
|
|
|
|
+source: "last\x0a\x09^ last",
|
|
|
|
+messageSends: [],
|
|
|
|
+referencedClasses: []
|
|
|
|
+}),
|
|
|
|
+smalltalk.ChunkParser);
|
|
|
|
+
|
|
smalltalk.addMethod(
|
|
smalltalk.addMethod(
|
|
smalltalk.method({
|
|
smalltalk.method({
|
|
selector: "nextChunk",
|
|
selector: "nextChunk",
|
|
@@ -1115,7 +1133,7 @@ fn: function (){
|
|
var self=this;
|
|
var self=this;
|
|
var char,result,chunk;
|
|
var char,result,chunk;
|
|
return smalltalk.withContext(function($ctx1) {
|
|
return smalltalk.withContext(function($ctx1) {
|
|
-var $1,$2,$3;
|
|
|
|
|
|
+var $1,$2,$3,$4;
|
|
var $early={};
|
|
var $early={};
|
|
try {
|
|
try {
|
|
result=""._writeStream();
|
|
result=""._writeStream();
|
|
@@ -1134,18 +1152,21 @@ $2=_st(_st(self["@stream"])._peek()).__eq("!");
|
|
if(smalltalk.assert($2)){
|
|
if(smalltalk.assert($2)){
|
|
_st(self["@stream"])._next();
|
|
_st(self["@stream"])._next();
|
|
} else {
|
|
} else {
|
|
-$3=_st(_st(result)._contents())._trimBoth();
|
|
|
|
|
|
+self["@last"]=_st(_st(result)._contents())._trimBoth();
|
|
|
|
+$3=self["@last"];
|
|
throw $early=[$3];
|
|
throw $early=[$3];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
return _st(result)._nextPut_(char);
|
|
return _st(result)._nextPut_(char);
|
|
}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
|
|
}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
|
|
-return nil;
|
|
|
|
|
|
+self["@last"]=nil;
|
|
|
|
+$4=self["@last"];
|
|
|
|
+return $4;
|
|
}
|
|
}
|
|
catch(e) {if(e===$early)return e[0]; throw e}
|
|
catch(e) {if(e===$early)return e[0]; throw e}
|
|
}, function($ctx1) {$ctx1.fill(self,"nextChunk",{char:char,result:result,chunk:chunk},smalltalk.ChunkParser)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"nextChunk",{char:char,result:result,chunk:chunk},smalltalk.ChunkParser)})},
|
|
args: [],
|
|
args: [],
|
|
-source: "nextChunk\x0a\x09\x22The chunk format (Smalltalk Interchange Format or Fileout format)\x0a\x09is a trivial format but can be a bit tricky to understand:\x0a\x09\x09- Uses the exclamation mark as delimiter of chunks.\x0a\x09\x09- Inside a chunk a normal exclamation mark must be doubled.\x0a\x09\x09- A non empty chunk must be a valid Smalltalk expression.\x0a\x09\x09- A chunk on top level with a preceding empty chunk is an instruction chunk:\x0a\x09\x09\x09- The object created by the expression then takes over reading chunks.\x0a\x0a\x09This method returns next chunk as a String (trimmed), empty String (all whitespace) or nil.\x22\x0a\x0a\x09| char result chunk |\x0a\x09result := '' writeStream.\x0a\x09\x09[ char := stream next.\x0a\x09\x09char notNil ] whileTrue: [\x0a\x09\x09\x09\x09char = '!' ifTrue: [\x0a\x09\x09\x09\x09\x09\x09stream peek = '!'\x0a\x09\x09\x09\x09\x09\x09\x09\x09ifTrue: [ stream next \x22skipping the escape double\x22 ]\x0a\x09\x09\x09\x09\x09\x09\x09\x09ifFalse: [ ^ result contents trimBoth \x22chunk end marker found\x22 ]].\x0a\x09\x09\x09\x09result nextPut: char ].\x0a\x09^ nil \x22a chunk needs to end with !\x22",
|
|
|
|
|
|
+source: "nextChunk\x0a\x09\x22The chunk format (Smalltalk Interchange Format or Fileout format)\x0a\x09is a trivial format but can be a bit tricky to understand:\x0a\x09\x09- Uses the exclamation mark as delimiter of chunks.\x0a\x09\x09- Inside a chunk a normal exclamation mark must be doubled.\x0a\x09\x09- A non empty chunk must be a valid Smalltalk expression.\x0a\x09\x09- A chunk on top level with a preceding empty chunk is an instruction chunk:\x0a\x09\x09\x09- The object created by the expression then takes over reading chunks.\x0a\x0a\x09This method returns next chunk as a String (trimmed), empty String (all whitespace) or nil.\x22\x0a\x0a\x09| char result chunk |\x0a\x09result := '' writeStream.\x0a\x09\x09[ char := stream next.\x0a\x09\x09char notNil ] whileTrue: [\x0a\x09\x09\x09\x09char = '!' ifTrue: [\x0a\x09\x09\x09\x09\x09\x09stream peek = '!'\x0a\x09\x09\x09\x09\x09\x09\x09\x09ifTrue: [ stream next \x22skipping the escape double\x22 ]\x0a\x09\x09\x09\x09\x09\x09\x09\x09ifFalse: [ ^ last := result contents trimBoth \x22chunk end marker found\x22 ]].\x0a\x09\x09\x09\x09result nextPut: char ].\x0a\x09^ last := nil \x22a chunk needs to end with !\x22",
|
|
messageSends: ["writeStream", "whileTrue:", "next", "notNil", "ifTrue:", "=", "ifTrue:ifFalse:", "peek", "trimBoth", "contents", "nextPut:"],
|
|
messageSends: ["writeStream", "whileTrue:", "next", "notNil", "ifTrue:", "=", "ifTrue:ifFalse:", "peek", "trimBoth", "contents", "nextPut:"],
|
|
referencedClasses: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
@@ -1304,7 +1325,7 @@ referencedClasses: []
|
|
smalltalk.ExportMethodProtocol.klass);
|
|
smalltalk.ExportMethodProtocol.klass);
|
|
|
|
|
|
|
|
|
|
-smalltalk.addClass('Importer', smalltalk.Object, [], 'Kernel-ImportExport');
|
|
|
|
|
|
+smalltalk.addClass('Importer', smalltalk.Object, ['lastSection', 'lastChunk'], 'Kernel-ImportExport');
|
|
smalltalk.Importer.comment="I can import Amber code from a string in the chunk format.\x0a\x0a## API\x0a\x0a Importer new import: aString";
|
|
smalltalk.Importer.comment="I can import Amber code from a string in the chunk format.\x0a\x0a## API\x0a\x0a Importer new import: aString";
|
|
smalltalk.addMethod(
|
|
smalltalk.addMethod(
|
|
smalltalk.method({
|
|
smalltalk.method({
|
|
@@ -1315,22 +1336,29 @@ var self=this;
|
|
var chunk,result,parser,lastEmpty;
|
|
var chunk,result,parser,lastEmpty;
|
|
function $ChunkParser(){return smalltalk.ChunkParser||(typeof ChunkParser=="undefined"?nil:ChunkParser)}
|
|
function $ChunkParser(){return smalltalk.ChunkParser||(typeof ChunkParser=="undefined"?nil:ChunkParser)}
|
|
function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
|
|
function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
|
|
|
|
+function $Error(){return smalltalk.Error||(typeof Error=="undefined"?nil:Error)}
|
|
return smalltalk.withContext(function($ctx1) {
|
|
return smalltalk.withContext(function($ctx1) {
|
|
var $1,$2;
|
|
var $1,$2;
|
|
parser=_st($ChunkParser())._on_(aStream);
|
|
parser=_st($ChunkParser())._on_(aStream);
|
|
lastEmpty=false;
|
|
lastEmpty=false;
|
|
|
|
+self["@lastSection"]="n/a, not started";
|
|
|
|
+self["@lastChunk"]=nil;
|
|
_st((function(){
|
|
_st((function(){
|
|
return smalltalk.withContext(function($ctx2) {
|
|
return smalltalk.withContext(function($ctx2) {
|
|
|
|
+_st((function(){
|
|
|
|
+return smalltalk.withContext(function($ctx3) {
|
|
chunk=_st(parser)._nextChunk();
|
|
chunk=_st(parser)._nextChunk();
|
|
chunk;
|
|
chunk;
|
|
return _st(chunk)._isNil();
|
|
return _st(chunk)._isNil();
|
|
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._whileFalse_((function(){
|
|
|
|
-return smalltalk.withContext(function($ctx2) {
|
|
|
|
|
|
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}))._whileFalse_((function(){
|
|
|
|
+return smalltalk.withContext(function($ctx3) {
|
|
$1=_st(chunk)._isEmpty();
|
|
$1=_st(chunk)._isEmpty();
|
|
if(smalltalk.assert($1)){
|
|
if(smalltalk.assert($1)){
|
|
lastEmpty=true;
|
|
lastEmpty=true;
|
|
return lastEmpty;
|
|
return lastEmpty;
|
|
} else {
|
|
} else {
|
|
|
|
+self["@lastSection"]=chunk;
|
|
|
|
+self["@lastSection"];
|
|
result=_st(_st($Compiler())._new())._evaluateExpression_(chunk);
|
|
result=_st(_st($Compiler())._new())._evaluateExpression_(chunk);
|
|
result;
|
|
result;
|
|
$2=lastEmpty;
|
|
$2=lastEmpty;
|
|
@@ -1340,12 +1368,56 @@ lastEmpty;
|
|
return _st(result)._scanFrom_(parser);
|
|
return _st(result)._scanFrom_(parser);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
|
|
|
|
|
|
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,3)})}));
|
|
|
|
+self["@lastSection"]="n/a, finished";
|
|
|
|
+return self["@lastSection"];
|
|
|
|
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._on_do_($Error(),(function(e){
|
|
|
|
+return smalltalk.withContext(function($ctx2) {
|
|
|
|
+self["@lastChunk"]=_st(parser)._last();
|
|
|
|
+self["@lastChunk"];
|
|
|
|
+return _st(e)._signal();
|
|
|
|
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1,7)})}));
|
|
return self}, function($ctx1) {$ctx1.fill(self,"import:",{aStream:aStream,chunk:chunk,result:result,parser:parser,lastEmpty:lastEmpty},smalltalk.Importer)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"import:",{aStream:aStream,chunk:chunk,result:result,parser:parser,lastEmpty:lastEmpty},smalltalk.Importer)})},
|
|
args: ["aStream"],
|
|
args: ["aStream"],
|
|
-source: "import: aStream\x0a\x09| chunk result parser lastEmpty |\x0a\x09parser := ChunkParser on: aStream.\x0a\x09lastEmpty := false.\x0a\x09[ chunk := parser nextChunk.\x0a\x09chunk isNil ] whileFalse: [\x0a\x09\x09chunk isEmpty\x0a\x09\x09\x09ifTrue: [ lastEmpty := true ]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09result := Compiler new evaluateExpression: chunk.\x0a\x09\x09\x09\x09lastEmpty\x0a\x09\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09lastEmpty := false.\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09result scanFrom: parser ]] ]",
|
|
|
|
-messageSends: ["on:", "whileFalse:", "nextChunk", "isNil", "ifTrue:ifFalse:", "isEmpty", "evaluateExpression:", "new", "ifTrue:", "scanFrom:"],
|
|
|
|
-referencedClasses: ["ChunkParser", "Compiler"]
|
|
|
|
|
|
+source: "import: aStream\x0a\x09| chunk result parser lastEmpty |\x0a\x09parser := ChunkParser on: aStream.\x0a\x09lastEmpty := false.\x0a\x09lastSection := 'n/a, not started'.\x0a\x09lastChunk := nil.\x0a\x09[\x0a\x09[ chunk := parser nextChunk.\x0a\x09chunk isNil ] whileFalse: [\x0a\x09\x09chunk isEmpty\x0a\x09\x09\x09ifTrue: [ lastEmpty := true ]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09lastSection := chunk.\x0a\x09\x09\x09\x09result := Compiler new evaluateExpression: chunk.\x0a\x09\x09\x09\x09lastEmpty\x0a\x09\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09lastEmpty := false.\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09result scanFrom: parser ]] ].\x0a\x09lastSection := 'n/a, finished'\x0a\x09] on: Error do: [:e | lastChunk := parser last. e signal ].",
|
|
|
|
+messageSends: ["on:", "on:do:", "whileFalse:", "nextChunk", "isNil", "ifTrue:ifFalse:", "isEmpty", "evaluateExpression:", "new", "ifTrue:", "scanFrom:", "last", "signal"],
|
|
|
|
+referencedClasses: ["ChunkParser", "Compiler", "Error"]
|
|
|
|
+}),
|
|
|
|
+smalltalk.Importer);
|
|
|
|
+
|
|
|
|
+smalltalk.addMethod(
|
|
|
|
+smalltalk.method({
|
|
|
|
+selector: "lastChunk",
|
|
|
|
+protocol: 'accessing',
|
|
|
|
+fn: function (){
|
|
|
|
+var self=this;
|
|
|
|
+return smalltalk.withContext(function($ctx1) {
|
|
|
|
+var $1;
|
|
|
|
+$1=self["@lastChunk"];
|
|
|
|
+return $1;
|
|
|
|
+}, function($ctx1) {$ctx1.fill(self,"lastChunk",{},smalltalk.Importer)})},
|
|
|
|
+args: [],
|
|
|
|
+source: "lastChunk\x0a\x09^ lastChunk",
|
|
|
|
+messageSends: [],
|
|
|
|
+referencedClasses: []
|
|
|
|
+}),
|
|
|
|
+smalltalk.Importer);
|
|
|
|
+
|
|
|
|
+smalltalk.addMethod(
|
|
|
|
+smalltalk.method({
|
|
|
|
+selector: "lastSection",
|
|
|
|
+protocol: 'accessing',
|
|
|
|
+fn: function (){
|
|
|
|
+var self=this;
|
|
|
|
+return smalltalk.withContext(function($ctx1) {
|
|
|
|
+var $1;
|
|
|
|
+$1=self["@lastSection"];
|
|
|
|
+return $1;
|
|
|
|
+}, function($ctx1) {$ctx1.fill(self,"lastSection",{},smalltalk.Importer)})},
|
|
|
|
+args: [],
|
|
|
|
+source: "lastSection\x0a\x09^ lastSection",
|
|
|
|
+messageSends: [],
|
|
|
|
+referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.Importer);
|
|
smalltalk.Importer);
|
|
|
|
|