lang: codegen: redesign variable definition/resolution system to support capturing
the codegen scope system has been removed. instead, each generator state in the stack,
from the current state backwards, is informed when a variable is defined, resolved, or
captured.
when a variable is defined, the state stack is traversed back-to-front (current generator
first). each state has a chance to record the variable definition. once one state has
signalled that it has recorded the variable definition, the traversal ends.
when a variable is resolved, the state stack is traversed back-to-front (current generator
first). each state is asked whether or not it recognises the variable identifier being resolved.
if a state has the variable in question defined, it returns information about the variable
definition, and the traversal stops.
once a variable has been resolved, the state stack is traversed front-to-back (current generator
last), starting from the generator /after/ the one that provided the variable definition. each
generator in the iteration is given the chance to adjust the variable information, or generate
IR in response to the variable being accessed. this is used to implement variable capture,
where the state of a variable in the enclosing context is captured for later use.
2025-04-22 15:23:42 +01:00
|
|
|
#include "var-map.h"
|
|
|
|
|
|
2025-11-06 10:38:32 +00:00
|
|
|
#include <blue/ds/hashmap.h>
|
|
|
|
|
#include <blue/ds/string.h>
|
lang: codegen: redesign variable definition/resolution system to support capturing
the codegen scope system has been removed. instead, each generator state in the stack,
from the current state backwards, is informed when a variable is defined, resolved, or
captured.
when a variable is defined, the state stack is traversed back-to-front (current generator
first). each state has a chance to record the variable definition. once one state has
signalled that it has recorded the variable definition, the traversal ends.
when a variable is resolved, the state stack is traversed back-to-front (current generator
first). each state is asked whether or not it recognises the variable identifier being resolved.
if a state has the variable in question defined, it returns information about the variable
definition, and the traversal stops.
once a variable has been resolved, the state stack is traversed front-to-back (current generator
last), starting from the generator /after/ the one that provided the variable definition. each
generator in the iteration is given the chance to adjust the variable information, or generate
IR in response to the variable being accessed. this is used to implement variable capture,
where the state of a variable in the enclosing context is captured for later use.
2025-04-22 15:23:42 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
enum ivy_status codegen_var_map_init(struct codegen_var_map *map)
|
|
|
|
|
{
|
|
|
|
|
memset(map, 0x0, sizeof *map);
|
|
|
|
|
map->m_map = b_hashmap_create(free, free);
|
|
|
|
|
|
|
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ivy_status codegen_var_map_fini(struct codegen_var_map *map)
|
|
|
|
|
{
|
2025-11-06 10:38:32 +00:00
|
|
|
b_hashmap_unref(map->m_map);
|
lang: codegen: redesign variable definition/resolution system to support capturing
the codegen scope system has been removed. instead, each generator state in the stack,
from the current state backwards, is informed when a variable is defined, resolved, or
captured.
when a variable is defined, the state stack is traversed back-to-front (current generator
first). each state has a chance to record the variable definition. once one state has
signalled that it has recorded the variable definition, the traversal ends.
when a variable is resolved, the state stack is traversed back-to-front (current generator
first). each state is asked whether or not it recognises the variable identifier being resolved.
if a state has the variable in question defined, it returns information about the variable
definition, and the traversal stops.
once a variable has been resolved, the state stack is traversed front-to-back (current generator
last), starting from the generator /after/ the one that provided the variable definition. each
generator in the iteration is given the chance to adjust the variable information, or generate
IR in response to the variable being accessed. this is used to implement variable capture,
where the state of a variable in the enclosing context is captured for later use.
2025-04-22 15:23:42 +01:00
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ivy_status codegen_var_map_get(
|
|
|
|
|
struct codegen_var_map *map, const char *ident, struct codegen_var **out)
|
|
|
|
|
{
|
|
|
|
|
b_hashmap_key key = {
|
|
|
|
|
.key_data = ident,
|
|
|
|
|
.key_size = strlen(ident),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const b_hashmap_value *value = b_hashmap_get(map->m_map, &key);
|
|
|
|
|
|
|
|
|
|
if (!value) {
|
|
|
|
|
return IVY_ERR_NO_ENTRY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*out = value->value_data;
|
|
|
|
|
|
|
|
|
|
return IVY_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum ivy_status codegen_var_map_put(
|
|
|
|
|
struct codegen_var_map *map, const char *ident,
|
|
|
|
|
const struct codegen_var *var)
|
|
|
|
|
{
|
|
|
|
|
b_hashmap_key key = {
|
|
|
|
|
.key_data = b_strdup(ident),
|
|
|
|
|
.key_size = strlen(ident),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!key.key_data) {
|
|
|
|
|
return IVY_ERR_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b_hashmap_value value = {
|
|
|
|
|
.value_data = malloc(sizeof *var),
|
|
|
|
|
.value_size = sizeof *var,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!value.value_data) {
|
|
|
|
|
free((void *)key.key_data);
|
|
|
|
|
return IVY_ERR_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(value.value_data, var, sizeof *var);
|
|
|
|
|
|
|
|
|
|
b_status status = b_hashmap_put(map->m_map, &key, &value);
|
|
|
|
|
if (!B_OK(status)) {
|
|
|
|
|
free((void *)key.key_data);
|
|
|
|
|
free(value.value_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ivy_status_from_b_status(status);
|
|
|
|
|
}
|