vc3/asm/resolve.c
2025-04-02 20:46:35 +02:00

113 lines
2.9 KiB
C

#include "resolve.h"
#include <stdlib.h>
#include <string.h>
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;
}