roza/lib/program.c

158 lines
3.8 KiB
C

#include "program.h"
#include "value.h"
void program_init(program_t* program)
{
assert(program);
program->size = 0;
program->cap = 0;
program->ops = NULL;
program->params = NULL;
program->values.cap = 0;
program->values.size = 0;
program->values.data = NULL;
}
program_t* program_new_clone(program_t* program)
{
assert(program);
program_t* clone = malloc(sizeof(program_t));
program_init(clone);
for (size_t i=0; i<program->size; i++)
{
program_push_instr(clone,
program->ops[i],
program->params[i]);
}
for (size_t i=0; i<program->values.size; i++)
{
char m[512]; value_str(program->values.data[i], m, 512);
program_push_new_value(clone,
value_new_clone(program->values.data[i]));
}
return clone;
}
void program_free(program_t* program)
{
assert(program);
for (size_t i=0; i<program->values.size; i++)
{
value_free((value_t*) program->values.data[i]);
free(program->values.data[i]);
program->values.data[i] = NULL;
}
free(program->values.data);
program->values.data = NULL;
program->values.size = 0;
program->values.cap = 0;
free(program->ops);
free(program->params);
program->size = 0;
program->cap = 0;
}
size_t program_push_instr(program_t* program, Opcode op, param_t param)
{
assert(program);
if (program->cap == 0)
{
program->cap = 2;
program->ops = malloc(sizeof(Opcode) * program->cap);
program->params = malloc(sizeof(param_t) * program->cap);
}
if (program->size >= program->cap)
{
program->cap *= 2;
program->ops = realloc(program->ops,
sizeof(Opcode) * program->cap);
program->params = realloc(program->params,
sizeof(param_t) * program->cap);
}
program->ops[program->size] = op;
program->params[program->size] = param;
program->size++;
return program->size - 1;
}
size_t program_push_new_value(program_t* program, struct value* value)
{
assert(program);
assert(value);
for (size_t i=0; i<program->values.size; i++)
{
assert(program->values.data[i] != value);
}
if (program->values.size == 0)
{
program->values.cap = 2;
program->values.data = malloc(sizeof(struct value*)
* program->values.cap);
}
if (program->values.size >= program->values.cap)
{
program->values.cap *= 2;
program->values.data = realloc(program->values.data,
sizeof(struct value*)
* program->values.cap);
}
program->values.data[program->values.size] = value;
program->values.size++;
return program->values.size - 1;
}
size_t program_str(program_t* program, char* buffer, size_t size)
{
size_t sz = 0;
sz += snprintf(buffer + sz, size - sz, "======== VALUES ========\n");
for (size_t i=0; i<program->values.size; i++)
{
sz += snprintf(buffer + sz, size - sz, "%d| ", (int) i);
sz += value_str((value_t*) program->values.data[i],
buffer + sz, size - sz);
sz += snprintf(buffer + sz, size - sz, "\n");
}
sz += snprintf(buffer + sz, size - sz, "\n======== PROGRAM ========\n");
for (size_t i=0; i<program->size; i++)
{
if (program->params[i] != RZ_NO_PARAM)
{
sz += snprintf(buffer + sz, size - sz, "%d| %s %d\n",
(int) i,
OpcodeStr[program->ops[i]] + strlen("OP_"),
program->params[i]);
}
else
{
sz += snprintf(buffer + sz, size - sz, "%d| %s\n",
(int) i,
OpcodeStr[program->ops[i]] + strlen("OP_"));
}
}
return sz;
}