Class: Macro::CallSiteNode
Overview
look for macro invocations, and expand them
Instance Method Summary collapse
Instance Method Details
#macro_expand(macros, session) ⇒ Object
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 |
# File 'lib/macro.rb', line 518 def (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. node,macros,session when Array; node.map{|item| Macro. 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. 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 |