Permalink
Browse files

Brief structural debugging function

  • Loading branch information...
1 parent cac42af commit ef548b8133c13dfe7086e42f2eca149d90253ea0 @matthewd committed Nov 22, 2010
Showing with 66 additions and 21 deletions.
  1. +4 −2 bin/rasp
  2. +26 −0 lib/rasp/ast.rb
  3. +9 −5 lib/rasp/ast/block.rb
  4. +4 −2 lib/rasp/ast/call.rb
  5. +2 −2 lib/rasp/ast/expression.rb
  6. +10 −7 lib/rasp/ast/flow.rb
  7. +3 −2 lib/rasp/ast/simple.rb
  8. +1 −1 lib/rasp/parser.citrus
  9. +7 −0 lib/rasp/parser.rb
View
@@ -7,11 +7,13 @@ require 'rasp'
filename = File.exist?(ARGV.first) ? ARGV.shift : 't/math.vbs'
parse = Rasp::Parser.parse(File.read(filename), :consume => true)
-parse.value.graph unless ARGV.grep(/^--graph$/).empty?
+ast = parse.value
+
+ast.graph unless ARGV.grep(/^--graph$/).empty?
old_debug, $DEBUG = $DEBUG, !ARGV.grep(/^--decode$/).empty?
begin
- compiled = Rasp::Compiler.new.compile(parse.value, filename)
+ compiled = Rasp::Compiler.new.compile(ast, filename)
ensure
$DEBUG = old_debug
end
View
@@ -32,6 +32,32 @@ def self.list(lhs, ary, attr=:rhs)
end
class Node
+ def self.attr_names
+ @attr_names ||= []
+ end
+ def self.node_attr *names
+ attr_accessor *names
+ attr_names.push *names
+ end
+
+ def node_summary
+ s = ""
+ s << self.class.name.sub(/.*::/, '')
+ unless self.class.attr_names.empty?
+ s << "<"
+ s << self.class.attr_names.map {|x|
+ z = instance_variable_get(:"@#{x}")
+ if Array === z
+ "[#{z.map {|q| q ? q.node_summary : '0' }.join ','}]"
+ else
+ z ? z.node_summary : '0'
+ end
+ }.join(',')
+ s << ">"
+ end
+ s
+ end
+
def graph
Rubinius::AST::AsciiGrapher.new(self, Node).print
end
View
@@ -4,7 +4,7 @@ class File < Node
include Rasp::Compiler::LocalVariables
attr_accessor :compiler
- attr_accessor :statements
+ node_attr :statements
def global; self; end
def explicit?; @explicit; end
def explicit!; @explicit = true; end
@@ -38,7 +38,8 @@ class LocalScope < Node
end
class FunctionDef < Node
- attr_accessor :name, :args, :body
+ attr_accessor :name, :args
+ node_attr :body
def initialize(name, args, body)
@name, @args, @body = name, args, body
end
@@ -49,7 +50,8 @@ def prescan(g)
end
end
class SubDef < Node
- attr_accessor :name, :args, :body
+ attr_accessor :name, :args
+ node_attr :body
def initialize(name, args, body)
@name, @args, @body = name, args, body
end
@@ -60,7 +62,8 @@ def prescan(g)
end
end
class PropertyDef < Node
- attr_accessor :ptype, :name, :args, :body
+ attr_accessor :ptype, :name, :args
+ node_attr :body
def initialize(ptype, name, args, body)
@ptype, @name, @args, @body = ptype, name, args, body
end
@@ -79,7 +82,8 @@ def prescan(g)
class Function < LocalScope
include Rasp::Compiler::LocalVariables
- attr_accessor :name, :args, :body
+ attr_accessor :name, :args
+ node_attr :body
def initialize(name, args, body)
@name, @args, @body = name, args, body
end
@@ -1,7 +1,8 @@
module Rasp::AST
class Call < Node
- attr_accessor :target, :name, :args
+ attr_accessor :name
+ node_attr :target, :args
def initialize(target, name, args)
@target, @name, @args = target, name, args
end
@@ -69,7 +70,8 @@ def bytecode(g)
end
end
class LetCall < Node
- attr_accessor :target, :name, :args, :value
+ attr_accessor :name
+ node_attr :target, :args, :value
def initialize(target, name, args, value)
@target, @name, @args, @value = target, name, args, value
end
@@ -1,7 +1,7 @@
module Rasp::AST
class UnaryOp < Node
- attr_accessor :inner
+ node_attr :inner
def initialize(inner)
@inner = inner
end
@@ -15,7 +15,7 @@ def prescan(g)
end
end
class BinaryOp < Node
- attr_accessor :lhs, :rhs
+ node_attr :lhs, :rhs
def initialize(lhs, rhs)
@lhs, @rhs = lhs, rhs
end
View
@@ -1,7 +1,8 @@
module Rasp::AST
class Loop < Node
- attr_accessor :type, :body
+ attr_accessor :type
+ node_attr :body
def initialize(type, body)
@type, @body = type, body
end
@@ -22,7 +23,7 @@ def prescan(g)
end
end
class DoWhile < Loop
- attr_accessor :condition
+ node_attr :condition
def initialize(type, condition, invert, body)
super(type, body)
@condition = invert ? NotExpr.new(condition) : condition
@@ -74,7 +75,8 @@ class ForLoop < Loop
# Contrary to my original expectation, not having used VBScript in
# ages, all three of (start, finish, step) are fixed at loop start.
- attr_accessor :var, :start, :finish, :step
+ attr_accessor :var
+ node_attr :start, :finish, :step
def initialize(var, start, finish, step, body)
super(:for, body)
@var, @start, @finish, @step = var, start, finish, step
@@ -182,7 +184,8 @@ def prescan(g)
end
end
class ForEachLoop < Loop
- attr_accessor :var, :collection
+ attr_accessor :var
+ node_attr :collection
def initialize(var, collection, body)
super(:for, body)
@var, @collection = var, collection
@@ -199,7 +202,7 @@ def prescan(g)
end
class If < Node
- attr_accessor :condition, :true_body, :false_body
+ node_attr :condition, :true_body, :false_body
def initialize(condition, true_body, false_body)
@condition, @true_body, @false_body = condition, true_body, false_body
end
@@ -242,7 +245,7 @@ def prescan(g)
end
class SelectCase < Container
- attr_accessor :expr, :cases, :else_body
+ node_attr :expr, :cases, :else_body
def initialize(expr, cases, else_body)
@expr, @cases, @else_body = expr, cases, else_body
end
@@ -273,7 +276,7 @@ def prescan(g)
end
end
class Case < Node
- attr_accessor :matches, :body
+ node_attr :matches, :body
def initialize(matches, body)
@matches, @body = matches, body
end
@@ -3,7 +3,8 @@ module Rasp::AST
class Statement < Node
end
class Assignment < Statement
- attr_accessor :var, :newval
+ attr_accessor :var
+ node_attr :newval
def initialize(var, newval)
@var, @newval = var, newval
end
@@ -66,7 +67,7 @@ def prescan(g)
end
end
class Randomize < Statement
- attr_accessor :seed
+ node_attr :seed
def initialize(seed=nil)
@seed = seed
end
@@ -107,7 +107,7 @@ grammar Rasp::Parser
(`if` SP expression SP `then` SP truepart:(single:single_line_if { [single] } | list:simple_statement_chain) (SP `else` SP falsepart:(single:single_line_if | list:simple_statement_chain EOL) | EOL) )
{
false_list = first(:falsepart) && (falsepart.first(:single) ? [falsepart.single.value] : falsepart.list.value)
- Rasp::AST::If.new(expression.value, truepart.value, false_list)
+ Rasp::AST::If.new(expression.value, truepart.value.map {|x| x.value }, false_list)
}
end
rule full_if_block
View
@@ -1,2 +1,9 @@
require 'citrus'
Citrus.load( File.dirname(__FILE__) + '/parser' )
+
+class << Rasp::Parser
+ def read(string, root=nil)
+ self.parse(string, :consume => true, :root => root)
+ end
+end
+

0 comments on commit ef548b8

Please sign in to comment.