Browse Source

Adds a skip button to the debugger

Nicolas Petton 10 years ago
parent
commit
d558b520a8
4 changed files with 114 additions and 12 deletions
  1. 31 3
      js/Compiler-Interpreter.js
  2. 54 4
      js/Helios-Debugger.js
  3. 13 4
      st/Compiler-Interpreter.st
  4. 16 1
      st/Helios-Debugger.st

+ 31 - 3
js/Compiler-Interpreter.js

@@ -930,7 +930,7 @@ smalltalk.AIContext.klass);
 
 
 smalltalk.addClass('ASTDebugger', smalltalk.Object, ['interpreter', 'context'], 'Compiler-Interpreter');
-smalltalk.ASTDebugger.comment="I am a stepping debugger interface for Amber code.\x0aI internally use an instance of `ASTSteppingInterpreter` to actually step through node and interpret them.\x0a\x0aMy instances are created from a `MethodContext` with `ASTDebugger class >> context:`.\x0aThey hold an `AIContext` instance internally, recursive copy of the `MethodContext`.\x0a\x0a## API\x0a\x0aUse the methods of the `'stepping'` protocol to do stepping.";
+smalltalk.ASTDebugger.comment="I am a stepping debugger interface for Amber code.\x0aI internally use an instance of `ASTInterpreter` to actually step through node and interpret them.\x0a\x0aMy instances are created from an `AIContext` with `ASTDebugger class >> context:`.\x0aThey hold an `AIContext` instance internally, recursive copy of the `MethodContext`.\x0a\x0a## API\x0a\x0aUse the methods of the `'stepping'` protocol to do stepping.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "atEnd",
@@ -1173,6 +1173,22 @@ referencedClasses: []
 }),
 smalltalk.ASTDebugger);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "skip",
+category: 'stepping',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._interpreter())._skip();
+return self}, function($ctx1) {$ctx1.fill(self,"skip",{},smalltalk.ASTDebugger)})},
+args: [],
+source: "skip\x0a\x09self interpreter skip",
+messageSends: ["skip", "interpreter"],
+referencedClasses: []
+}),
+smalltalk.ASTDebugger);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "stepInto",
@@ -1572,6 +1588,7 @@ category: 'interpreting',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._atEnd();
@@ -1579,10 +1596,21 @@ return self._atEnd();
 return smalltalk.withContext(function($ctx2) {
 return self._step();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
+$1=_st(self._context())._outerContext();
+if(($receiver = $1) == nil || $receiver == null){
+$1;
+} else {
+var outer;
+outer=$receiver;
+$2=_st(outer)._interpreter();
+_st($2)._skip();
+$3=_st($2)._proceed();
+$3;
+};
 return self}, function($ctx1) {$ctx1.fill(self,"proceed",{},smalltalk.ASTInterpreter)})},
 args: [],
-source: "proceed\x0a\x09\x22Eagerly evaluate the ast\x22\x0a\x09\x0a\x09[ self atEnd ] whileFalse: [ \x0a\x09\x09self step ]",
-messageSends: ["whileFalse:", "atEnd", "step"],
+source: "proceed\x0a\x09\x22Eagerly evaluate the ast\x22\x0a\x09\x0a\x09[ self atEnd ] \x0a\x09\x09whileFalse: [ self step ].\x0a\x09\x09\x0a\x09self context outerContext ifNotNil: [ :outer |\x0a\x09\x09outer interpreter \x0a\x09\x09\x09skip; \x22current send node already evaluated by the receiver\x22 \x0a\x09\x09\x09proceed ]",
+messageSends: ["whileFalse:", "atEnd", "step", "ifNotNil:", "outerContext", "context", "skip", "interpreter", "proceed"],
 referencedClasses: []
 }),
 smalltalk.ASTInterpreter);

+ 54 - 4
js/Helios-Debugger.js

@@ -809,6 +809,28 @@ referencedClasses: []
 }),
 smalltalk.HLDebuggerModel);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "skip",
+category: 'actions',
+fn: function (){
+var self=this;
+function $HLDebuggerStepped(){return smalltalk.HLDebuggerStepped||(typeof HLDebuggerStepped=="undefined"?nil:HLDebuggerStepped)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+_st(self._interpreter())._skip();
+$1=_st($HLDebuggerStepped())._new();
+_st($1)._context_(self._currentContext());
+$2=_st($1)._yourself();
+_st(self._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"skip",{},smalltalk.HLDebuggerModel)})},
+args: [],
+source: "skip\x0a\x09self interpreter skip.\x0a\x09self announcer announce: (HLDebuggerStepped new\x0a\x09\x09context: self currentContext;\x0a\x09\x09yourself)",
+messageSends: ["skip", "interpreter", "announce:", "announcer", "context:", "new", "currentContext", "yourself"],
+referencedClasses: ["HLDebuggerStepped"]
+}),
+smalltalk.HLDebuggerModel);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "stepOver",
@@ -986,7 +1008,7 @@ category: 'rendering',
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$3,$4,$5,$6,$7,$8,$2;
+var $1,$3,$4,$5,$6,$7,$8,$9,$10,$2;
 $1=_st(html)._div();
 _st($1)._class_("debugger_bar");
 $ctx1.sendIdx["class:"]=1;
@@ -1017,19 +1039,31 @@ return self._where();
 $ctx2.sendIdx["onClick:"]=2;
 $6;
 $7=_st(html)._button();
+$ctx2.sendIdx["button"]=3;
 _st($7)._class_("btn stepOver");
+$ctx2.sendIdx["class:"]=4;
 _st($7)._with_("Step over");
+$ctx2.sendIdx["with:"]=4;
 $8=_st($7)._onClick_((function(){
 return smalltalk.withContext(function($ctx3) {
 return self._stepOver();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,4)})}));
-return $8;
+$ctx2.sendIdx["onClick:"]=3;
+$8;
+$9=_st(html)._button();
+_st($9)._class_("btn skip");
+_st($9)._with_("Skip");
+$10=_st($9)._onClick_((function(){
+return smalltalk.withContext(function($ctx3) {
+return self._skip();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,5)})}));
+return $10;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 $ctx1.sendIdx["with:"]=1;
 return self}, function($ctx1) {$ctx1.fill(self,"renderButtonsOn:",{html:html},smalltalk.HLStackListWidget)})},
 args: ["html"],
-source: "renderButtonsOn: html\x0a\x09html div \x0a\x09\x09class: 'debugger_bar'; \x0a\x09\x09with: [\x0a\x09\x09\x09html button \x0a\x09\x09\x09\x09class: 'btn restart';\x0a\x09\x09\x09\x09with: 'Restart';\x0a\x09\x09\x09\x09onClick: [ self restart ].\x0a\x09\x09\x09html button \x0a\x09\x09\x09\x09class: 'btn where';\x0a\x09\x09\x09\x09with: 'Where';\x0a\x09\x09\x09\x09onClick: [ self where ].\x0a\x09\x09\x09html button \x0a\x09\x09\x09\x09class: 'btn stepOver';\x0a\x09\x09\x09\x09with: 'Step over';\x0a\x09\x09\x09\x09onClick: [ self stepOver ] ]",
-messageSends: ["class:", "div", "with:", "button", "onClick:", "restart", "where", "stepOver"],
+source: "renderButtonsOn: html\x0a\x09html div \x0a\x09\x09class: 'debugger_bar'; \x0a\x09\x09with: [\x0a\x09\x09\x09html button \x0a\x09\x09\x09\x09class: 'btn restart';\x0a\x09\x09\x09\x09with: 'Restart';\x0a\x09\x09\x09\x09onClick: [ self restart ].\x0a\x09\x09\x09html button \x0a\x09\x09\x09\x09class: 'btn where';\x0a\x09\x09\x09\x09with: 'Where';\x0a\x09\x09\x09\x09onClick: [ self where ].\x0a\x09\x09\x09html button \x0a\x09\x09\x09\x09class: 'btn stepOver';\x0a\x09\x09\x09\x09with: 'Step over';\x0a\x09\x09\x09\x09onClick: [ self stepOver ].\x0a\x09\x09\x09html button \x0a\x09\x09\x09\x09class: 'btn skip';\x0a\x09\x09\x09\x09with: 'Skip';\x0a\x09\x09\x09\x09onClick: [ self skip ] ]",
+messageSends: ["class:", "div", "with:", "button", "onClick:", "restart", "where", "stepOver", "skip"],
 referencedClasses: []
 }),
 smalltalk.HLStackListWidget);
@@ -1066,6 +1100,22 @@ referencedClasses: []
 }),
 smalltalk.HLStackListWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "skip",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._model())._skip();
+return self}, function($ctx1) {$ctx1.fill(self,"skip",{},smalltalk.HLStackListWidget)})},
+args: [],
+source: "skip\x0a\x09self model skip",
+messageSends: ["skip", "model"],
+referencedClasses: []
+}),
+smalltalk.HLStackListWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "stepOver",

+ 13 - 4
st/Compiler-Interpreter.st

@@ -301,9 +301,9 @@ Object subclass: #ASTDebugger
 	package: 'Compiler-Interpreter'!
 !ASTDebugger commentStamp!
 I am a stepping debugger interface for Amber code.
-I internally use an instance of `ASTSteppingInterpreter` to actually step through node and interpret them.
+I internally use an instance of `ASTInterpreter` to actually step through node and interpret them.
 
-My instances are created from a `MethodContext` with `ASTDebugger class >> context:`.
+My instances are created from an `AIContext` with `ASTDebugger class >> context:`.
 They hold an `AIContext` instance internally, recursive copy of the `MethodContext`.
 
 ## API
@@ -385,6 +385,10 @@ restart
 	self interpreter restart
 !
 
+skip
+	self interpreter skip
+!
+
 stepInto
 	self shouldBeImplemented
 !
@@ -482,8 +486,13 @@ next
 proceed
 	"Eagerly evaluate the ast"
 	
-	[ self atEnd ] whileFalse: [ 
-		self step ]
+	[ self atEnd ] 
+		whileFalse: [ self step ].
+		
+	self context outerContext ifNotNil: [ :outer |
+		outer interpreter 
+			skip; "current send node already evaluated by the receiver" 
+			proceed ]
 !
 
 restart

+ 16 - 1
st/Helios-Debugger.st

@@ -269,6 +269,13 @@ restart
 		yourself)
 !
 
+skip
+	self interpreter skip.
+	self announcer announce: (HLDebuggerStepped new
+		context: self currentContext;
+		yourself)
+!
+
 stepOver
 	self interpreter stepOver.
 	self announcer announce: (HLDebuggerStepped new
@@ -364,6 +371,10 @@ selectItem: aContext
    	self model currentContext: aContext
 !
 
+skip
+	self model skip
+!
+
 stepOver
 	self model stepOver
 !
@@ -389,6 +400,10 @@ renderButtonsOn: html
 			html button 
 				class: 'btn stepOver';
 				with: 'Step over';
-				onClick: [ self stepOver ] ]
+				onClick: [ self stepOver ].
+			html button 
+				class: 'btn skip';
+				with: 'Skip';
+				onClick: [ self skip ] ]
 ! !