class Macro::FormNode

postpone macro expansion (and definition) in forms until they are evaled (or returned from a macro) but not in form parameters

The syntax node for forms

Public Class Methods

_load(str) click to toggle source
# File lib/macro/form.rb, line 82
def self._load str
  result=allocate
  result.replace [Marshal.load(str)]
  result.rebuild_transform
end
new(colon,text) click to toggle source

Create a new form node. The user should normally not call this function. Form nodes are created by the parser.

colon

A colon token

text

A ParenedNode or VarLikeNode

Calls superclass method
# File lib/macro/form.rb, line 37
def initialize(colon,text)
  @startline=@endline=nil

  # Certain node types need to be quoted
  # (or rather, not unquoted)
  if RedParse::VarLikeNode===text
    #this code is dead now, I believe
    @transform=HashLiteralNode[]
    @stars_transform=HashLiteralNode[]
    text.startline=text.endline=0
    super text
    return
  end


  # Sanity check - make sure this is a valid ParenedNode
  if ParenedNode===text && text.size==1 
    text=text.body #unquote the form
  elsif text.size==0
    @transform=HashLiteralNode[]
    @stars_transform=HashLiteralNode[]
    super SequenceNode[]
    return
  end

  super text
  rebuild_transform
end

Public Instance Methods

_dump(depth) click to toggle source
# File lib/macro/form.rb, line 78
def _dump depth
  Marshal.dump text,depth
end
deep_copy(transform={}) click to toggle source

Make a deep copy of this form

transform

TODO

Calls superclass method
# File lib/macro/form.rb, line 162
def deep_copy transform={}
  super(transform).rebuild_transform
end
each_parameter(&block) click to toggle source

Iterate over all the parameters in this form

block

the block to call for each parameter

# File lib/macro/form.rb, line 154
def each_parameter(&block)
  @parameters.each(&block) if defined? @parameters
end
formname() click to toggle source

Lazily evaluate the name of the form and return it

# File lib/macro/form.rb, line 265
def formname
  startline=@startline if defined? @startline
  endline=@endline if defined? @endline
  ivars={:@startline=>startline, :@endline=>endline}

  @formname ||= ConstantNode[nil,"Macro","Names",::Macro::Names.request(self), ivars]
end
initialize_copy(other) click to toggle source
# File lib/macro/form.rb, line 70
def initialize_copy other
  replace other
  other.instance_variables{|v|
    instance_variable_set v, other.instance_variable_get(v)
  }
  rebuild_transform
end
initialize_ivars() click to toggle source

def _dump depth

"foobarbaz"

end

def self._load str

result=allocate

end

Calls superclass method
# File lib/macro/form.rb, line 98
def initialize_ivars
  rebuild_transform
  super
end
macro_expand(macros,session) click to toggle source
# File lib/macro.rb, line 680
def macro_expand(macros,session)
  #return text.to_sexp({})
   

  #maybe this doesn't allow expansion of parameters themselves... only within params?
  each_parameter{|param| Macro.expand(param,macros,session) }


  #replace (text for) form itself with a reference which will be
  #looked up at runtime (and have parameters expanded at that point too)
  
  


  return parses_like,false #halt further recursion: already done where necessary
end
noinspect_instance_variables() click to toggle source
# File lib/macro/form.rb, line 66
def noinspect_instance_variables
  %w[@stars_transform @transform]
end
parses_like() click to toggle source

Turn the form into something that is legal ruby (since :(..) is not legal ruby syntax). Thus the form is changed from the syntax:

:(code)

to:

RedParse::SomeNodeType[ some transform of code ]
# File lib/macro/form.rb, line 253
def parses_like
  startline=@startline if defined? @startline
  endline=@endline if defined? @endline
  ivars={:@startline=>startline, :@endline=>endline}
  CallSiteNode[
    CallSiteNode[formname, "reify", [@transform,@stars_transform], ivars], 
    "text", ivars
  ]
  #:(^(formname).reify(^@transform,^@stars_transform).text)
end
parsetree() click to toggle source

Transform this node into a ParseTree parse tree

# File lib/macro/form.rb, line 221
def parsetree
  parses_like.parsetree
end
rebuild_transform() click to toggle source

Initialize the transform and create all the form escapes that are used in this form

# File lib/macro/form.rb, line 105
def rebuild_transform
  # TODO: this method needs to be better documented/refactored
  @transform=HashLiteralNode[]
  @stars_transform=HashLiteralNode[]
  @parameters=[]
  @parameters.extend RedParse::ListInNode

  walkers=proc{|rcvr,wraplayers| #curry
    rcvr.walk{|parent,i,j,node| 
     node.startline=node.endline=0 if node.respond_to? :startline
     case node
     when FormEscapeNode
       target=node.wraplevel
       #fail if wraplayers > target
       if wraplayers==target #skip this parameter if it doesn't have enough wrappers
         @parameters << node #remember parameter (and implicitly, location)

         nil# and stop further recursion
       else 
         true
       end
     when FormNode
       #walk form with same walker we're using now, except an extra layer of form parameters
       #must be present for them to be considered 'our' parameters
       walkers[node.text,wraplayers+1]
       nil #don't recurse in this node again, we just did it
     else true
     end
    } if rcvr.respond_to? :walk
  }
  walkers[text,1]

  @parameters.each{|orig_escd| 
    escd=orig_escd
    escd=escd.val while FormEscapeNode===escd
    if UnaryStarNode===escd
      @stars_transform.push LiteralNode[orig_escd.__id__], escd.val
    else
      @transform.push LiteralNode[orig_escd.__id__], escd
    end
  }

  return self
end
reducer_ident() click to toggle source
# File lib/macro/ReduceWithsFor_RedParse_RedParse__MacroMixin_RedParse__WithMacros_1_8.rb, line 18862
def reducer_ident
  :FormNode
end
reify(transform, stars_transform) click to toggle source

Called when the form is evaluated to convert the abstract form of the parse tree into a concrete form that can be modified (makes a copy of the form).

transform

the transform to use in the deep copy

# File lib/macro/form.rb, line 181
def reify transform, stars_transform
  transform&&=transform.dup
  stars_transform&&=stars_transform.dup
  transform.each_pair{|k,v|
    case v
    when Node; next
    when Symbol; v=CallNode[nil,v.to_s]
    else v=Macro.quote v
    end
    transform[k]=v
  }
  stars_transform.each_pair{|k,v|
    case v
    when Symbol; v=CallNode[nil,v.to_s]
    else v=Macro.quote v
    end
    stars_transform[k]=v.extend InlineList
  }
  result=deep_copy(transform.merge( stars_transform ))
  #expand InlineLists somehow
  result.walk{|parent,i,j,node|
    if InlineList===node
      if j
        parent[i][j,1]=*node
      else
        parent[i,1]=*node
      end
      nil #halt further recursion
    else
      true
    end
  } unless stars_transform.empty?
  
  return result
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

Calls superclass method
# File lib/macro.rb, line 701
def to_sexp session
  nest=session[:form_nest_level]
  session[:form_nest_level]=nest ? nest+1 : 2

  result=super

  if nest
    session[:form_nest_level]-=1
  else
    session.delete :form_nest_level
  end
  return result
end
unparse(o=default_unparse_options) click to toggle source

Performs the reverse of a parse operation (turns the node into a string)

o

a list of options for unparse

# File lib/macro/form.rb, line 171
def unparse o=default_unparse_options
  ":("+text.unparse(o)+")"
end