#include "resolve.h" #include #include void ident_resol_destroy(IdentResol* resol) { switch (resol->ty) { case IdentResolTy_None: break; case IdentResolTy_Label: case IdentResolTy_SubLabel: free(resol->ident); break; case IdentResolTy_Const: free(resol->ident); free(resol->src_filename); break; } } void ident_resolver_construct(IdentResolver* resolver) { size_t capacity = 512; *resolver = (IdentResolver) { .resols = malloc(sizeof(IdentResol) * capacity), .resols_capacity = capacity, .resols_size = 0, }; } void ident_resolver_destroy(IdentResolver* resolver) { for (size_t i = 0; i < resolver->resols_size; ++i) { ident_resol_destroy(&resolver->resols[i]); } free(resolver->resols); } static inline size_t ident_resolver_first_empty(IdentResolver* resolver) { size_t i = 0; for (; i < resolver->resols_size; ++i) { if (resolver->resols[i].ty == IdentResolTy_None) { break; } } if (i >= resolver->resols_size) { if (resolver->resols_size + 1 > resolver->resols_capacity) { resolver->resols_capacity *= 2; resolver->resols = realloc(resolver->resols, sizeof(IdentResol) * resolver->resols_capacity); } resolver->resols_size += 1; } return i; } void ident_resolver_define_label( IdentResolver* resolver, char* ident, Loc loc, uint16_t asm_ip) { size_t i = ident_resolver_first_empty(resolver); resolver->resols[i] = (IdentResol) { .ident = ident, .loc = loc, .ty = IdentResolTy_Label, .ip = asm_ip * 2, }; resolver->current_parent = &resolver->resols[i]; } void ident_resolver_define_sublabel( IdentResolver* resolver, char* ident, Loc loc, uint16_t asm_ip) { size_t i = ident_resolver_first_empty(resolver); resolver->resols[i] = (IdentResol) { .ident = ident, .loc = loc, .parent = resolver->current_parent, .ty = IdentResolTy_SubLabel, .ip = asm_ip * 2, }; } void ident_resolver_define_const(IdentResolver* resolver, char* ident, Loc loc, uint16_t value, char* src_filename) { size_t i = ident_resolver_first_empty(resolver); resolver->resols[i] = (IdentResol) { .ident = ident, .loc = loc, .ty = IdentResolTy_Const, .value = value, .src_filename = src_filename, }; } const IdentResol* ident_resolver_resolve( const IdentResolver* resolver, const char* ident) { for (size_t i = resolver->resols_size; i > 0; --i) { IdentResol* re = &resolver->resols[i - 1]; if (re->ty != IdentResolTy_None && strcmp(re->ident, ident) == 0 && (re->ty != IdentResolTy_SubLabel || re->parent == resolver->current_parent)) { return re; } } return NULL; }