53 lines
1.5 KiB
C
53 lines
1.5 KiB
C
|
|
#include "labeltable.h"
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
LabelTable_t* rava_labeltable_create(RavaInstructionList_t* instructions) {
|
||
|
|
if (!instructions) return NULL;
|
||
|
|
|
||
|
|
LabelTable_t* table = malloc(sizeof(LabelTable_t));
|
||
|
|
if (!table) return NULL;
|
||
|
|
|
||
|
|
int max_label = 0;
|
||
|
|
for (size_t i = 0; i < instructions->count; i++) {
|
||
|
|
if (instructions->instructions[i].opcode == RAVA_OP_LABEL) {
|
||
|
|
int lid = instructions->instructions[i].operand.label_id;
|
||
|
|
if (lid > max_label) max_label = lid;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
table->max_label_id = (size_t)max_label;
|
||
|
|
table->label_to_pc = calloc((size_t)(max_label + 1), sizeof(int));
|
||
|
|
if (!table->label_to_pc) {
|
||
|
|
free(table);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int i = 0; i <= max_label; i++) {
|
||
|
|
table->label_to_pc[i] = -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (size_t i = 0; i < instructions->count; i++) {
|
||
|
|
if (instructions->instructions[i].opcode == RAVA_OP_LABEL) {
|
||
|
|
int lid = instructions->instructions[i].operand.label_id;
|
||
|
|
table->label_to_pc[lid] = (int)(i + 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return table;
|
||
|
|
}
|
||
|
|
|
||
|
|
void rava_labeltable_destroy(LabelTable_t* table) {
|
||
|
|
if (!table) return;
|
||
|
|
free(table->label_to_pc);
|
||
|
|
free(table);
|
||
|
|
}
|
||
|
|
|
||
|
|
size_t rava_labeltable_lookup(LabelTable_t* table, int label_id) {
|
||
|
|
if (!table || label_id < 0 || (size_t)label_id > table->max_label_id) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
int pc = table->label_to_pc[label_id];
|
||
|
|
return (pc >= 0) ? (size_t)pc : 0;
|
||
|
|
}
|