feat(boards): 更新python_skulpt debugger

This commit is contained in:
王立帮
2025-04-04 00:16:04 +08:00
parent 535d1fe788
commit 69633451e0

View File

@@ -1,8 +1,7 @@
/** /**
* Debugger support for skulpt module * Debugger support for skulpt module
*/ */
import './skulpt.min.js';
var Sk = Sk || {}; //jshint ignore:line
function hasOwnProperty(obj, prop) { function hasOwnProperty(obj, prop) {
var proto = obj.constructor.prototype; var proto = obj.constructor.prototype;
@@ -10,15 +9,18 @@ function hasOwnProperty(obj, prop) {
(!(prop in proto) || proto[prop] !== obj[prop]); (!(prop in proto) || proto[prop] !== obj[prop]);
} }
Sk.Breakpoint = function(filename, lineno, colno) { class Breakpoint {
constructor(filename, lineno, colno) {
this.filename = filename; this.filename = filename;
this.lineno = lineno; this.lineno = lineno;
this.colno = colno; this.colno = colno;
this.enabled = true; this.enabled = true;
this.ignore_count = 0; this.ignore_count = 0;
}; }
}
Sk.Debugger = function(filename, output_callback) { export default class Debugger {
constructor(filename, output_callback) {
this.dbg_breakpoints = {}; this.dbg_breakpoints = {};
this.tmp_breakpoints = {}; this.tmp_breakpoints = {};
this.suspension_stack = []; this.suspension_stack = [];
@@ -28,56 +30,56 @@ Sk.Debugger = function(filename, output_callback) {
this.output_callback = output_callback; this.output_callback = output_callback;
this.step_mode = false; this.step_mode = false;
this.filename = filename; this.filename = filename;
}; }
Sk.Debugger.prototype.print = function(txt) { print(txt) {
if (this.output_callback != null) { if (this.output_callback != null) {
this.output_callback.print(txt); this.output_callback.print(txt);
} }
}; }
Sk.Debugger.prototype.get_source_line = function(lineno) { get_source_line(lineno) {
if (this.output_callback != null) { if (this.output_callback != null) {
return this.output_callback.get_source_line(lineno); return this.output_callback.get_source_line(lineno);
} }
return ""; return "";
}; }
Sk.Debugger.prototype.move_up_the_stack = function() { move_up_the_stack() {
this.current_suspension = Math.min(this.current_suspension + 1, this.suspension_stack.length - 1); this.current_suspension = Math.min(this.current_suspension + 1, this.suspension_stack.length - 1);
}; }
Sk.Debugger.prototype.move_down_the_stack = function() { move_down_the_stack() {
this.current_suspension = Math.max(this.current_suspension - 1, 0); this.current_suspension = Math.max(this.current_suspension - 1, 0);
}; }
Sk.Debugger.prototype.enable_step_mode = function() { enable_step_mode() {
this.step_mode = true; this.step_mode = true;
}; }
Sk.Debugger.prototype.disable_step_mode = function() { disable_step_mode() {
this.step_mode = false; this.step_mode = false;
}; }
Sk.Debugger.prototype.get_suspension_stack = function() { get_suspension_stack() {
return this.suspension_stack; return this.suspension_stack;
}; }
Sk.Debugger.prototype.get_active_suspension = function() { get_active_suspension() {
if (this.suspension_stack.length === 0) { if (this.suspension_stack.length === 0) {
return null; return null;
} }
return this.suspension_stack[this.current_suspension]; return this.suspension_stack[this.current_suspension];
}; }
Sk.Debugger.prototype.generate_breakpoint_key = function(filename, lineno, colno) { generate_breakpoint_key(filename, lineno) {
var key = filename + "-" + lineno; var key = filename + "-" + lineno;
return key; return key;
}; }
Sk.Debugger.prototype.check_breakpoints = function(filename, lineno, colno, globals, locals) { check_breakpoints(filename, lineno, colno) {
// If Step mode is enabled then ignore breakpoints since we will just break // If Step mode is enabled then ignore breakpoints since we will just break
// at every line. // at every line.
if (this.step_mode === true) { if (this.step_mode === true) {
@@ -100,71 +102,69 @@ Sk.Debugger.prototype.check_breakpoints = function(filename, lineno, colno, glob
bp = this.dbg_breakpoints[key]; bp = this.dbg_breakpoints[key];
if (bp.ignore_count === 0) { if (bp.ignore_count === 0) {
return true; return true;
} else {
return false;
}
} }
return false; return false;
}; }
return false;
}
Sk.Debugger.prototype.get_breakpoints_list = function() { get_breakpoints_list() {
return this.dbg_breakpoints; return this.dbg_breakpoints;
}; }
Sk.Debugger.prototype.disable_breakpoint = function(filename, lineno, colno) { disable_breakpoint(filename, lineno, colno) {
var key = this.generate_breakpoint_key(filename, lineno, colno); var key = this.generate_breakpoint_key(filename, lineno, colno);
if (hasOwnProperty(this.dbg_breakpoints, key)) { if (hasOwnProperty(this.dbg_breakpoints, key)) {
this.dbg_breakpoints[key].enabled = false; this.dbg_breakpoints[key].enabled = false;
} }
}; }
Sk.Debugger.prototype.enable_breakpoint = function(filename, lineno, colno) { enable_breakpoint(filename, lineno, colno) {
var key = this.generate_breakpoint_key(filename, lineno, colno); var key = this.generate_breakpoint_key(filename, lineno, colno);
if (hasOwnProperty(this.dbg_breakpoints, key)) { if (hasOwnProperty(this.dbg_breakpoints, key)) {
this.dbg_breakpoints[key].enabled = true; this.dbg_breakpoints[key].enabled = true;
} }
}; }
Sk.Debugger.prototype.clear_breakpoint = function(filename, lineno, colno) { clear_breakpoint(filename, lineno, colno) {
var key = this.generate_breakpoint_key(filename, lineno, colno); var key = this.generate_breakpoint_key(filename, lineno, colno);
if (hasOwnProperty(this.dbg_breakpoints, key)) { if (hasOwnProperty(this.dbg_breakpoints, key)) {
delete this.dbg_breakpoints[key]; delete this.dbg_breakpoints[key];
return null; return null;
} else { }
return "Invalid breakpoint specified: " + filename + " line: " + lineno; return "Invalid breakpoint specified: " + filename + " line: " + lineno;
} }
};
Sk.Debugger.prototype.clear_all_breakpoints = function() { clear_all_breakpoints() {
this.dbg_breakpoints = {}; this.dbg_breakpoints = {};
this.tmp_breakpoints = {}; this.tmp_breakpoints = {};
}; }
Sk.Debugger.prototype.set_ignore_count = function(filename, lineno, colno, count) { set_ignore_count(filename, lineno, colno, count) {
var key = this.generate_breakpoint_key(filename, lineno, colno); var key = this.generate_breakpoint_key(filename, lineno, colno);
if (hasOwnProperty(this.dbg_breakpoints, key)) { if (hasOwnProperty(this.dbg_breakpoints, key)) {
var bp = this.dbg_breakpoints[key]; var bp = this.dbg_breakpoints[key];
bp.ignore_count = count; bp.ignore_count = count;
} }
}; }
Sk.Debugger.prototype.set_condition = function(filename, lineno, colno, lhs, cond, rhs) { set_condition(filename, lineno, colno, lhs, cond, rhs) {
var key = this.generate_breakpoint_key(filename, lineno, colno); var key = this.generate_breakpoint_key(filename, lineno, colno);
var bp; var bp;
if (hasOwnProperty(this.dbg_breakpoints, key)) { if (hasOwnProperty(this.dbg_breakpoints, key)) {
// Set a new condition // Set a new condition
bp = this.dbg_breakpoints[key]; bp = this.dbg_breakpoints[key];
} else { } else {
bp = new Sk.Breakpoint(filename, lineno, colno); bp = new Breakpoint(filename, lineno, colno);
} }
bp.condition = new Sk.Condition(lhs, cond, rhs); bp.condition = new window.Sk.Condition(lhs, cond, rhs);
this.dbg_breakpoints[key] = bp; this.dbg_breakpoints[key] = bp;
}; }
Sk.Debugger.prototype.print_suspension_info = function(suspension) { print_suspension_info(suspension) {
var filename = suspension.filename; var filename = suspension.filename;
var lineno = suspension.lineno; var lineno = suspension.lineno;
var colno = suspension.colno; var colno = suspension.colno;
@@ -172,11 +172,11 @@ Sk.Debugger.prototype.print_suspension_info = function(suspension) {
this.print("----------------------------------------------------------------------------------\n"); this.print("----------------------------------------------------------------------------------\n");
this.print(" ==> " + this.get_source_line(lineno - 1) + "\n"); this.print(" ==> " + this.get_source_line(lineno - 1) + "\n");
this.print("----------------------------------------------------------------------------------\n"); this.print("----------------------------------------------------------------------------------\n");
}; }
Sk.Debugger.prototype.set_suspension = function(suspension) { set_suspension(suspension) {
var parent = null; var parent = null;
if (!hasOwnProperty(suspension, "filename") && suspension.child instanceof Sk.misceval.Suspension) { if (!hasOwnProperty(suspension, "filename") && suspension.child instanceof window.Sk.misceval.Suspension) {
suspension = suspension.child; suspension = suspension.child;
} }
@@ -187,7 +187,7 @@ Sk.Debugger.prototype.set_suspension = function(suspension) {
} }
// Unroll the stack to get each suspension. // Unroll the stack to get each suspension.
while (suspension instanceof Sk.misceval.Suspension) { while (suspension instanceof window.Sk.misceval.Suspension) {
parent = suspension; parent = suspension;
this.suspension_stack.push(parent); this.suspension_stack.push(parent);
this.current_suspension += 1; this.current_suspension += 1;
@@ -197,27 +197,27 @@ Sk.Debugger.prototype.set_suspension = function(suspension) {
suspension = parent; suspension = parent;
this.print_suspension_info(suspension); this.print_suspension_info(suspension);
}; }
Sk.Debugger.prototype.add_breakpoint = function(filename, lineno, colno, temporary) { add_breakpoint(filename, lineno, colno, temporary) {
var key = this.generate_breakpoint_key(filename, lineno, colno); var key = this.generate_breakpoint_key(filename, lineno, colno);
this.dbg_breakpoints[key] = new Sk.Breakpoint(filename, lineno, colno); this.dbg_breakpoints[key] = new Breakpoint(filename, lineno, colno);
if (temporary) { if (temporary) {
this.tmp_breakpoints[key] = true; this.tmp_breakpoints[key] = true;
} }
}; }
Sk.Debugger.prototype.suspension_handler = function(susp) { suspension_handler(susp) {
return new Promise(function(resolve, reject) { return new Promise(function (resolve, reject) {
try { try {
resolve(susp.resume()); resolve(susp.resume());
} catch(e) { } catch (e) {
reject(e); reject(e);
} }
}); });
}; }
Sk.Debugger.prototype.resume = function() { resume() {
// Reset the suspension stack to the topmost // Reset the suspension stack to the topmost
this.current_suspension = this.suspension_stack.length - 1; this.current_suspension = this.suspension_stack.length - 1;
@@ -227,15 +227,15 @@ Sk.Debugger.prototype.resume = function() {
var promise = this.suspension_handler(this.get_active_suspension()); var promise = this.suspension_handler(this.get_active_suspension());
promise.then(this.success.bind(this), this.error.bind(this)); promise.then(this.success.bind(this), this.error.bind(this));
} }
}; }
Sk.Debugger.prototype.pop_suspension_stack = function() { pop_suspension_stack() {
this.suspension_stack.pop(); this.suspension_stack.pop();
this.current_suspension -= 1; this.current_suspension -= 1;
}; }
Sk.Debugger.prototype.success = function(r) { success(r) {
if (r instanceof Sk.misceval.Suspension) { if (r instanceof window.Sk.misceval.Suspension) {
this.set_suspension(r); this.set_suspension(r);
} else { } else {
if (this.suspension_stack.length > 0) { if (this.suspension_stack.length > 0) {
@@ -250,7 +250,7 @@ Sk.Debugger.prototype.success = function(r) {
var parent_suspension = this.get_active_suspension(); var parent_suspension = this.get_active_suspension();
// The child has completed the execution. So override the child's resume // The child has completed the execution. So override the child's resume
// so we can continue the execution. // so we can continue the execution.
parent_suspension.child.resume = function() { parent_suspension.child.resume = function () {
return r; return r;
}; };
this.resume(); this.resume();
@@ -258,9 +258,9 @@ Sk.Debugger.prototype.success = function(r) {
this.print("Program execution complete"); this.print("Program execution complete");
} }
} }
}; }
Sk.Debugger.prototype.error = function(e) { error(e) {
this.print("Traceback (most recent call last):"); this.print("Traceback (most recent call last):");
for (var idx = 0; idx < e.traceback.length; ++idx) { for (var idx = 0; idx < e.traceback.length; ++idx) {
this.print(" File \"" + e.traceback[idx].filename + "\", line " + e.traceback[idx].lineno + ", in <module>"); this.print(" File \"" + e.traceback[idx].filename + "\", line " + e.traceback[idx].lineno + ", in <module>");
@@ -274,22 +274,22 @@ Sk.Debugger.prototype.error = function(e) {
for (idx = 0; idx < e.args.v.length; ++idx) { for (idx = 0; idx < e.args.v.length; ++idx) {
this.print(err_ty + ": " + e.args.v[idx].v); this.print(err_ty + ": " + e.args.v[idx].v);
} }
}; }
Sk.Debugger.prototype.asyncToPromise = function(suspendablefn, suspHandlers, debugger_obj) { asyncToPromise(suspendablefn, suspHandlers, debugger_obj) {
return new Promise(function(resolve, reject) { return new Promise(function (resolve, reject) {
try { try {
var r = suspendablefn(); var r = suspendablefn();
(function handleResponse (r) { (function handleResponse(r) {
try { try {
while (r instanceof Sk.misceval.Suspension) { while (r instanceof window.Sk.misceval.Suspension) {
debugger_obj.set_suspension(r); debugger_obj.set_suspension(r);
return; return;
} }
resolve(r); resolve(r);
} catch(e) { } catch (e) {
reject(e); reject(e);
} }
})(r); })(r);
@@ -298,15 +298,14 @@ Sk.Debugger.prototype.asyncToPromise = function(suspendablefn, suspHandlers, deb
reject(e); reject(e);
} }
}); });
}; }
Sk.Debugger.prototype.execute = function(suspendablefn, suspHandlers) { execute(suspendablefn) {
var r = suspendablefn(); var r = suspendablefn();
if (r instanceof Sk.misceval.Suspension) { if (r instanceof window.Sk.misceval.Suspension) {
this.suspensions.concat(r); this.suspensions.concat(r);
this.eval_callback(r); this.eval_callback(r);
} }
}; }
}
goog.exportSymbol("Sk.Debugger", Sk.Debugger);