Class: Macro::MacroNode
- Defined in:
- lib/macro.rb,
lib/macro/ReduceWithsFor_RedParse_RedParse__MacroMixin_RedParse__WithMacros_1_9.rb,
lib/macro/ReduceWithsFor_RedParse_RedParse__MacroMixin_RedParse__WithMacros_1_8.rb,
lib/macro.rb
Overview
look for macro definitions, save them and convert them to method definitions
Instance Method Summary collapse
-
#initialize(macroword, header, semi, body, rescues, else_, ensure_, endword) ⇒ MacroNode
constructor
A new instance of MacroNode.
- #macro_expand(macros, session) ⇒ Object
- #reducer_ident ⇒ Object
-
#unparse(o = default_unparse_options) ⇒ Object
Performs the reverse of a parse operation (turns the MacroNode into a string).
Constructor Details
#initialize(macroword, header, semi, body, rescues, else_, ensure_, endword) ⇒ MacroNode
Returns a new instance of MacroNode.
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 |
# 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 |
Instance Method Details
#macro_expand(macros, session) ⇒ Object
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
# File 'lib/macro.rb', line 440 def (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 =proc{|x| Node===x ? Macro.(x,macros,session) : x} node.receiver= [node.receiver] node.args.map!( & )if node.args node.body= [node.body] node.rescues.map!( & )if node.rescues node.ensure_= [node.ensure_] node.else_= [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 ⇒ Object
19093 19094 19095 |
# File 'lib/macro/ReduceWithsFor_RedParse_RedParse__MacroMixin_RedParse__WithMacros_1_9.rb', line 19093 def reducer_ident :MacroNode end |
#unparse(o = default_unparse_options) ⇒ Object
Performs the reverse of a parse operation (turns the MacroNode into a string)
o
-
a list of options for unparse
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 |
# File 'lib/macro.rb', line 789 def unparse o= 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 |