parser
Dibyendu Majumdar 4 years ago
parent ed4e86cdae
commit 24b8a8e45c

@ -303,7 +303,7 @@ DECLARE_PTR_LIST(proc_list, struct proc);
enum opcode { op_nop, op_ret, op_loadk};
enum pseudo_type { PSEUDO_LOCAL, PSEUDO_TEMP, PSEUDO_TEMP_INT, PSEUDO_TEMP_ANY, PSEUDO_CONSTANT };
enum pseudo_type { PSEUDO_LOCAL, PSEUDO_TEMP_FLT, PSEUDO_TEMP_INT, PSEUDO_TEMP_ANY, PSEUDO_CONSTANT };
/* pseudo represents a pseudo (virtual) register */
struct pseudo {

@ -130,6 +130,31 @@ struct pseudo *allocate_constant_pseudo(struct proc *proc, const struct constant
return pseudo;
}
struct pseudo* allocate_temp_pseudo(struct proc* proc, ravitype_t type) {
struct pseudo_generator* gen;
enum pseudo_type pseudo_type;
switch (type) {
case RAVI_TNUMFLT:
gen = &proc->temp_int_pseudos;
pseudo_type = PSEUDO_TEMP_FLT;
break;
case RAVI_TNUMINT:
gen = &proc->temp_flt_pseudos;
pseudo_type = PSEUDO_TEMP_INT;
break;
default:
gen = &proc->temp_pseudos;
pseudo_type = PSEUDO_TEMP_ANY;
break;
}
unsigned reg = alloc_reg(gen);
struct pseudo* pseudo = dmrC_allocator_allocate(&proc->linearizer->pseudo_allocator, 0);
pseudo->type = pseudo_type;
pseudo->regnum = reg;
return pseudo;
}
/**
* Allocate a new proc. If there is a current proc, then the new proc gets added to the
* current procs children.
@ -187,10 +212,12 @@ static struct pseudo *linearize_literal(struct proc *proc, struct ast_node *expr
if (expr->literal_expr.type.type_code == RAVI_TNUMFLT || expr->literal_expr.type.type_code == RAVI_TNUMINT ||
expr->literal_expr.type.type_code == RAVI_TSTRING) {
struct pseudo *pseudo = allocate_constant_pseudo(proc, allocate_constant(proc, expr));
struct pseudo* target = allocate_temp_pseudo(proc, pseudo->constant->type);
struct instruction* insn = alloc_instruction(proc, op_loadk);
ptrlist_add((struct ptr_list**) &insn->operands, pseudo, &proc->linearizer->ptrlist_allocator);
ptrlist_add((struct ptr_list**) &insn->targets, target, &proc->linearizer->ptrlist_allocator);
ptrlist_add((struct ptr_list**) &proc->current_bb->insns, insn, &proc->linearizer->ptrlist_allocator);
return pseudo;
return target;
}
else {
abort();
@ -353,6 +380,7 @@ static struct basic_block *create_block(struct proc *proc) {
}
assert(proc->node_count < proc->allocated);
struct basic_block *new_block = dmrC_allocator_allocate(&proc->linearizer->basic_block_allocator, 0);
new_block->index = proc->node_count;
proc->nodes[proc->node_count++] = bb2n(new_block);
return new_block;
}
@ -422,11 +450,92 @@ static void linearize_function(struct linearizer *linearizer) {
end_scope(linearizer, proc);
}
void output_pseudo(struct pseudo *pseudo, membuff_t *mb)
{
switch (pseudo->type) {
case PSEUDO_CONSTANT: {
const struct constant* constant = pseudo->constant;
if (constant->type == RAVI_TNUMFLT) {
membuff_add_fstring(mb, "%.12f", constant->n);
}
else if (constant->type == RAVI_TNUMINT) {
membuff_add_fstring(mb, "%ld", constant->i);
}
else {
membuff_add_fstring(mb, "'%s'", getstr(constant->s));
}
membuff_add_fstring(mb, " K(%d)", pseudo->regnum);
} break;
case PSEUDO_TEMP_INT:
membuff_add_fstring(mb, "Tint(%d)", pseudo->regnum);
break;
case PSEUDO_TEMP_FLT:
membuff_add_fstring(mb, "Tflt(%d)", pseudo->regnum);
break;
case PSEUDO_TEMP_ANY:
membuff_add_fstring(mb, "T(%d)", pseudo->regnum);
break;
}
}
static const char* op_codenames[] = {
"NOOP",
"RET",
"LOADK"
};
void output_pseudo_list(struct pseudo_list* list, membuff_t* mb) {
struct pseudo* pseudo;
membuff_add_string(mb, " {");
int i = 0;
FOR_EACH_PTR(list, pseudo) {
if (i > 0) membuff_add_string(mb, ", ");
output_pseudo(pseudo, mb);
i++;
} END_FOR_EACH_PTR(pseudo);
membuff_add_string(mb, "}");
}
void output_instruction(struct instruction* insn, membuff_t* mb) {
membuff_add_fstring(mb, "\t%s", op_codenames[insn->opcode]);
if (insn->operands) {
output_pseudo_list(insn->operands, mb);
}
if (insn->targets) {
output_pseudo_list(insn->targets, mb);
}
membuff_add_string(mb, "\n");
}
void output_instructions(struct instruction_list* list, membuff_t* mb) {
struct instruction* insn;
FOR_EACH_PTR(list, insn) {
output_instruction(insn, mb);
} END_FOR_EACH_PTR(insn);
}
void output_basic_block(struct basic_block* bb, membuff_t* mb) {
membuff_add_fstring(mb, "L%d\n", bb->index);
output_instructions(bb->insns, mb);
}
void output_proc(struct proc* proc, membuff_t* mb) {
struct basic_block* bb;
for (int i = 0; i < proc->node_count; i++) {
bb = n2bb(proc->nodes[i]);
output_basic_block(bb, mb);
}
}
void raviA_ast_linearize(struct linearizer *linearizer, struct ast_container *container) {
ravi_init_linearizer(linearizer, container);
struct proc *proc = allocate_proc(linearizer, container->main_function);
set_main_proc(linearizer, proc);
set_current_proc(linearizer, proc);
linearize_function(linearizer);
membuff_t mb;
membuff_init(&mb, 1024);
output_proc(proc, &mb);
printf(mb.buf);
ravi_destroy_linearizer(linearizer);
}

Loading…
Cancel
Save