From 23d767231388bf304d6269149649c55dfc7caaa4 Mon Sep 17 00:00:00 2001 From: Christopher Bertels Date: Sun, 3 Jun 2012 17:53:52 +0200 Subject: [PATCH] Add initial version of debugger support Use Rubinus::Debugger but provide some fancy-specific output on method names / signatures etc. --- lib/main.fy | 5 +++ lib/rbx.fy | 1 + lib/rbx/compiled_method.fy | 14 ++++++++ lib/rbx/debugger.fy | 72 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 lib/rbx/compiled_method.fy create mode 100644 lib/rbx/debugger.fy diff --git a/lib/main.fy b/lib/main.fy index 5e6ed56b..51bdbfe4 100644 --- a/lib/main.fy +++ b/lib/main.fy @@ -21,6 +21,7 @@ if: (ARGV size == 1) then: { " -e 'command' One line of Fancy code that gets evaluated immediately", " -c [filenames] Compile given files to Rubinius bytecode", " -cv [filenames] Compile given files to Rubinius bytecode verbosely (outputting the generated bytecode)", + " -debug Start the Rubinius Debugger with Fancy", "", "Fancy package management:", " install [packagename] Install a Fancy package with a given name to $FANCYPACK_DIR", @@ -65,6 +66,10 @@ ARGV for_option: "-cv" do: { System exit } +ARGV for_option: "-debug" do: { + require: "rbx/debugger" +} + ARGV for_option: "install" do: |package_name| { match package_name { case "--deps" -> Fancy Package install_dependencies diff --git a/lib/rbx.fy b/lib/rbx.fy index ca885404..7a760a36 100644 --- a/lib/rbx.fy +++ b/lib/rbx.fy @@ -42,3 +42,4 @@ require: "rbx/actor" require: "rbx/mutex" require: "rbx/module" require: "rbx/proc" +require: "rbx/compiled_method" diff --git a/lib/rbx/compiled_method.fy b/lib/rbx/compiled_method.fy new file mode 100644 index 00000000..9d065df0 --- /dev/null +++ b/lib/rbx/compiled_method.fy @@ -0,0 +1,14 @@ +class Rubinius CompiledMethod { + forwards_unary_ruby_methods + + def selectors_with_args { + local_names = local_names to_a + if: (required_args > 0) then: { + name to_s split: ":" . map_with_index: |sel i| { + "#{sel}: #{local_names[i]}" + } . join: " " + } else: { + name to_s rest + } + } +} diff --git a/lib/rbx/debugger.fy b/lib/rbx/debugger.fy new file mode 100644 index 00000000..33f0f89b --- /dev/null +++ b/lib/rbx/debugger.fy @@ -0,0 +1,72 @@ +require("rubinius/debugger") + +class Rubinius Debugger { + forwards_unary_ruby_methods + metaclass forwards_unary_ruby_methods +} + +class Rubinius Debugger Command SetBreakPoint { + def match_method: method_identifier { + match method_identifier { + case /##/ -> + class_name, method_name = method_identifier split: "##" + method_identifier = "#{class_name}::#{method_name message_name}" + case /#/ -> + class_name, method_name = method_identifier split: "#" + method_identifier = "#{class_name}##{method_name message_name}" + } + + /([A-Z]\w*(?:::[A-Z]\w*)*)([.#]|::)([a-zA-Z0-9_\[\]:]+[!?=]?)(?:[:](\d+))?/ match: method_identifier + } + + alias_method('match_method, 'match_method:) +} + +class Rubinius Location { + forwards_unary_ruby_methods +} + +class Rubinius Debugger Frame { + forwards_unary_ruby_methods + + def describe { + arg_str = "" + recv = nil + signature = method selectors_with_args + + loc = @location + + if: (loc is_block) then: { + if: (method required_args == 0) then: { + recv = "{ } in #{loc describe_receiver}#{loc name}" + } else: { + block_args = method local_names join: ", " + recv = "|#{block_args}| { } in #{loc describe_receiver}#{loc name}" + } + } else: { + if: (method required_args == 0) then: { + recv = loc describe + } else: { + recv = "#{loc describe}" + } + } + + recv = recv replace: "#:" with: "#" + recv = recv replace: ".:" with: "##" + recv = recv replace: "." with: "##" + + str = "#{recv} at #{loc method active_path}:#{loc line} (#{loc ip})" + { str << " (+#{loc ip})" } if: $ @debugger variables['show_ip] + str + } + + alias_method('describe, ':describe) + + def run: code { + Fancy eval: (code to_s) binding: binding + } + + alias_method('run, 'run:) +} + +Rubinius Debugger start \ No newline at end of file