class Lisp::Debug
Attributes
eval_in_debug_repl[RW]
interactive[RW]
on_entry[RW]
on_error[RW]
single_step[RW]
target_env[RW]
trace[RW]
Public Class Methods
add_debug_on_entry_impl(args, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 50 def self.add_debug_on_entry_impl(args, env) f = args.car return Lisp::Debug.process_error("the argument to add-debug-on-error has to be a function", env) unless f.function? || f.primitive? self.on_entry.add(f.name) f end
debug_impl(args, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 66 def self.debug_impl(args, env) end
debug_on_entry_impl(args, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 46 def self.debug_on_entry_impl(args, env) Lisp::ConsCell.array_to_list(self.on_entry.to_a.sort.map {|s| Lisp::String.with_value(s) }) end
debug_on_error_impl(args, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 39 def self.debug_on_error_impl(args, env) flag = args.car return Lisp::Debug.process_error("the argument to debug-on-error has to be a boolean", env) unless flag.boolean? self.on_error = flag.value flag end
debug_repl(env)
click to toggle source
# File lib/rubylisp/debug.rb, line 103 def self.debug_repl(env) parser = Lisp::Parser.new puts("Debugging: #{env.current_code[0]}") while line = Readline.readline('D> ', true) if !line.empty? if line[0] == ':' tokens = line[1..-1].split case tokens[0] when '(+' f = func_or_nil(tokens[1], env) self.on_entry.add(f.name) unless f.nil? when '(-' f = func_or_nil(tokens[1], env) self.on_entry.delete(f.name) unless f.nil? when '(' self.on_entry.to_a.sort.each {|f| puts f} when '?' puts "RubyLisp Debugger" puts "-----------------" puts ":(+ func - debug on entry to func" puts ":(- func - don't debug on entry to func" puts ":( - show functions marked as debug on entry" puts ":? - show this command summary" puts ":b - show the environment stack" puts ":c - continue, exiting the debugger" puts ":d - do a full of the environment stack" puts ":e on/off - Enable/disable debug on error" puts ":f frame# - do a full dump of a single environment frame" puts ":q - quit GoLisp" puts ":r sexpr - return from the current evaluation with the specified value" puts ":s - single step (run to the next evaluation)" puts ":t on/off - Enable/disable tracing" puts ":u - continue until the enclosing environment frame is returned to" puts when 'b' env.dump_headers() puts when 'c' self.target_env = nil self.single_step = false self.eval_in_debug_repl = false return when 'd' env.dump when 'e' ok, state = process_state(tokens) self.on_error = state if ok when 'f' if tokens.size != 2 puts "Missing frame number." else fnum = tokens[1].to_i env.dump_single_frame(fnum) end when 'q' exit() when 'r' self.eval_in_debug_repl = true code = parser.parse(tokens[1..-1].join(' ')) return_value = code.evaluate(env) self.eval_in_debug_repl = false self.target_env = nil self.single_step = false self.eval_in_debug_repl = false return return_value when 's' self.single_step = true return when 't' ok, state = process_state(tokens) self.trace = state if ok when 'u' if env.previous.nil? puts "Already at top frame." else self.target_env = env return end end else begin self.eval_in_debug_repl = true code = parser.parse(line) value = code.evaluate(env) self.eval_in_debug_repl = false puts value.to_s rescue Exception => ex puts "ERROR: #{ex}" puts ex.backtrace end end end end end
debug_trace_impl(args, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 32 def self.debug_trace_impl(args, env) flag = args.car return Lisp::Debug.process_error("the argument to debug-trace has to be a boolean", env) unless flag.boolean? self.trace = flag.value flag end
dump_impl(args, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 69 def self.dump_impl(args, env) env.dump() end
log_eval(sexpr, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 213 def self.log_eval(sexpr, env) if !self.eval_in_debug_repl && self.trace depth = env.depth print("% #d: " % depth) print_dashes(depth) puts("> #{sexpr.to_s}") end end
log_result(result, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 223 def self.log_result(result, env) if !self.eval_in_debug_repl && self.trace depth = env.depth print("% #d: <" % depth) print_dashes(depth) puts(" #{result.to_s}") end end
print_dashes(level)
click to toggle source
# File lib/rubylisp/debug.rb, line 208 def self.print_dashes(level) print("-" * level) end
process_error(error_message, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 198 def self.process_error(error_message, env) if self.on_error && self.interactive puts "ERROR: #{error_message}" self.debug_repl(env) else raise error_message end end
process_state(tokens)
click to toggle source
# File lib/rubylisp/debug.rb, line 74 def self.process_state(tokens) if tokens.size != 2 puts "Missing on/off" [false, false] else case tokens[1] when 'on' [true, true] when 'off' [true, false] else puts "on/off expected." [false, false] end end end
register()
click to toggle source
# File lib/rubylisp/debug.rb, line 15 def self.register self.trace = false self.on_error = false self.on_entry = Set.new self.single_step = false self.interactive = false Primitive.register("debug-trace", "1") {|args, env| Lisp::Debug::debug_trace_impl(args, env) } Primitive.register("debug-on-error", "1") {|args, env| Lisp::Debug::debug_on_error_impl(args, env) } Primitive.register("debug-on-entry", "0") {|args, env| Lisp::Debug::debug_on_entry_impl(args, env) } Primitive.register("add-debug-on-entry", "1") {|args, env| Lisp::Debug::add_debug_on_entry_impl(args, env) } Primitive.register("remove-debug-on-entry", "1") {|args, env| Lisp::Debug::remove_debug_on_entry_impl(args, env) } Primitive.register("debug", "0") {|args, env| Lisp::Debug::debug_impl(args, env) } Primitive.register("dump", "0") {|args, env| Lisp::Debug::dump_imp2l(args, env) } end
remove_debug_on_entry_impl(args, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 58 def self.remove_debug_on_entry_impl(args, env) f = args.car return Lisp::Debug.process_error("the argument to remove-debug-on-error has to be a function", env) unless f.function? self.on_entry.remove(f.name) f end
Public Instance Methods
func_or_nil(fname, env)
click to toggle source
# File lib/rubylisp/debug.rb, line 92 def func_or_nil(fname, env) f = env.value_of(Lisp::Symbol.named(fname)) if f.nil? || !f.function? puts "No such function." nil else f end end