parrotcode: Untitled | |
Contents | Compilers |
This file contains functions that convert the data structures that contain sub calls, return statements etc., created during the parse into a series of instructions that implement the Parrot Calling Conventions.
*/
#include "pirpcc.h" #include "pircompunit.h" #include "pircompiler.h" #include "pirerr.h" #include "pirsymbol.h"
#include "parrot/oplib/ops.h"
/*
static int calculate_pcc_target_flags(target *const result)
result
.
static int calculate_pcc_argument_flags(argument *const arg)
arg
.
An int encoding the flags is returned.
static target *generate_unique_pir_reg(lexer_state *const lexer, pir_type type)
type
.
It uses the reg
constructor to create a target node,
and using pir_reg_generator
field of lexer
the PIR register number is specified.
Because the positive PIR register numbers can be used in PIR code,
we use the negative numbers here,
for the reg() constructor this doesn't matter; a PIR register is always mapped to a PASM register,
so using negative PIR register is safe.
static int generate_signature_pmc(lexer_state *const lexer, unsigned size)
void emit_sub_epilogue(lexer_state *const lexer)
:main
sub,
the "end" instruction is emitted,
otherwise it's a standard return sequence.
static void add_alias_operand(lexer_state *const lexer, PMC *array, int index, char const *const alias)
array
is the signature array,
which must hold the right flags for this new operand (at position index
).
The alias name is passed in alias
.
static void targets_to_operands(lexer_state *const lexer, target *const targets)
target
nodes into operands.
Before the operands are added to the current instruction,
a FixedIntegerArray is created,
which contains one integer for each target (to be converted into an operand).
The integer encodes the type of the target (operand) and other flags,
such as :slurpy
etc.If one of the targets has the :named flag,
an extra operand is inserted,
which indicates a string constant,
containing the alias by which that target receives a value.
So,
in case of:
.param int i :named('answer')then the extra operand is a string constant (index in the PBC constant table) with value "answer".
static void arguments_to_operands(lexer_state *const lexer, argument *const args)
argument
nodes into operands. Before the operands are added to the current instruction, a FixedIntegerArray PMC is created which will hold one integer for each argument in the list. The integer at index i
encodes the type and flags (such as :flat
) for operand i
.
void generate_parameters_instr(lexer_state *const lexer, unsigned num_parameters)
void generate_getresults_instr(lexer_state *const lexer, target *const targetlist)
.get_results
statement.
static void save_global_reference(lexer_state *const lexer, instruction *const instr, char const *const label)
instr
, which references the global label label
in a list. After the parse phase, this instruction can be patched, if label
can be resolved during compile time.
static target *get_invoked_sub(lexer_state *const lexer, target *const sub)
target
node that represents the sub to invoke. If sub
is a register, that is returned. If it's a declared .local
, then a target node representing that symbol is returned. If it's just the name of a .sub, then there's 2 possibilities: either the sub was already parsed, in which case it's stored as a global_label, or the sub was not parsed yet, in which case a runtime resolving instruction is emitted.
static void convert_pcc_call(lexer_state *const lexer, invocation *const inv)
set_args_pc get_results_pc invokecc_p / invoke_p_pFor "foo"() and foo():
set_args_pc set_p_pc / find_sub_not_null_p_sc get_results_pc invokecc_p
static void convert_pcc_tailcall(lexer_state *const lexer, invocation *const inv)
set_args_pc tailcall_pc
static void convert_pcc_return(lexer_state *const lexer, invocation *const inv)
set_returns_pc returncc
static void convert_nci_call(lexer_state *const lexer, invocation *const inv)
set_args_pc get_results_pc invokecc_p
static void convert_pcc_yield(lexer_state *const lexer, invocation *const inv)
set_returns_pc yield
static void convert_pcc_methodcall(lexer_state *const lexer, invocation *const inv)
set_args_pc get_results_pc callmethodcc_p_sc
static void convert_pcc_methodtailcall(lexer_state *const lexer, invocation *const inv)
set_args_pc tailcallmethod_p_p / tailcallmethod_p_sc
void convert_inv_to_instr(lexer_state *const lexer, invocation *const inv)
invocation
structure into a series of instructions. This is the dispatch function, which calls the appropriate conversion function, based on the type of inv
.
|