2025-08-29 15:46:52 +01:00
|
|
|
#include "builder.h"
|
|
|
|
|
|
2025-09-08 15:42:22 +01:00
|
|
|
#include <blue/core/stringstream.h>
|
2025-08-29 15:46:52 +01:00
|
|
|
#include <mie/select/graph.h>
|
|
|
|
|
#include <mie/select/node.h>
|
|
|
|
|
#include <mie/select/opcode.h>
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
static const struct select_node_type *node_types[] = {
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
static const size_t nr_node_types = sizeof node_types / sizeof node_types[0];
|
|
|
|
|
|
|
|
|
|
const struct select_node_type *select_type_for_node(enum mie_select_opcode node)
|
|
|
|
|
{
|
|
|
|
|
if (node < 0 || node >= nr_node_types) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return node_types[node];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mie_select_node_iterator_next(struct mie_select_node_iterator *it)
|
|
|
|
|
{
|
|
|
|
|
b_queue_iterator_next(&it->it_base);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool mie_select_node_iterator_is_valid(const struct mie_select_node_iterator *it)
|
|
|
|
|
{
|
|
|
|
|
return b_queue_iterator_is_valid(&it->it_base);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_select_node *mie_select_node_create(
|
|
|
|
|
const struct mie_target *target, unsigned int op,
|
|
|
|
|
struct mie_type **results, size_t nr_results)
|
|
|
|
|
{
|
|
|
|
|
struct mie_select_node *out = malloc(sizeof *out);
|
|
|
|
|
if (!out) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
|
|
|
|
|
out->n_target = target;
|
|
|
|
|
out->n_opcode = op;
|
|
|
|
|
out->n_results = calloc(nr_results, sizeof(struct mie_type *));
|
|
|
|
|
if (!out->n_results) {
|
|
|
|
|
free(out);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out->n_nr_results = nr_results;
|
|
|
|
|
memcpy(out->n_results, results, nr_results * sizeof(struct mie_type *));
|
|
|
|
|
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mie_select_node_destroy(struct mie_select_node *node)
|
|
|
|
|
{
|
|
|
|
|
if (node->n_results) {
|
|
|
|
|
free(node->n_results);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mie_select_node_clear_operands(node);
|
|
|
|
|
|
|
|
|
|
free(node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum mie_status mie_select_node_set_operands(
|
|
|
|
|
struct mie_select_node *node, struct mie_select_value *operands,
|
|
|
|
|
size_t nr_operands)
|
|
|
|
|
{
|
|
|
|
|
mie_select_node_clear_operands(node);
|
|
|
|
|
if (!nr_operands) {
|
|
|
|
|
return MIE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_select_use *uses = calloc(nr_operands, sizeof *uses);
|
|
|
|
|
if (!uses) {
|
|
|
|
|
return MIE_ERR_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(uses, 0x0, sizeof *uses);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < nr_operands; i++) {
|
|
|
|
|
struct mie_select_node *operand_node = operands[i].v_node;
|
|
|
|
|
|
|
|
|
|
uses[i].u_user = node;
|
|
|
|
|
uses[i].u_value = operands[i];
|
|
|
|
|
|
|
|
|
|
b_queue_push_back(&operand_node->n_use, &uses[i].u_entry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
node->n_operands = uses;
|
|
|
|
|
node->n_nr_operands = nr_operands;
|
|
|
|
|
|
|
|
|
|
return MIE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum mie_status mie_select_node_clear_operands(struct mie_select_node *node)
|
|
|
|
|
{
|
|
|
|
|
struct mie_select_use_iterator it;
|
|
|
|
|
mie_select_use_foreach(&it, &node->n_use)
|
|
|
|
|
{
|
|
|
|
|
struct mie_select_use *use = mie_select_use_iterator_unbox(&it);
|
|
|
|
|
if (use->u_value.v_node == node) {
|
|
|
|
|
memset(&use->u_value, 0x0, sizeof use->u_value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (node->n_operands) {
|
|
|
|
|
free(node->n_operands);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
node->n_operands = NULL;
|
|
|
|
|
node->n_nr_operands = 0;
|
|
|
|
|
|
|
|
|
|
return MIE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mie_select_node_get_users(
|
|
|
|
|
struct mie_select_node *node, struct mie_select_node_iterator *it)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mie_select_node_get_uses(
|
|
|
|
|
struct mie_select_node *node, struct mie_select_node_iterator *it)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-08 15:42:22 +01:00
|
|
|
enum mie_status mie_select_node_get_value(
|
|
|
|
|
struct mie_select_node *node, struct mie_type *type, size_t index,
|
|
|
|
|
struct mie_select_value *out)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < node->n_nr_results; i++) {
|
|
|
|
|
if (!mie_type_compare(node->n_results[i], type)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (index > 0) {
|
|
|
|
|
index--;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out->v_node = node;
|
|
|
|
|
out->v_index = i;
|
|
|
|
|
return MIE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
return MIE_ERR_NO_ENTRY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum mie_status mie_select_node_set_description(
|
|
|
|
|
struct mie_select_node *node, const char *format, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list arg;
|
|
|
|
|
va_start(arg, format);
|
|
|
|
|
b_stringstream str;
|
|
|
|
|
b_stringstream_begin_dynamic(&str);
|
|
|
|
|
b_stringstream_addvf(&str, format, arg);
|
|
|
|
|
va_end(arg);
|
|
|
|
|
|
|
|
|
|
node->n_description = b_stringstream_end(&str);
|
|
|
|
|
return node->n_description ? MIE_SUCCESS : MIE_ERR_NO_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-29 15:46:52 +01:00
|
|
|
struct mie_select_node *mie_select_node_get_glued_node(struct mie_select_node *node)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_select_node *mie_select_node_get_glued_user(struct mie_select_node *node)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|