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
166 167 168 |
# File 'lib/mirah/transform/transformer.rb', line 166 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
218 219 220 221 |
# File 'lib/mirah/transform/transformer.rb', line 218 def append_node(node) @extra_body << node node end |
#body(parent = nil) ⇒ Object
238 239 240 241 |
# File 'lib/mirah/transform/transformer.rb', line 238 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
104 105 106 107 108 109 110 111 112 |
# File 'lib/mirah/transform/transformer.rb', line 104 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
183 184 185 186 187 188 189 190 191 |
# File 'lib/mirah/transform/transformer.rb', line 183 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
176 177 178 179 180 181 |
# File 'lib/mirah/transform/transformer.rb', line 176 def constant(name, array=false) node = eval("Foo") node.name = name node.array = array node end |
#define_class(position, name, &block) ⇒ Object
223 224 225 |
# File 'lib/mirah/transform/transformer.rb', line 223 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
243 244 245 246 247 248 249 250 251 252 |
# File 'lib/mirah/transform/transformer.rb', line 243 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
227 228 229 230 231 232 233 234 235 236 |
# File 'lib/mirah/transform/transformer.rb', line 227 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
121 122 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 |
# File 'lib/mirah/transform/transformer.rb', line 121 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
199 200 201 202 203 204 |
# File 'lib/mirah/transform/transformer.rb', line 199 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
114 115 116 117 118 119 |
# File 'lib/mirah/transform/transformer.rb', line 114 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
210 211 212 213 214 215 216 |
# File 'lib/mirah/transform/transformer.rb', line 210 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
206 207 208 |
# File 'lib/mirah/transform/transformer.rb', line 206 def find_class(name) AST.type(nil, name, false, false) end |
#fixnum(value) ⇒ Object
170 171 172 173 174 |
# File 'lib/mirah/transform/transformer.rb', line 170 def fixnum(value) node = eval("1") node.literal = value node end |
#load_ast(args) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/mirah/transform/transformer.rb', line 153 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
193 194 195 196 197 |
# File 'lib/mirah/transform/transformer.rb', line 193 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 |
# File 'lib/mirah/transform/transformer.rb', line 74 def transform(node, parent) return nil if node.nil? begin top = @extra_body.nil? if top @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 |