Class: Macro::Node
Instance Method Summary collapse
-
#eval(binding = nil, file = nil, line = nil) ⇒ Object
just like Kernel#eval, but allows macros (and forms) and input is a RedParse parse tree (as receiver).
-
#load(name = '', wrap = false) ⇒ Object
A helper for Macro.load and Macro.eval.
-
#to_sexp(session) ⇒ Object
Convert this node to an S-expression.
Instance Method Details
#eval(binding = nil, file = nil, line = nil) ⇒ Object
just like Kernel#eval, but allows macros (and forms) and input is a RedParse parse tree (as receiver). beware: default for binding is currently broken. best practice is to pass an explicit binding (see Kernel#binding) for now.
binding
-
the binding in which to evaluate the node
file
-
for purpose of evaluation, the name of the file this node came from
line
-
for purpose of evaluation, the line number this node came from
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/macro.rb', line 284 def eval(binding=nil,file=nil,line=nil) #binding should default to Binding.of_caller, but.... that's expensive if String===binding file=binding binding=nil end #references to 'self' (implicit and explicit) within this parse tree #should be forced to refer to the self from binding, (if any)... =self #Macro.expand(deep_copy,::Macro::GLOBALS) unparsed=.unparse #puts unparsed ::Kernel.eval unparsed, binding||::Object.new_binding,file||'(eval)',line||1 end |
#load(name = '', wrap = false) ⇒ Object
A helper for Macro.load and Macro.eval. The source code for the node is saved to a file so that it can be viewed in the debugger.
name
-
the name of the file being loaded
wrap
-
whether to wrap the loaded file in an anonymous module
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/macro.rb', line 308 def load(name='',wrap=false) =self #Macro.expand(deep_copy,::Macro::GLOBALS) #replace __FILE__ in tree with the correct file name #(otherwise, it will point to some tmp file) filenamenode=nil .walk{|parent,i,subi,node| if VarLikeNode===node and node.ident=="__FILE__" filenamenode||=Macro.quote name #StringNode[name.gsub(/['\\]/){|ch| '\\'+ch},{:@open=>"'", :@close=>"'"}] if parent subi ? parent[i][subi]=filenamenode : parent[i]=filenamenode else =filenamenode end end true } unparsed=.unparse #p expanded_tree #puts unparsed Tempfile.open("macroexpanded_"+name.gsub("/","__")){|tf| tf.write unparsed tf.flush ::Kernel::load tf.path, wrap } return true end |
#to_sexp(session) ⇒ Object
Convert this node to an S-expression
session
-
the context in which this macro is being processed
341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/macro.rb', line 341 def to_sexp session # TODO: this (and all other functions similarly named) is possibly # dead code self.class.name+"["+ map{|param| call_to_sexp param,session }.join(", ")+ ", {"+instance_variables.map{|iv| iv=="@data" and next val=instance_variable_get(iv) val=call_to_sexp(val,session) ":"+iv+"=>"+val }.join(", ")+"}"+ "]" end |