class Macro::Node
Public Instance Methods
eval(binding=nil,file=nil,line=nil)
click to toggle source
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
# 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)... expanded_tree=self #Macro.expand(deep_copy,::Macro::GLOBALS) unparsed=expanded_tree.unparse #puts unparsed ::Kernel.eval unparsed, binding||::Object.new_binding,file||'(eval)',line||1 end
load(name='',wrap=false)
click to toggle source
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
# File lib/macro.rb, line 308 def load(name='',wrap=false) expanded_tree=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 expanded_tree.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 expanded_tree=filenamenode end end true } unparsed=expanded_tree.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)
click to toggle source
Convert this node to an S-expression
session
-
the context in which this macro is being processed
# 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
Private Instance Methods
call_to_sexp(param,session)
click to toggle source
# File lib/macro.rb, line 356 def call_to_sexp param,session if param.instance_of? ::Array "["+param.map{|subparam| call_to_sexp(subparam,session)}.join(", ")+"]" elsif param.respond_to?(:to_sexp) param.to_sexp(session) else param.inspect end end