class Macro::CallSiteNode
look for macro invocations, and expand them
Public Instance Methods
macro_expand(macros,session)
click to toggle source
# File lib/macro.rb, line 518 def macro_expand(macros,session) name=self.name #pp macros #pp Macro::GLOBALS macro=macros[name.to_sym] unless macro #turn off modpath surity in blocks. #this disables modpath surity in callsite receivers and parameters as well; #unnecessary, but no great loss. old_unsure=session[:@modpath_unsure] session[:@modpath_unsure]=true map!{|node| case node when Node; Macro.expand node,macros,session when Array; node.map{|item| Macro.expand item,macros,session} else node end } session[:@modpath_unsure]=old_unsure return nil,false #change nothing, recursion done already end return nil,true unless macro #change nothing but keep recursing if not a macro Method===macro or fail args = args()||[] #if this callsite names a macro, then it is a macro #macro=macros[name.to_sym]=::Object.method(macro) if String===macro #refuse macro calls with receivers, blocks, varargs, or &args: not supported yet fail "macro blocky args not supported yet" if UnOpNode===args.last and args.last.ident=="&@" fail "macro varargs calls not supported yet" if UnaryStarNode===args.last fail if args.class!=Array args.unshift receiver||VarLikeNode.allocate.replace(["self"]) if block newnode=macro.call( *args )do |*bparams| if !blockparams block else bparams=KWCallNode["nil"] if bparams.empty? #warning: scoping rules for lvars in blocks not enforced here #(rather serious violation of variable hygiene) ParenedNode[ AssignNode[MultiAssign[*blockparams],'=',bparams]+block ] end end else newnode=macro.call( *args ) end #subi ? parent[i][subi]=newnode : parent[i]=newnode # and keep recursing, no matter what, by all means!! if newnode newnode=Macro.expand newnode,macros,session #just do it here newnode=OneLineParenedNode[newnode] #disable newlines in macro text else newnode=JustNilNode.new end return newnode,false #and not in caller end