#include "as_analyzer.h" #include #include const char * compose_section_label(allocator_t alct, const char * section, const char * name) { size_t section_len = strlen(section); size_t name_len = strlen(name); size_t sz = section_len + name_len; char * buf = allocate(alct, sz + 1); memcpy(buf, section, section_len); memcpy(buf + section_len, name, name_len); buf[sz] = '\0'; return buf; } void process_section_label(allocator_t alct, prog_t prog) { const char * section = ""; stmt_t* stmts = prog->stmts->stmts; for (size_t i = 0; ; i++) { if (stmts[i] == NULL) break; if (stmts[i]->label == NULL) continue; const char* name = stmts[i]->label->name; if (name[0] == '.') { stmts[i]->label->name = compose_section_label(alct, section, name); } else { section = name; continue; } } } size_t instr_size(instr_t instr) { return op_size(instr->op); } struct sym_table new_sym_table(allocator_t alct) { struct sym_table tbl; tbl.cap = 16; tbl.size = 0; tbl.buf = allocate(alct, sizeof(struct sym_table_entry) * 16); return tbl; } void sym_table_add(allocator_t alct, struct sym_table* tbl, const char* name, int pos) { if (tbl->cap == tbl->size) { void *old_buf = tbl->buf; tbl->buf = allocate(alct, sizeof(struct sym_table_entry) * tbl->cap * 2); memcpy(tbl->buf, old_buf, sizeof(struct sym_table_entry) * tbl->cap); tbl->cap = tbl->cap * 2; } tbl->buf[tbl->size] = (struct sym_table_entry){.name = name, .offset = pos,}; tbl->size += 1; } struct sym_table analyze_prog(allocator_t alct, prog_t prog) { process_section_label(alct, prog); stmt_t * stmts = prog->stmts->stmts; struct sym_table tbl = new_sym_table(alct); size_t cur_pos = 0; for (int i = 0; ; i++) { if (stmts[i] == NULL) break; stmt_t stmt = stmts[i]; if (stmt->label) { sym_table_add(alct, &tbl, stmt->label->name, cur_pos); } if (stmt->instr) { cur_pos += instr_size(stmt->instr); } } return tbl; }