grammar Cardinal::ASTGrammar is TGE::Grammar;

transform result (ROOT) :language('PIR') {
    debug_init

    .local pmc past
    past = new 'Cardinal::PAST::Block'
    past.'init'('node'=>node, 'name'=>'top', 'blocktype'=>'block')
    self.'push_scope_stack'(past)

    .local pmc child
    $I0 = defined node['compound_statement']
    unless $I0 goto err_no_tree
    $P0 = node['compound_statement']
    child = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    past.'add_child'(child)
    .return (past)

  err_no_tree:
    print "The top-level node doesn't contain an 'compound_statement' match.\n"
    end
}

transform result (Cardinal::Grammar::body_statement) :language('PIR') {
    .local pmc child
    .local pmc result
    result = new 'Cardinal::PAST::Stmts'
    result.'init'('node'=>node)

    $I0 = defined node['compound_statement']
    unless $I0 goto err_no_tree
    $P0 = node['compound_statement']
    child = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    result.'add_child'(child)

    $I0 = defined node['rescue_clause']
    unless $I0 goto n1
    $P0 = node['rescue_clause']
    child = tree.get('result', $P0, 'Cardinal::Grammar::rescue_clause')
    result.'add_child'(child)

    n1:
    $I0 = defined node['else_clause']
    unless $I0 goto n2
    $P0 = node['else_clause']
    child = tree.get('result', $P0, 'Cardinal::Grammar::else_clause')
    result.'add_child'(child)

    n2:
    $I0 = defined node['rescue_clause']
    unless $I0 goto n3
    $P0 = node['rescue_clause']
    child = tree.get('result', $P0, 'Cardinal::Grammar::rescue_clause')
    result.'add_child'(child)

    n3:
    .return (result)

  err_no_tree:
    print "The body_statement node doesn't contain a 'compound_statement' match.\n"
    end
}

transform result (Cardinal::Grammar::compound_statement) :language('PIR') {
    .local pmc child
    .local pmc result
    result = new 'Cardinal::PAST::Stmts'
    result.'init'('node'=>node)
    #.kdump2(node, 'compound_statement')

    $I0 = defined node['statement']
    unless $I0 goto no_statement
    $P0 = node['statement']      
    
    .local pmc iter
    iter = new Iterator, $P0    # setup iterator for node
    iter = 0

  iter_loop:
    unless iter, iter_end         # while (entries) ...
    shift $P0, iter
    
    child = tree.get('result', $P0, 'Cardinal::Grammar::statement')
    result.'add_child'(child)

    goto iter_loop

  iter_end:
    .return (result)

  no_statement:
    .return ()

  err_no_tree:
    print "The statements node doesn't contain a 'statement' match.\n"
    .kdump2(node, 'statements')
    end
}

transform val (string) :language('PIR') {
  .local pmc result
    result = new 'Cardinal::PAST::Val'
    $S0 = node
    result.'init'('node'=>node, 'name'=>$S0, 'valtype'=>'String')
    .return (result)             
}

transform result (Cardinal::Grammar::statement) :language('PIR') {
    #.kdump2(node, 'statement')
    .local pmc result
    .local pmc child
    .local pmc op

    result = new 'Cardinal::PAST::Stmt'
    result.'init'('node'=>node)
  
    # alias
    $I0 = defined node['ALIAS']
    unless $I0 goto n1
    $S0 = node['ALIAS']
    
    op = new 'Cardinal::PAST::Op'
    op.'init'('node'=>node, 'name'=>$S0)
    $I0 = defined node['function_item']
    unless $I0 goto l1
    $P0 = node['function_item']
    $P1 = $P0[0]
    $P1 = tree.'get'('val', $P1, 'string')
    $P2 = $P0[1]
    $P2 = tree.'get'('val', $P2, 'string')
    goto finish_alias
  l1:
    $I0 = defined node['GLOBAL_VARIABLE']
    unless $I0 goto err_no_tree

    $P0 = node['GLOBAL_VARIABLE']
    $P1 = $P0[0]
    $P1 = tree.'get'('val', $P1, 'string')
    $I0 = elements $P0
    unless $I0 == 2 goto back_reference
    $P2 = $P0[1]
    goto finish_GLOBAL_VARIABLE
  back_reference:
    $P2 = node['back_reference']
  finish_GLOBAL_VARIABLE:
    $P2 = tree.'get'('val', $P2, 'string')

  finish_alias:
    op.'add_child'($P1)
    op.'add_child'($P2)
    result.'add_child'(op)
    .return (result)

    # undef
  n1:
    $I0 = defined node['UNDEF']
    unless $I0 goto n2
    child = tree.get('result', node, 'Cardinal::Grammar::undef')
    .return (child)

    # begin
  n2:
    $I0 = defined node['BEGIN']
    unless $I0 goto n3
    .local pmc begin_sub
    $P0 = self.'top_scope_stack'()
    begin_sub = new 'Cardinal::PAST::Block'
    begin_sub.'init'('node'=>node, 'name'=>'begin', 'blocktype'=>'BEGIN', 'outer'=>$P0)
    $P0 = node['compound_statement']

    self.'push_scope_stack'(begin_sub)
    child = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    self.'pop_scope_stack'()

    begin_sub.'add_child'(child)
    .return (begin_sub)

    # end
  n3:
    $I0 = defined node['END']
    unless $I0 goto n4
    .local pmc begin_sub
    $P0 = self.'top_scope_stack'()
    begin_sub = new 'Cardinal::PAST::Block'
    begin_sub.'init'('node'=>node, 'name'=>'end', 'blocktype'=>'END', 'outer'=>$P0)
    $P0 = node['compound_statement']

    self.'push_scope_stack'(begin_sub)
    child = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    self.'pop_scope_stack'()

    begin_sub.'add_child'(child)
    .return (begin_sub)

  n4:
    # if | unless | while | until
    $I0 = defined node['expression']
    unless $I0 goto n6
    $P0 = node['expression']      
    $P1 = $P0[0]
    child = tree.get('result', $P1, 'Cardinal::Grammar::expression')

    $I0 = defined node['MODIFIER']
    unless $I0 goto n5
    $P2 = node['MODIFIER']
    $S0 = $P2[0]
    
    op = new 'Cardinal::PAST::Op'
    op.'init'('node'=>node, 'name'=>$S0)
    $P1 = $P0[1]
    $P3 = tree.get('result', $P1, 'Cardinal::Grammar::expression')

    op.'add_child'($P3)
    unless $S0 == 'unless' goto its_a_if
    null $P4 
    op.'add_child'($P4)
  its_a_if:
    op.'add_child'(child)
    result.'add_child'(op)
    .return (result)

  n5:
    # rescue
    $I0 = defined node['rescue']
    unless $I0 goto pass_through
    
    $I0 = defined node['statement']
    unless $I0 goto err_no_tree
    $P0 = node['statement'; 0]      
    $P0 = tree.get('result', $P0, 'Cardinal::Grammar::statement')
    
    result = new 'Cardinal::PAST::Rescue_Stmt'
    result.'init'('node'=>node, 'try_stmt'=>child, 'rescue_stmt'=>$P0)
    .return (result)

  n6:
    $I0 = defined node['lang_statements']
    unless $I0 goto err_no_tree
    $P0 = node['lang_statements']      
    $P0 = tree.get('result', $P0, 'Cardinal::Grammar::lang_statements')
    .return ($P0)


  pass_through: 
    result.'add_child'(child)
    .return (result)

  err_no_tree:
    print "The statement node doesn't contain a 'expression' match.\n"
    end
}

transform result (Cardinal::Grammar::expression) :language('PIR') {

    # Ask the child node for its result
    .local pmc child
    $I0 = defined node['operator_precedence_parser']
    unless $I0 goto err_no_tree
    $P0 = node['operator_precedence_parser']
    child = tree.get('result', $P0, 'Cardinal::Grammar::operator_precedence_parser')
    .return (child)

  err_no_tree:
    print "The expression node doesn't contain a 'operator_precedence_parser' match.\n"
    end
}

transform result (Cardinal::Grammar::operator_precedence_parser) :language('PIR') {
    .local pmc result
    result = new 'Cardinal::PAST::Exp'
    result.'init'('node'=>node)

    .local pmc iter
    $P1 = node.get_hash()
    iter = new Iterator, $P1    # setup iterator for node
    iter = 0
  iter_loop:
    unless iter, iter_end         # while (entries) ...
      shift $S1, iter           # get the key of the iterator
      $P2 = iter[$S1]
      $S0 = 'Cardinal::Grammar::'
      $S0 .= $S1
      $P3 = tree.get('result', $P2, $S0)
      if null $P3 goto iter_loop
      result.'add_child'($P3)
      goto iter_loop
  iter_end:

    .return (result)
}

transform result (Cardinal::Grammar::expr) :language('PIR') {
    .local string type
    type = node["type"]
    unless node goto error_no_node
    if type == 'term:' goto transform_term
      # else
      $P1 = tree.get('op', node, 'expr')
      .return($P1)
    transform_term:
      $P1 = tree.get('term', node, 'expr')
      .return($P1)
    error_no_node:
      print "error: no node\n"
      end
}


transform result (Cardinal::Grammar::assignment) :language('PIR') {
    .local pmc child
    .local string assign_symbol
    .local pmc child2
  
    $I0 = defined node[0]
    unless $I0 goto other_assignment
    $S0 = node[0]
    ne_str $S0, '=', na1
    assign_symbol = 'infix:='
    goto get_left
  na1:
    print "No other assigns have been coded yet"
    end

  other_assignment:
    $I0 = defined node['ASSIGN_OP']
    unless $I0 goto try_command
    assign_symbol = node['ASSIGN_OP']
    ne_str assign_symbol, '-=', na2
    assign_symbol = 'infix:-='
  na2:
    goto get_left
    
  get_left:
    $I0 = defined node['left_hand_side']
    unless $I0 goto get_variable
    $P0 = node['left_hand_side']
    child = tree.get('result', $P0, 'Cardinal::Grammar::left_hand_side')
    goto get_right

  get_variable:
    $I0 = defined node['variable']
    unless $I0 goto err_no_left_hand_side
    $P0 = node['variable']
    child = tree.get('result', $P0, 'Cardinal::Grammar::variable')
    goto get_right

  get_right:
    $I0 = defined node['expression']
    unless $I0 goto err_no_tree
    $P0 = node['expression']
    child2 = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    goto build_assignment

  try_command:
    $I0 = defined node['command_call']
    unless $I0 goto try_method_call
    $P0 = node['command_call']
    child = tree.get('result', $P0, 'Cardinal::Grammar::command_call')
    goto single_item

  try_method_call:
    $I0 = defined node['method_call']
    unless $I0 goto try_atom
    $P0 = node['method_call']
    child = tree.get('result', $P0, 'Cardinal::Grammar::method_call')
    goto single_item
  
  try_atom:
    $I0 = defined node['atom']
    unless $I0 goto err_no_tree
    $P0 = node['atom']
    child = tree.get('result', $P0, 'Cardinal::Grammar::atom')
    goto single_item
  

  build_assignment: 
    .local pmc result
    result = new 'Cardinal::PAST::Op'
    result.'init'('node'=>node, 'name'=>assign_symbol)
    result.'add_child'(child)
    result.'add_child'(child2)
    .return (result)

  single_item:
    .return (child)

  err_not_past_val:
    print "Not a Identifier\n"
    end

  err_no_tree:
    print "The assignment node doesn't contain a 'postfix' match.\n"
    .kdump2(node, "Node")
    end
  err_no_assign_symbol:
    print "The assignment node doesn't contain a assignment symbol.\n"
    end
  err_no_left_hand_side:
    .kdump2(node, "Node")
    print "The assignment node doesn't contain a 'left_hand_side' match.\n"
    end
}

transform result (Cardinal::Grammar::command_call) :language('PIR') {
    .local pmc command
    $I0 = defined node['command']
    unless $I0 goto err_no_tree
    $P1 = node['command']
    command = tree.get('result', $P1, 'Cardinal::Grammar::command')

    .return (command)

  err_no_tree:
    print "The command_call node doesn't contain a 'command' match.\n"
    end
}

transform result (Cardinal::Grammar::method_call) :language('PIR') {
    .local pmc child
    .local pmc child2

    $I0 = defined node['atom']
    unless $I0 goto err_no_tree
    $P0 = node['atom']
    $S0 = node['atom']
    #child = tree.get('result', $P0, 'Cardinal::Grammar::atom')
    child = new 'Cardinal::PAST::Var'
    child.'init'('node'=>node, 'name'=> $S0, 'scope'=>'exists')
    
    $I0 = defined node['operation2']
    unless $I0 goto err_no_tree
    $P0 = node['operation2']
    child2 = tree.get('result', $P0, 'Cardinal::Grammar::operation2')

    .local pmc result
    result = new 'Cardinal::PAST::MethodCall'
    result.'init'('node'=>node, 'name'=>child2)
    result.'add_child'(child)
    result.'add_child'(child2)
    .return (result)

  err_no_tree:
    print "The method_call node doesn't contain a match.\n"
    end
}

transform result (Cardinal::Grammar::command) :language('PIR') {
    .local pmc name
    .local pmc result
    $I0 = defined node['operation']
    unless $I0 goto try_atom
    $P0 = node['operation']
    $S0 = tree.get('result', $P0, 'Cardinal::Grammar::operation')

    # Check for args
    .local pmc args
    $I0 = defined node['command_args']
    if $I0 goto get_operator_args
    .return (name)

  try_atom:
  try_special_command_type:
    $I0 = defined node['special_command_type']
    unless $I0 goto err_no_name
    $P0 = node['special_command_type']
    $S0 = $P0
    result = new 'Cardinal::PAST::Op'
    result.'init'('node'=>node, 'name'=>$S0)
    goto get_args


  get_operator_args:
    result = new 'Cardinal::PAST::Op'
    result.'init'('node'=>node, 'name'=>$S0)
  get_args:
    $I0 = defined node['command_args']
    $P0 = node['command_args']
    args = tree.get('result', $P0, 'Cardinal::Grammar::command_args')
    if_null args, noargs

    .local pmc iter
    iter = new Iterator, args
    iter = 0

    iter_loop:
    unless iter, iter_end
    shift $P2, iter
    result.'add_child'($P2)
    goto iter_loop
    iter_end:

  noargs:
    .return (result)

  err_no_name:
    print "The command node doesn't contain a 'operation' match.\n"
    end
}

transform result (Cardinal::Grammar::command_args) :language('PIR') {
    .local pmc args
    $I0 = defined node['paren_args']
    unless $I0 goto call_args
    $P0 = node['paren_args']
    args = tree.get('result', $P0, 'Cardinal::Grammar::paren_args')
    .return (args)

  call_args:
    $I0 = defined node['call_args']
    unless $I0 goto err_no_tree
    $P0 = node['call_args']
    args = tree.get('result', $P0, 'Cardinal::Grammar::call_args')
    .return (args)

  err_no_tree:
    print "The command_args node doesn't contain an 'paren_args' or 'call_args' match.\n"
    end
}

transform result (Cardinal::Grammar::paren_args) :language('PIR') {
    .local pmc args
    $I0 = defined node['call_args']
    unless $I0 goto no_call_args
    $P0 = node['call_args']
    $P0 = $P0[0]
    args = tree.get('result', $P0, 'Cardinal::Grammar::call_args')
    .return (args)

  no_call_args:
    null args
    .return (args)
}

transform result (Cardinal::Grammar::call_args) :language('PIR') {
    .local pmc child
    .local pmc result
    result = new .ResizablePMCArray

    $I0 = defined node['call_args_positional']
    unless $I0 goto next_1
    $P0 = node['call_args_positional']
    child = tree.get('result', $P0, 'Cardinal::Grammar::call_args_positional')
    .return (child)

  next_1:
    goto err_no_tree
    $I0 = defined node['call_args_positional']
    unless $I0 goto err_no_tree
    $P0 = node['call_args_positional']
    child = tree.get('result', $P0, 'Cardinal::Grammar::call')
    goto add_child

  add_child:
    push result, child
    .return (result)

  err_no_tree:
    print "The call_args node doesn't contain a proper 'argument' match.\n"
    end

}

transform result (Cardinal::Grammar::call_args_positional) :language('PIR') { 
    .local pmc result
    result = new .ResizablePMCArray

    $I0 = defined node['expression']
    unless $I0 goto err_no_tree
    $P0 = node['expression']

    .local pmc iter
    iter = new Iterator, $P0    # setup iterator for node
    iter = 0

    iter_loop:
    unless iter, iter_end         # while (entries) ...
    shift $P2, iter
    
    .local pmc child
    child = tree.get('result', $P2, 'Cardinal::Grammar::expression')
    push result, child

    goto iter_loop
  iter_end:
    
    .return (result)

  err_no_tree:
    print "The call_args_positional node doesn't contain a proper 'expression' match.\n"
    end
}

transform result (Cardinal::Grammar::operation) :language('PIR') {
    .local pmc name
    $I0 = defined node['IDENTIFIER']
    unless $I0 goto test_constant
    $P0 = node['IDENTIFIER']
    name = tree.get('result', $P0, 'Cardinal::Grammar::IDENTIFIER')
    .return (name)

  test_constant:
    $I0 = defined node['CONSTANT']
    unless $I0 goto err_no_name
    $P0 = node['CONSTANT']
    name = tree.get('result', $P0, 'Cardinal::Grammar::CONSTANT')
    .return (name)
  
  err_no_name:
    print "The PGE operation node doesn't contain a 'IDENTIFIER' or a 'CONSTANT' match.\n"
    end
}

transform result (Cardinal::Grammar::operation2) :language('PIR') {
.local pmc name

    $I0 = defined node['IDENTIFIER']
    unless $I0 goto test_constant
    $P0 = node['IDENTIFIER']
    name = tree.get('result', $P0, 'Cardinal::Grammar::IDENTIFIER')
    .return (name)

  test_constant:
    $I0 = defined node['CONSTANT']
    unless $I0 goto test_op
    $P0 = node['CONSTANT']
    name = tree.get('result', $P0, 'Cardinal::Grammar::CONSTANT')
    .return (name)

  test_op:
    $I0 = defined node['op']
    unless $I0 goto err_no_name
    $P0 = node['op']
    name = tree.get('result', $P0, 'Cardinal::Grammar::op')
    .return (name)
  
  err_no_name:
    print "The PGE operation2 node doesn't contain a 'IDENTIFIER', 'CONSTANT', or a 'op' match.\n"
    end
}

transform result (Cardinal::Grammar::IDENTIFIER) :language('PIR') {
    .local pmc result

    $S0 = node

    result = new 'Cardinal::PAST::Val'
    result.'init'('node'=>node, 'name'=>$S0, 'valtype'=>'identifier')
    .return (result)             

  err_no_tree:
    print "The IDENTIFIER node doesn't contain a 'identifier' match.\n"
    end
}

transform result (Cardinal::Grammar::CONSTANT) :language('PIR') {
    $I0 = defined node[0]
    unless $I0 goto err_no_tree
    $S0 = node[0]

    .local pmc result
    result = new 'Cardinal::PAST::Val'
    result.'init'('node'=>node, 'name'=>$S0, 'valtype'=>'constant')      
    .return (result)             

  err_no_tree:
    print "The CONSTANT node doesn't contain a 'constant' match.\n"
    end
}

transform result (Cardinal::Grammar::op) :language('PIR') {
    $S0 = node

    .local pmc result
    result = new 'Cardinal::PAST::Val'
    result.'init'('node'=>node, 'name'=>$S0, 'valtype'=>'op')      
    .return (result)             

  err_no_tree:
    print "The op node doesn't contain an 'op' match.\n"
    end
}

transform result (Cardinal::Grammar::atom) :language('PIR') {
    .local pmc child
    $I0 = defined node['literal']
    unless $I0 goto try_string
    $P0 = node['literal']
    child = tree.get('result', $P0, 'Cardinal::Grammar::literal')
    goto done
    
  try_string:
    $I0 = defined node['string']
    unless $I0 goto try_variable
    $P0 = node['string']
    child = tree.get('result', $P0, 'Cardinal::Grammar::string')
    goto done

  try_variable:
    $I0 = defined node['variable']
    unless $I0 goto try_expression 
    $P0 = node['variable']
    child = tree.get('result', $P0, 'Cardinal::Grammar::variable')
    goto done

  try_expression:
    $I0 = defined node['expression']
    unless $I0 goto err_no_tree
    $P0 = node['expression']
    child = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    goto done

done:
    .return (child)

err_no_tree:
    print "The atom node doesn't contain an appropriate match.\n"
    .kdump2(node, "atom")
    end
}
    
transform result (Cardinal::Grammar::lang_statements) :language('PIR') {
    .local pmc child
    $I0 = defined node['begin']
    unless $I0 goto try_if_clause
    .local pmc block
    $P0 = self.'top_scope_stack'()
    block = new 'Cardinal::PAST::Block'
    block.'init'('node'=>node, 'blocktype'=>'begin', 'outer'=>$P0)

    $P0 = node['body_statement']
    self.'push_scope_stack'(block)
    child = tree.get('result', $P0, 'Cardinal::Grammar::body_statement')
    self.'pop_scope_stack'()

    block.'add_child'(child)
    .return (block)
  
  try_if_clause:
    $I0 = defined node['if_clause']
    unless $I0 goto try_while_until_statement
    $P0 = node['if_clause']
    child = tree.get('result', $P0, 'Cardinal::Grammar::if_clause')
    .return (child)

  try_while_until_statement:
    .local pmc test
    .local pmc body
    .local pmc result

    $I0 = defined node['while_until']
    unless $I0 goto try_for_statement
    $P0 = node['while_until']
    $S0 = $P0

    result = new 'Cardinal::PAST::WhileUntil'
    result.'init'('node'=>node, 'name'=>$S0)
  
    $I0 = defined node['expression']
    unless $I0 goto while_err_no_tree
    $P0 = node['expression']
    test = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    result.add_child(test)

    $I0 = defined node['compound_statement']
    unless $I0 goto while_err_no_tree
    $P0 = node['compound_statement']
    body = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    result.add_child(body)

    .return (result)             
  
  while_err_no_tree:
    print "while or until node inline\n"
    print "The while or until node doesn't contain an appropriate match.\n"
    .kdump2(node, "while_statement")
    end

#    $I0 = defined node['while_until']
#    unless $I0 goto try_for_statement
#    child = tree.get('result', node, 'Cardinal::Grammar::while_until_statement')
#    .return (child)

  try_for_statement:
    $I0 = defined node['for']
    unless $I0 goto try_def

    .local pmc var
    .local pmc test
    .local pmc body
    .local pmc result

    result = new 'Cardinal::PAST::For'
    result.'init'('node'=>node)
  
    $I0 = defined node['for_variable']
    unless $I0 goto for_err_no_tree
    $P0 = node['for_variable']
    var = tree.get('result', $P0, 'Cardinal::Grammar::for_variable')
    result.add_child(var)

    $I0 = defined node['expression']
    unless $I0 goto for_err_no_tree
    $P0 = node['expression']
    test = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    result.add_child(test)

    $I0 = defined node['compound_statement']
    unless $I0 goto for_err_no_tree
    $P0 = node['compound_statement']
    body = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    result.add_child(body)

    .return (result)             
  
  for_err_no_tree:
    print "The for node doesn't contain an appropriate match.\n"
    .kdump2(node, "while_statement")
    end

#    $I0 = defined node['for']
#    unless $I0 goto try_def
#    child = tree.get('result', node, 'Cardinal::Grammar::for')
#    .return (child)

  try_def:
    $I0 = defined node['def']
    unless $I0 goto try_class
    .local pmc function
    .local string function_name
    $P0 = node['function_name']
    function_name = tree.get('result', $P0, 'Cardinal::Grammar::function_name')

    $P0 = self.'top_scope_stack'()
    $S0 = $P0.'blocktype'()
    .local string function_blocktype
    
    function_blocktype = 'function'
    unless $S0 == 'class' goto is_function
      function_blocktype = 'method'
    is_function:
    
    function = new 'Cardinal::PAST::Block'
    function.'init'('node'=>node, 'name'=>function_name, 'blocktype'=>function_blocktype, 'outer'=>$P0)
    $P0 = node['function_prototype_arg_list']
    
    self.'add_to_current_block'(function_name, function)

    self.'push_scope_stack'(function)

    child = tree.get('result', $P0, 'Cardinal::Grammar::function_prototype_arg_list')
   
  if_null child, no_params 
    .local pmc iter
    iter = new .Iterator, child
  iter_loop1:
    unless iter, iter_end1
    shift $P1, iter
    function.'add_child'($P1)
    goto iter_loop1
  iter_end1:
  no_params:

    $P0 = node['body_statement']
    child = tree.get('result', $P0, 'Cardinal::Grammar::body_statement')
    self.'pop_scope_stack'()
    function.'add_child'(child)
    .return (function)
  
  try_class:
    $I0 = defined node['class']
    unless $I0 goto try_module

    $P0 = self.'top_scope_stack'()
    .local pmc class_block
    class_block = new 'Cardinal::PAST::Class'
    class_block.'init'('node'=>node, 'name'=>function_name, 'blocktype'=>'class', 'outer'=>$P0)

    $I0 = defined node['class_path']
    unless $I0 goto err_no_tree
    $P0 = node['class_path']
    child = tree.get('result', $P0, 'Cardinal::Grammar::class_path')
    class_block.'class_path'(child)


    $I0 = defined node['superclass']
    unless $I0 goto err_no_tree
    $P0 = node['superclass']
    child = tree.get('result', $P0, 'Cardinal::Grammar::superclass')
    if_null child, class_body
    class_block.'add_child'(child)

  class_body:
    $P0 = node['body_statement']
    self.'push_scope_stack'(class_block)
    child = tree.get('result', $P0, 'Cardinal::Grammar::body_statement')
    self.'pop_scope_stack'()
    class_block.'add_child'(child)
    .return (class_block)

  try_module:
    $I0 = defined node['module']
    unless $I0 goto err_no_tree

    $P0 = self.'top_scope_stack'()
    .local pmc module_block
    module_block = new 'Cardinal::PAST::Module'
    module_block.'init'('node'=>node, 'name'=>function_name, 'blocktype'=>'module', 'outer'=>$P0)

    $I0 = defined node['class_path']
    unless $I0 goto err_no_tree
    $P0 = node['class_path']
    child = tree.get('result', $P0, 'Cardinal::Grammar::class_path')
    module_block.'add_child'(child)

  module_body:
    $P0 = node['body_statement']
    self.'push_scope_stack'(module_block)
    child = tree.get('result', $P0, 'Cardinal::Grammar::body_statement')
    self.'pop_scope_stack'()
    module_block.'add_child'(child)
    .return (module_block)

  err_no_tree:
    print "The lang_statements node doesn't contain an appropriate match.\n"
    .kdump2(node, "lang_statements")
    end
}

transform result (Cardinal::Grammar::while_until_statement) :language('PIR') {
    .local pmc test
    .local pmc body
    .local pmc result

    $I0 = defined node['while_until']
    unless $I0 goto err_no_tree
    $P0 = node['while_until']
    $S0 = $P0

    result = new 'Cardinal::PAST::WhileUntil'
    result.'init'('node'=>node, 'name'=>$S0)
  
    $I0 = defined node['expression']
    unless $I0 goto err_no_tree
    $P0 = node['expression']
    test = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    result.add_child(test)

    $I0 = defined node['compound_statement']
    unless $I0 goto err_no_tree
    $P0 = node['compound_statement']
    body = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    result.add_child(body)

    .return (result)             
  
  err_no_tree:
    print "while_until_statement\n"
    print "The while or until node doesn't contain an appropriate match.\n"
    .kdump2(node, "while_until_statement")
    end
}

transform result (Cardinal::Grammar::for_statement) :language('PIR') {
    .local pmc var
    .local pmc test
    .local pmc body
    .local pmc result

    result = new 'Cardinal::PAST::For'
    result.'init'('node'=>node)
  
    $I0 = defined node['for_variable']
    unless $I0 goto err_no_tree
    $P0 = node['for_variable']
    var = tree.get('result', $P0, 'Cardinal::Grammar::for_variable')
    result.add_child(var)

    $I0 = defined node['expression']
    unless $I0 goto err_no_tree
    $P0 = node['expression']
    test = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    result.add_child(test)

    $I0 = defined node['compound_statement']
    unless $I0 goto err_no_tree
    $P0 = node['compound_statement']
    body = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    result.add_child(body)

    .return (result)             
  
  err_no_tree:
    print "The for node doesn't contain an appropriate match.\n"
    .kdump2(node, "while_statement")
    end
}

transform result (Cardinal::Grammar::for_variable) :language('PIR') {
    .local pmc var

    $I0 = defined node['left_hand_side']
    unless $I0 goto err_no_tree
    $P0 = node['left_hand_side']
    var = tree.get('result', $P0, 'Cardinal::Grammar::left_hand_side')
    .return (var)

    $I0 = defined node['multiple_left_hand_side']
    unless $I0 goto err_no_tree
    $P0 = node['multiple_left_hand_side']
    var = tree.get('result', $P0, 'Cardinal::Grammar::multiple_left_hand_side')

    .return (var)
  
  err_no_tree:
    print "The for_variable node doesn't contain an appropriate match.\n"
    .kdump2(node, "for_variable")
    end
}

transform result (Cardinal::Grammar::function_name) :language('PIR') {
    .local pmc op
    .local pmc child
    $I0 = defined node['IDENTIFIER']
    unless $I0 goto n1
    $P0 = node['IDENTIFIER']
    child = tree.get('result', $P0, 'Cardinal::Grammar::IDENTIFIER')
    goto finish
    n1:
    $I0 = defined node['CONSTANT']
    unless $I0 goto n2
    $P0 = node['CONSTANT']
    child = tree.get('result', $P0, 'Cardinal::Grammar::CONSTANT')
    goto finish
    n2:
    $I0 = defined node['FID']
    unless $I0 goto n3
    $P0 = node['FID']
    child = tree.get('result', $P0, 'Cardinal::Grammar::FID')
    goto finish
    n3:
    $I0 = defined node['op']
    unless $I0 goto n4
    $P0 = node['op']
    child = tree.get('result', $P0, 'Cardinal::Grammar::op')
    goto finish
    n4:
    $I0 = defined node['reserved_words']
    unless $I0 goto err_no_tree
    $P0 = node['reserved_words']
    child = tree.get('result', $P0, 'Cardinal::Grammar::reserved_words')
    goto finish
    finish:
    $S0 = child
    .return ($S0)

  err_no_tree:
    print "The function_name node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_name')
    end
}
transform result (Cardinal::Grammar::class_path) :language('PIR') {
    .local pmc result
    .local pmc child
    result = new 'Cardinal::PAST::ClassPath'
    result.'init'('node'=>node, 'name'=>'class_path')
    $S0 = node
    result.'class_name'($S0)
    
    $I0 = defined node['starting_colons']
    unless $I0 goto atoms
    $P0 = node['starting_colons']
    result.'starting_colons'(1)

  atoms:
    $I0 = defined node['atom']
    unless $I0 goto get_name
    $P0 = node['atom']

    .local pmc iter
    iter = new .Iterator, $P0
  iter_loop:
    unless iter goto iter_end
    $P1 = shift iter
    child = tree.get('result', $P1, 'Cardinal::Grammar::atom')
    result.'add_child'(child)
    goto iter_loop
  iter_end:

  get_name:
    $I0 = defined node['class_name']
    unless $I0 goto err_no_tree
    $S0 = node['class_name']
    result.'add_child'($S0)

    .return (result)

  err_no_tree:
    print "The class_path node doesn't contain a the right component matches.\n"
    .kdump(node)
    end
}

transform result (Cardinal::Grammar::superclass) :language('PIR') {
    .local pmc result
    .local pmc child
    result = new 'Cardinal::PAST::Op'
    result.'init'('node'=>node, 'name'=>'superclass')
    
    $I0 = defined node['expression']
    unless $I0 goto try_error
    $P0 = node['expression'; 0]
    child = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    .return (child)

  try_error:
    $I0 = defined node['error']
    unless $I0 goto just_return
    $P0 = node['error']
    child = tree.get('result', $P0, 'Cardinal::Grammar::error')
    .return (child)

  just_return:
    null $P0
    .return ($P0)

  err_no_tree:
    print "The superclass node doesn't contain a the right component matches.\n"
    .kdump(node)
    end
}

transform result (Cardinal::Grammar::function_prototype_arg_list) :language('PIR') {
    .local pmc child
    $I0 = defined node['function_prototype_args']
    unless $I0 goto return_empty
    $P0 = node['function_prototype_args'; 0]
    child = tree.get('result', $P0, 'Cardinal::Grammar::function_prototype_args')
    .return (child)
  return_empty:
    null $P0
    .return ($P0)

  err_no_tree:
    print "The function_prototype_arg_list node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_prototype_arg_list')
    end
}

transform result (Cardinal::Grammar::function_prototype_args) :language('PIR') {
    .local pmc child
    .local pmc arg_list
    arg_list = new .ResizablePMCArray

    $I0 = defined node['function_prototype_positional_arg_list']
    unless $I0 goto n1
    $P1 = node['function_prototype_positional_arg_list']
    child = tree.get('result', $P1, 'Cardinal::Grammar::function_prototype_positional_arg_list')
    arg_list.'append'(child)

    n1:
    $I0 = defined node['function_prototype_optional_arg_list']
    unless $I0 goto n2
    $P1 = node['function_prototype_optional_arg_list']
    child = tree.get('result', $P1, 'Cardinal::Grammar::function_prototype_optional_arg_list')
    arg_list.'append'(child)

    n2:
    $I0 = defined node['function_prototype_rest_args']
    unless $I0 goto n3
    $P1 = node['function_prototype_rest_args']
    child = tree.get('result', $P1, 'Cardinal::Grammar::function_prototype_rest_args')
    push arg_list, child

    n3:
    $I0 = defined node['function_prototype_block_arg']
    unless $I0 goto n4
    $P1 = node['function_prototype_block_arg']
    child = tree.get('result', $P1, 'Cardinal::Grammar::function_prototype_block_arg')
    push arg_list, child

    n4:
    .return (arg_list)

  err_no_tree:
    print "The function_prototype_args node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_prototype_args')
    end
}

transform result (Cardinal::Grammar::function_prototype_positional_arg_list) :language('PIR') {
    .local pmc child
    .local pmc arg_list
    arg_list = new .ResizablePMCArray

    $I0 = defined node['function_prototype_arg']
    unless $I0 goto n1
    $P0 = node['function_prototype_arg']
    
    .local pmc iter
    iter = new .Iterator, $P0
  iter_loop:
    unless iter, iter_end
    shift $P1, iter
    child = tree.get('result', $P1, 'Cardinal::Grammar::function_prototype_arg')
    push arg_list, child
    goto iter_loop
  iter_end:
   
  n1: 
    .return (arg_list)

  err_no_tree:
    print "The function_prototype_positional_arg_list node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_prototype_positional_arg_list')
    end
}

transform result (Cardinal::Grammar::function_prototype_optional_arg_list) :language('PIR') {
    .local pmc child
    .local pmc arg_list
    arg_list = new .ResizablePMCArray

    $I0 = defined node['function_prototype_optional_arg']
    unless $I0 goto n1
    $P0 = node['function_prototype_optional_arg']
    
    .local pmc iter
    iter = new .Iterator, $P0
  iter_loop:
    unless iter, iter_end
    shift $P1, iter
    child = tree.get('result', $P1, 'Cardinal::Grammar::function_prototype_optional_arg')
    push arg_list, child
    goto iter_loop
  iter_end:

  n1:
    .return (arg_list)
  
  err_no_tree:
    print "The function_prototype_optional_arg_list node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_prototype_optional_arg_list')
    end
}


transform result (Cardinal::Grammar::function_prototype_arg) :language('PIR') {
    .local pmc op
    .local pmc child
    .local string type
    
    $I0 = defined node['IDENTIFIER']
    unless $I0 goto n1
    $P0 = node['IDENTIFIER']
    child = tree.get('result', $P0, 'Cardinal::Grammar::IDENTIFIER')
    type = 'normal'
    goto finish
    n1:
    $I0 = defined node['CONSTANT']
    unless $I0 goto n2
    $P0 = node['CONSTANT']
    child = tree.get('result', $P0, 'Cardinal::Grammar::CONSTANT')
    type = 'normal'
    goto finish
    n2:
    $I0 = defined node['INSTANCE_VARIABLE']
    unless $I0 goto n3
    $P0 = node['INSTANCE_VARIABLE']
    child = tree.get('result', $P0, 'Cardinal::Grammar::INSTANCE_VARIABLE')
    type = 'instance'
    goto finish
    n3:
    $I0 = defined node['GLOBAL_VARIABLE']
    unless $I0 goto n4
    $P0 = node['GLOBAL_VARIABLE']
    child = tree.get('result', $P0, 'Cardinal::Grammar::GLOBAL_VARIABLE')
    type = 'global'
    goto finish
    n4:
    $I0 = defined node['CLASS_VARIABLE']
    unless $I0 goto err_no_tree
    $P0 = node['CLASS_VARIABLE']
    child = tree.get('result', $P0, 'Cardinal::Grammar::CLASS_VARIABLE')
    type = 'class'
    goto finish
    finish:
    $S0 = child
    op = new 'Cardinal::PAST::PositionalParameter'
    op.'init'('node'=>node, 'name'=>$S0, 'scope'=>'parameter', 'type'=>type)
    self.'add_to_current_block'($S0, op)
    .return (op)

  err_no_tree:
    print "The function_prototype_arg node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_prototype_arg')
    end
}

transform result (Cardinal::Grammar::function_prototype_optional_arg) :language('PIR') {
    .local pmc op
    .local pmc child
    .local pmc expression
    $I0 = defined node['IDENTIFIER']
    unless $I0 goto err_no_tree
    $P0 = node['IDENTIFIER']
    child = tree.get('result', $P0, 'Cardinal::Grammar::IDENTIFIER')
    $S0 = child
    $P0 = node['expression']
    expression = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    op = new 'Cardinal::PAST::OptionalParameter'
    op.'init'('node'=>node, 'name'=>$S0, 'scope'=>'parameter', 'default_value'=>expression)
    self.'add_to_current_block'($S0, op)
    .return (op)

  err_no_tree:
    print "The function_prototype_optional_arg node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_prototype_optional_arg')
    end
}

transform result (Cardinal::Grammar::function_prototype_rest_args) :language('PIR') {
    .local pmc op
    .local pmc child
    $I0 = defined node['IDENTIFIER']
    unless $I0 goto err_no_tree
    $P0 = node['IDENTIFIER']
    child = tree.get('result', $P0, 'Cardinal::Grammar::IDENTIFIER')
    $S0 = child
    op = new 'Cardinal::PAST::RestParameter'
    op.'init'('node'=>node, 'name'=>$S0, 'scope'=>'parameter')
    self.'add_to_current_block'($S0, op)
    .return (op)

  err_no_tree:
    print "The function_prototype_rest_arg_list node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_prototype_rest_arg_list')
    end
}

transform result (Cardinal::Grammar::function_prototype_block_arg) :language('PIR') {
    .local pmc op
    .local pmc child
    $I0 = defined node['IDENTIFIER']
    unless $I0 goto err_no_tree
    $P0 = node['IDENTIFIER']
    child = tree.get('result', $P0, 'Cardinal::Grammar::IDENTIFIER')
    $S0 = child
    op = new 'Cardinal::PAST::BlockParameter'
    op.'init'('node'=>node, 'name'=>$S0, 'scope'=>'parameter')
    self.'add_to_current_block'($S0, op)
    .return (op)

  err_no_tree:
    print "The function_prototype_block_arg node doesn't contain a the right component matches.\n"
    .kdump2(node, 'function_prototype_block_arg')
    end
}

transform result (Cardinal::Grammar::if_clause) :language('PIR') {
    .local pmc child
    .local pmc op
    op = new 'Cardinal::PAST::Op'
    op.'init'('node'=>node, 'name'=>'if')

    $I0 = defined node['expression']
    unless $I0 goto err_no_tree
    $P0 = node['expression']
    child = tree.get('result', $P0, 'Cardinal::Grammar::expression')
    op.'add_child'(child)

    $I0 = defined node['compound_statement']
    unless $I0 goto err_no_tree
    $P0 = node['compound_statement']
    child = tree.get('result', $P0, 'Cardinal::Grammar::compound_statement')
    op.'add_child'(child)

    $I0 = defined node['elsif_clause']
    unless $I0 goto n1
    $P0 = node['elsif_clause']
    child = tree.get('result', $P0, 'Cardinal::Grammar::elsif_clause')
    op.'add_child'(child)

  n1:
    $I0 = defined node['else_clause']
    unless $I0 goto n2
    $P0 = node['else_clause']
    child = tree.get('result', $P0, 'Cardinal::Grammar::else_clause')
    op.'add_child'(child)

  n2:
    .return (op)


  err_no_tree:
    print "The if_clause node doesn't contain a the right component matches.\n"
    .kdump2(node, 'if_clause')
    end
}

transform result (Cardinal::Grammar::string) :language('PIR') {

    # Ask the child node for its result
    .local pmc child
    $I0 = defined node['DOUBLE_STRING']
    unless $I0 goto try_string2
    $P0 = node['DOUBLE_STRING']
    child = tree.get('result', $P0, 'Cardinal::Grammar::DOUBLE_STRING')
    goto done

  try_string2:
    $I0 = defined node['SINGLE_STRING']
    unless $I0 goto err_no_tree
    $P0 = node['SINGLE_STRING']
    child = tree.get('result', $P0, 'Cardinal::Grammar::SINGLE_STRING')

  done:
    .return (child)

  err_no_tree:
    print "The atom node doesn't contain a 'literal' or a 'string'  match.\n"
    end
}

transform result (Cardinal::Grammar::literal) :language('PIR') {
    # Ask the child node for its result
    .local pmc child
    $I0 = defined node['numeric']
    unless $I0 goto err_no_tree
    $P0 = node['numeric']
    child = tree.get('result', $P0, 'Cardinal::Grammar::numeric')
    goto done

  done:
    .return (child)

  err_no_tree:
    print "The literal node doesn't contain a 'numeric' match.\n"
    end
}

transform result (Cardinal::Grammar::numeric) :language('PIR') {
    # Ask the child node for its result
    .local pmc child
    $I0 = defined node['INTEGER']
    unless $I0 goto try_float
    $P0 = node['INTEGER']
    child = tree.get('result', $P0, 'Cardinal::Grammar::INTEGER')
    goto done
    
  try_float:
    $I0 = defined node['FLOAT']
    unless $I0 goto err_no_tree
    $P0 = node['FLOAT']
    child = tree.get('result', $P0, 'Cardinal::Grammar::FLOAT')
    goto done

  done:
    .return (child)

  err_no_tree:
    print "The numeric node doesn't contain a 'INTEGER', or a 'LOAT' match.\n"
    end
}

transform result (Cardinal::Grammar::INTEGER) :language('PIR') {
    $S0 = node 
    .local pmc result
    result = new 'Cardinal::PAST::Val'
    result.'init'('node'=>node, 'name'=>$S0, 'valtype'=>'Integer')      
    .return (result)             

    # Ask the child node for its result
    .local pmc child
    $I0 = defined node['DECIMAL']
    unless $I0 goto err_no_tree
    $P0 = node['DECIMAL']
    child = tree.get('result', $P0, 'Cardinal::Grammar::DECIMAL')

    .return (child)

  err_no_tree:
    print "The INTEGER node doesn't contain a 'DECIMAL' match.\n"
    end
}

transform result (Cardinal::Grammar::FLOAT) :language('PIR') {
    $S0 = node 
    .local pmc result
    result = new 'Cardinal::PAST::Val'
    result.'init'('node'=>node, 'name'=>$S0, 'valtype'=>'float')      
    .return (result)             

  err_no_tree:
    print "The FLOAT node doesn't contain a 'DECIMAL' match.\n"
    end
}

transform result (Cardinal::Grammar::DECIMAL) :language('PIR') {
    $S0 = node 
    .local pmc result
    result = new 'Cardinal::PAST::Val'
    result.'init'('node'=>node, 'name'=>$S0)
    .return (result)             

  err_no_tree:
    print "The DECIMAL node doesn't contain a 'YYY' match.\n"
    end
}

transform result (Cardinal::Grammar::DOUBLE_STRING) :language('PIR') {
    .local string value
    # Check if this is a string match
    $I0 = defined node["PGE::Text::bracketed"]
    if $I0 goto bracketed_value
    value = node
    goto no_bracketed_value
  bracketed_value:
    $P1 = node["PGE::Text::bracketed"]
    $P2 = $P1[0]
    value = $P2
  no_bracketed_value:

    .local pmc result
    result = new 'Cardinal::PAST::Val'
    result.'init'('node'=>node, 'name'=>value, 'valtype'=>'double_qutoed_string')
    .return (result)
}

transform result (Cardinal::Grammar::SINGLE_STRING) :language('PIR') {
    .local string value
    # Check if this is a string match
    $I0 = defined node["PGE::Text::bracketed"]
    if $I0 goto bracketed_value
    value = node
    goto no_bracketed_value
  bracketed_value:
    $P1 = node["PGE::Text::bracketed"]
    $P2 = $P1[0]
    value = $P2
  no_bracketed_value:

    .local pmc result
    result = new 'Cardinal::PAST::Val'
    result.'init'('node'=>node, 'name'=>value, 'valtype'=>'single_qutoed_string')
    .return (result)
}

transform result (Cardinal::Grammar::left_hand_side) :language('PIR') {
    # Ask the child node for its result
    .local pmc child
    $I0 = defined node['variable']
    unless $I0 goto err_no_tree
    $P0 = node['variable']
    child = tree.get('result', $P0, 'Cardinal::Grammar::variable')

    .return (child)

  err_no_tree:
    print "The left_hand_side node doesn't contain a 'variable' match.\n"
    end
}

transform result (Cardinal::Grammar::variable) :language('PIR') {
    $I0 = defined node['IDENTIFIER']
    unless $I0 goto constant_variable
    $S0 = node['IDENTIFIER']
    #$S0 = tree.get('result', $P0, 'Cardinal::Grammar::IDENTIFIER')
    goto case_end

  constant_variable:
    $I0 = defined node['CONSTANT']
    unless $I0 goto global_variable
    $S0 = node['CONSTANT']
    #$S0 = tree.get('result', $P0, 'Cardinal::Grammar::CONSTANT')
    goto case_end

  global_variable:
    $I0 = defined node['GLOBAL_VARIABLE']
    unless $I0 goto instance_variable
    $P0 = node['GLOBAL_VARIABLE']
    $P0 = tree.'get'('result', $P0, 'Cardinal::Grammar::GLOBAL_VARIABLE')
    .return ($P0)

  instance_variable:
    $I0 = defined node['INSTANCE_VARIABLE']
    unless $I0 goto class_variable
    $P0 = node['INSTANCE_VARIABLE']
    $P0 = tree.'get'('result', $P0, 'Cardinal::Grammar::INSTANCE_VARIABLE')
    .return ($P0)

  class_variable:
    $I0 = defined node['CLASS_VARIABLE']
    unless $I0 goto true_bool
    $P0 = node['CLASS_VARIABLE']
    $P0 = tree.'get'('result', $P0, 'Cardinal::Grammar::CLASS_VARIABLE')
    .return ($P0)

  true_bool:
    .local pmc bool_val
    bool_val = new 'Cardinal::PAST::Val'
    $S0 = node
    ne $S0, "true", false_bool
    bool_val.'init'('node'=>node, 'name'=>1, 'valtype'=>'boolean')
    .return (bool_val)
  false_bool:
    ne $S0, "false", err_no_tree
    bool_val.'init'('node'=>node, 'name'=>0, 'valtype'=>'boolean')
    .return (bool_val)

  case_end:
    .local pmc result
    $S1 = self.'variable_scope'($S0)
    eq $S1, 'func', func_call_without_args

    result = new 'Cardinal::PAST::Var'
    result.'init'('node'=>node, 'name'=> $S0, 'scope'=>$S1)
    ne $S1, 'lexical', return
    self.'add_to_current_block'($S0, result)
  return:
    .return (result)

  func_call_without_args:
    result = new 'Cardinal::PAST::FunctionCall'
    result.'init'('node'=>node, 'name'=> $S0)
    .return (result)

  err_no_tree:
    print "The variable node doesn't contain a valid variable match.\n"
    .kdump2(node, "VARIABLE NO MATCH")
    end
}

transform result (Cardinal::Grammar::GLOBAL_VARIABLE) :language('PIR') {
    $S0 = node
    .local pmc result
    result = new 'Cardinal::PAST::Var'
    result.'init'('node'=>node, 'name'=> $S0, 'scope'=>'global')
    .return (result)
}

transform result (Cardinal::Grammar::INSTANCE_VARIABLE) :language('PIR') {
    $S0 = node
    .local pmc result
    result = new 'Cardinal::PAST::Var'
    result.'init'('node'=>node, 'name'=> $S0, 'scope'=>'instance')
    .return (result)
}

transform result (Cardinal::Grammar::CLASS_VARIABLE) :language('PIR') {
    $S0 = node
    .local pmc result
    result = new 'Cardinal::PAST::Var'
    result.'init'('node'=>node, 'name'=> $S0, 'scope'=>'class')
    .return (result)
}



# The following rules are for the results of the operator precedence
# parser. These operate very differently than the standard grammar
# rules, because they give the node type in a "type" hash key inside the
# node, instead of storing the node as the value of a hash key that
# is their type.

transform op (expr) :language('PIR') {
    .local pmc result
    .local string type
    $S1 = node["type"]
    result = new 'Cardinal::PAST::Op'
    result.'init'('node'=>node, 'name'=>$S1)

    $P1 = node.get_array()
    .local pmc iter
    iter = new Iterator, $P1
    set iter, 0
  iter_loop:
    unless iter, iter_end
    shift $P2, iter
    
    type = $P2["type"]
    if type == 'term:' goto transform_term
      # else
      $P3 = tree.get('op', $P2, 'expr')
      if null $P3 goto iter_loop
      result.'add_child'($P3)
      goto iter_loop
    transform_term:
      $P3 = tree.get('term', $P2, 'expr')
      if null $P3 goto iter_loop
      result.'add_child'($P3)
      goto iter_loop
  iter_end:

    .return (result)
}

transform term (expr) :language('PIR') {
    .local pmc result
    .local pmc children
    children = new .ResizablePMCArray
    $P1 = node.get_hash()
    $P0 = new Iterator, $P1    # setup iterator for node
    set $P0, 0 # reset iterator, begin at start
  iter_loop:
    unless $P0, iter_end         # while (entries) ...
      shift $S2, $P0             # get key for next entry
      # skip 'type' keys added by the operator precedence parser
      if $S2 == 'type' goto iter_loop 
      $P2 = $P0[$S2]      # get entry at current key
      $S1 = 'Cardinal::Grammar::'
      $S1 .= $S2
      $P3 = tree.get('result', $P2, $S1)
      if null $P3 goto iter_loop
      push children, $P3
      goto iter_loop
  iter_end:

    $I0 = elements children
    unless $I0 == 1 goto err_too_many
    result = children[0]
    .return (result)

  err_too_many:
    print "error: Currently, 'term' nodes should have only one child.\n"
    .kdump2(node, 'term')
    end
}

=head1 LICENSE

Copyright (C) 2006, The Perl Foundation.

This is free software; you may redistribute it and/or modify
it under the same terms as Parrot.

=head1 AUTHOR

Kevin Tew <tewk@tewk.com>

=cut
