class Macro::MacroNode
look for macro definitions, save them and convert them to method definitions
Public Class Methods
new(macroword,header,semi,body,rescues,else_,ensure_,endword)
click to toggle source
# File lib/macro.rb, line 743 def initialize(macroword,header,semi,body,rescues,else_,ensure_,endword) #decompose header if CallSiteNode===header receiver=header.receiver args=header.args header=header.name end if MethNameToken===header #not needed? header=header.ident end unless String===header fail "unrecognized method header: #{header}" end @data=replace [receiver,header,args,body,rescues,else_,ensure_] =begin hmm, maybe not a good idea.... #quote parameters to yield within macro walk{|cntr,i,subi,item| case item when KWCallNode; if item.name=="yield" raise ArgumentError if item.block or item.blockparams if item.params raise ArgumentError if UnAmpNode===item.params.last item.params.map!{|param| FormNode.new(nil,ParenedNode[param]) } end false else true end else true end } =end end
Public Instance Methods
macro_expand(macros,session)
click to toggle source
# File lib/macro.rb, line 440 def macro_expand(macros,session) fail "scoped macros are not allowed (yet)" unless session[:@modpath].empty? #varargs, &args and receivers are not allowed in macro definitions (yet) fail "macro receivers not supported yet" if receiver if args last=args # else # last=args.last end fail "macro varargs and block not supported yet" if UnOpNode===last and /\A[*&]@\Z/===last.op.ident name=self.name #macros can't be settors fail "macro settors are not allowed" if /=$/===name self.args||=[] args.unshift VarNode.allocate.replace(["receiver"]) self.walk{|parent,i,subi,node| #replace self kw in body with receiver var instead if VarLikeNode===node and node.ident=="self" if subi parent[i][subi]=VarNode.allocate.replace(["receiver"]) else parent[i]=VarNode.allocate.replace(["receiver"]) end end true } #macro definitions need to be dealt with in 2 steps: registration and activation # name=self.name self[1]="macro_"+name unless /^macro_/===name node=MethodNode[*self] #convert macro node to a method def node huh(node.receiver) if node.receiver node[0]=ParenedNode[ConstantNode[nil,"Object"]] #all macros are global for now... til we get scoped macros #sets receiver #disable postponement (delayed macros) ... i think they're not necessary expand=proc{|x| Node===x ? Macro.expand(x,macros,session) : x} node.receiver= expand[node.receiver] node.args.map!( &expand )if node.args node.body= expand[node.body] node.rescues.map!( &expand )if node.rescues node.ensure_= expand[node.ensure_] node.else_= expand[node.else_] node.eval(nil,session[:filename]) macros[name.to_sym]=::Object.method("macro_"+name) return node,false =begin was #node.eval #no, not here.... newnode=Macro.postpone node, session #newnode=:(( # ^newnode # Macro::GLOBALS[^name.to_sym]=Object.method ^node.name.to_sym # nil #)) newnode=ParenedNode[SequenceNode[ newnode, CallNode[ConstantNode[nil,"Macro", "GLOBALS"],"[]=",[ LiteralNode[name.to_sym], CallNode[ConstantNode[nil,"Object"], "method", [LiteralNode[node.name.to_sym]],nil,nil]], nil,nil], VarLikeNode['nil'] ]] #newnode=RedParse::VarLikeNode["nil", {:@value=>false,}] #subi ? parent[i][subi]=newnode : parent[i]=newnode return newnode,false #dont keep recursing =end end
reducer_ident()
click to toggle source
# File lib/macro/ReduceWithsFor_RedParse_RedParse__MacroMixin_RedParse__WithMacros_1_8.rb, line 18872 def reducer_ident :MacroNode end
unparse(o=default_unparse_options)
click to toggle source
Performs the reverse of a parse operation (turns the MacroNode
into a string)
o
-
a list of options for unparse
# File lib/macro.rb, line 789 def unparse o=default_unparse_options result="macro " result+=receiver.unparse(o)+'.' if receiver result+=name if args and !args.empty? result+="(" result+=args.map{|arg| arg.unparse o}.join',' result+=")" end result+=unparse_nl(body,o)+body.unparse(o) if body result+=rescues.map{|resc| resc.unparse o}.to_s if rescues result+=unparse_nl(else_,o)+"else "+else_.unparse( o )+"\n" if else_ result+=unparse_nl(ensure_,o)+"ensure "+ensure_.unparse( o )+"\n" if ensure_ result+=";end" return result end