Class: Mirah::Transform::Transformer
- Inherits:
-
Object
- Object
- Mirah::Transform::Transformer
- Defined in:
- lib/mirah/transform/transformer.rb
Defined Under Namespace
Classes: JMetaPosition
Instance Attribute Summary collapse
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#filename ⇒ Object
Returns the value of attribute filename.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Instance Method Summary collapse
- #__ruby_eval(code, arg) ⇒ Object
- #add_annotation(annotation) ⇒ Object
- #annotations ⇒ Object
- #append_node(node) ⇒ Object
- #body(parent = nil) ⇒ Object
- #camelize(name) ⇒ Object
- #captured?(node) ⇒ Boolean
- #cast(type, value) ⇒ Object
- #constant(name, array = false) ⇒ Object
- #define_class(position, name, &block) ⇒ Object
- #define_closure(position, name, enclosing_type) ⇒ Object
- #defineClass(name, superclass = nil, interfaces = nil) ⇒ Object
- #destination ⇒ Object
- #dump_ast(node, call = nil) ⇒ Object
- #empty_array(type_node, size_node) ⇒ Object
- #eval(src, filename = '-', parent = nil, *vars) ⇒ Object
- #expand(fvcall, parent) ⇒ Object
- #find_class(name) ⇒ Object
- #fixnum(value) ⇒ Object
-
#initialize(state) ⇒ Transformer
constructor
A new instance of Transformer.
- #load_ast(args) ⇒ Object
- #position(node) ⇒ Object
- #string(value) ⇒ Object
- #tmp(format = "__xform_tmp_%d") ⇒ Object
- #transform(node, parent) ⇒ Object
- #verbose? ⇒ Boolean
Constructor Details
#initialize(state) ⇒ Transformer
Returns a new instance of Transformer.
13 14 15 16 17 18 19 20 21 |
# File 'lib/mirah/transform/transformer.rb', line 13 def initialize(state) @errors = [] @tmp_count = 0 @annotations = [] @scopes = [] @extra_body = nil @state = state @helper = Mirah::Transform::Helper.new(self) end |
Instance Attribute Details
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
11 12 13 |
# File 'lib/mirah/transform/transformer.rb', line 11 def errors @errors end |
#filename ⇒ Object
Returns the value of attribute filename.
12 13 14 |
# File 'lib/mirah/transform/transformer.rb', line 12 def filename @filename end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
11 12 13 |
# File 'lib/mirah/transform/transformer.rb', line 11 def state @state end |
Instance Method Details
#__ruby_eval(code, arg) ⇒ Object
168 169 170 |
# File 'lib/mirah/transform/transformer.rb', line 168 def __ruby_eval(code, arg) self.instance_eval(code) end |
#add_annotation(annotation) ⇒ Object
36 37 38 39 |
# File 'lib/mirah/transform/transformer.rb', line 36 def add_annotation(annotation) @annotations << annotation Mirah::AST::Noop.new(annotation.parent, annotation.position) end |
#annotations ⇒ Object
31 32 33 34 |
# File 'lib/mirah/transform/transformer.rb', line 31 def annotations result, @annotations = @annotations, [] return result end |
#append_node(node) ⇒ Object
220 221 222 223 |
# File 'lib/mirah/transform/transformer.rb', line 220 def append_node(node) @extra_body << node node end |
#body(parent = nil) ⇒ Object
240 241 242 243 |
# File 'lib/mirah/transform/transformer.rb', line 240 def body(parent=nil) parent ||= @extra_body Mirah::AST::Body.new(parent, parent.position) end |
#camelize(name) ⇒ Object
70 71 72 |
# File 'lib/mirah/transform/transformer.rb', line 70 def camelize(name) name.gsub(/([a-z])([A-Z])/, '\1_\2').downcase end |
#captured?(node) ⇒ Boolean
106 107 108 109 110 111 112 113 114 |
# File 'lib/mirah/transform/transformer.rb', line 106 def captured?(node) depth = node.depth scope = @scopes[-1] while depth > 0 depth -= 1 scope = scope.enclosing_scope end scope.isCaptured(node.index) end |
#cast(type, value) ⇒ Object
185 186 187 188 189 190 191 192 193 |
# File 'lib/mirah/transform/transformer.rb', line 185 def cast(type, value) if value.kind_of?(String) value = Mirah::AST::Local.new(@extra_body, @extra_body.position, value) end fcall = eval("Foo()") fcall.name = type fcall.parameters = [value] fcall end |
#constant(name, array = false) ⇒ Object
178 179 180 181 182 183 |
# File 'lib/mirah/transform/transformer.rb', line 178 def constant(name, array=false) node = eval("Foo") node.name = name node.array = array node end |
#define_class(position, name, &block) ⇒ Object
225 226 227 |
# File 'lib/mirah/transform/transformer.rb', line 225 def define_class(position, name, &block) append_node Mirah::AST::ClassDefinition.new(@extra_body, position, name, &block) end |
#define_closure(position, name, enclosing_type) ⇒ Object
245 246 247 248 249 250 251 252 253 254 |
# File 'lib/mirah/transform/transformer.rb', line 245 def define_closure(position, name, enclosing_type) target = self parent = @extra_body enclosing_type = enclosing_type. if enclosing_type.respond_to?(:node) && enclosing_type.node parent = target = enclosing_type.node end target.append_node(Mirah::AST::ClosureDefinition.new( parent, position, name, enclosing_type)) end |
#defineClass(name, superclass = nil, interfaces = nil) ⇒ Object
229 230 231 232 233 234 235 236 237 238 |
# File 'lib/mirah/transform/transformer.rb', line 229 def defineClass(name, superclass=nil, interfaces=nil) define_class(@extra_body.position, name) do |class_def| superclass = Mirah::AST::Constant.new(class_def, class_def.position, superclass) superclass.parent = class_def if interfaces class_def.implements(*interfaces.map {|i| Mirah::AST::Constant.new(class_def, class_def.position, i)}) end [superclass, body(class_def)] end end |
#destination ⇒ Object
23 24 25 |
# File 'lib/mirah/transform/transformer.rb', line 23 def destination @state.destination end |
#dump_ast(node, call = nil) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/mirah/transform/transformer.rb', line 123 def dump_ast(node, call=nil) encoded = nil values = Mirah::AST::Unquote.extract_values do encoded = Base64.encode64(Marshal.dump(node)) end scope = call.scope.static_scope if call result = Mirah::AST::Array.new(nil, node.position) if encoded.size < 65535 result << Mirah::AST::String.new(result, node.position, encoded) else strings = Mirah::AST::StringConcat.new(result, node.position) result << strings while encoded.size >= 65535 chunk = encoded[0, 65535] encoded[0, 65535] = "" strings << Mirah::AST::String.new(strings, node.position, chunk) end strings << Mirah::AST::String.new(strings, node.position, encoded) end values.each do |value| if call scoped_value = Mirah::AST::ScopedBody.new(result, value.position) scoped_value << value scoped_value.static_scope = scope else scoped_value = value end result << scoped_value end return result end |
#empty_array(type_node, size_node) ⇒ Object
201 202 203 204 205 206 |
# File 'lib/mirah/transform/transformer.rb', line 201 def empty_array(type_node, size_node) node = eval('int[0]') node.type_node = type_node node.size = size_node node end |
#eval(src, filename = '-', parent = nil, *vars) ⇒ Object
116 117 118 119 120 121 |
# File 'lib/mirah/transform/transformer.rb', line 116 def eval(src, filename='-', parent=nil, *vars) node = Mirah::AST.parse_ruby(src, filename) mirah_node = transform(node, nil).body mirah_node.parent = parent mirah_node end |
#expand(fvcall, parent) ⇒ Object
212 213 214 215 216 217 218 |
# File 'lib/mirah/transform/transformer.rb', line 212 def (fvcall, parent) result = yield self, fvcall, parent unless AST::Node === result raise Error.new('Invalid macro result', fvcall.position) end result end |
#find_class(name) ⇒ Object
208 209 210 |
# File 'lib/mirah/transform/transformer.rb', line 208 def find_class(name) AST.type(nil, name, false, false) end |
#fixnum(value) ⇒ Object
172 173 174 175 176 |
# File 'lib/mirah/transform/transformer.rb', line 172 def fixnum(value) node = eval("1") node.literal = value node end |
#load_ast(args) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/mirah/transform/transformer.rb', line 155 def load_ast(args) nodes = args.to_a encoded = nodes.shift Mirah::AST::Unquote.inject_values(nodes) do result = Marshal.load(Base64.decode64(encoded)) if Mirah::AST::UnquotedValue === result result.node else result end end end |
#position(node) ⇒ Object
66 67 68 |
# File 'lib/mirah/transform/transformer.rb', line 66 def position(node) JMetaPosition.new(node.start_position, node.end_position) end |
#string(value) ⇒ Object
195 196 197 198 199 |
# File 'lib/mirah/transform/transformer.rb', line 195 def string(value) node = eval('"Foo"') node.literal = value node end |
#tmp(format = "__xform_tmp_%d") ⇒ Object
41 42 43 |
# File 'lib/mirah/transform/transformer.rb', line 41 def tmp(format="__xform_tmp_%d") format % [@tmp_count += 1] end |
#transform(node, parent) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/mirah/transform/transformer.rb', line 74 def transform(node, parent) return nil if node.nil? begin top = @extra_body.nil? if top return nil if !node.children.empty? && node.children.all?(&:nil?) @extra_body = Mirah::AST::Body.new(nil, position(node)) end method = "transform_#{camelize(node[0])}" result = @helper.send method, node, parent if top body = result.body if body.kind_of?(Mirah::AST::Body) && @extra_body.empty? @extra_body = body else result.body = @extra_body body.parent = @extra_body @extra_body.children.insert(0, body) end end return result rescue Error => ex @errors << ex Mirah::AST::ErrorNode.new(parent, ex) # rescue Exception => ex # error = Error.new(ex.message, position(node), ex) # @errors << error # Mirah::AST::ErrorNode.new(parent, error) end end |
#verbose? ⇒ Boolean
27 28 29 |
# File 'lib/mirah/transform/transformer.rb', line 27 def verbose? @state.verbose end |