93 lines
2.5 KiB
C
93 lines
2.5 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;
|
|
}
|
|
}
|
|
|
|
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,
|
|
};
|
|
}
|
|
|
|
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;
|
|
}
|