Files
fz-lang/src/vm/reader/vm_rd_extern_fns.c
T

235 lines
6.2 KiB
C

#include <common/fzl_extern.h>
#include <common/fzl_types.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vm/fzl_vm_reader.h>
#include <vm/internals/reader.h>
// Read external functions definitions
bool vm_rd_extern_fns(fzl_vm_reader_t *reader, FILE *fd)
{
if (!reader || !fd)
return false;
uint16_t fns_count = reader->extern_fns_count;
if (!fns_count)
return true;
reader->extern_fns = malloc(sizeof(fzl_extern_fn_t) * fns_count);
if (!reader->extern_fns)
{
snprintf(internal_error, sizeof(internal_error), "out of memory");
return false;
}
memset(reader->extern_fns, 0, sizeof(fzl_extern_fn_t) * fns_count);
for (uint16_t i = 0; i < fns_count; i++)
{
fzl_extern_fn_t *fn = &reader->extern_fns[i];
uint16_t lib_slot;
if (!vm_rd_u16(fd, 1, &lib_slot))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u lib slot", i);
return false;
}
fn->lib_slot = lib_slot;
uint16_t used_name_sz;
if (!vm_rd_u16(fd, 1, &used_name_sz))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u used name size", i);
return false;
}
char used_name_buf[256];
memset(used_name_buf, 0, sizeof(used_name_buf));
if (!vm_rd_char(fd, used_name_sz, used_name_buf))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u used name", i);
return false;
}
char *val = malloc(sizeof(char) * used_name_sz + 1);
if (!val)
{
snprintf(internal_error, sizeof(internal_error),
"out of memory on fn #%u used name allocation", i);
return false;
}
memset(val, 0, sizeof(char) * used_name_sz + 1);
memcpy(val, used_name_buf, sizeof(char) * used_name_sz);
fn->used_name = val;
char has_symbol_name;
if (!vm_rd_char(fd, 1, &has_symbol_name))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u symbol name existing flag", i);
return false;
}
if ((bool)has_symbol_name)
{
if (!vm_rd_u16(fd, 1, &used_name_sz))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u symbol name size", i);
return false;
}
if (!vm_rd_char(fd, used_name_sz, used_name_buf))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u symbol name", i);
return false;
}
char *symval = malloc(sizeof(char) * used_name_sz + 1);
if (!symval)
{
snprintf(internal_error, sizeof(internal_error),
"out of memory on fn #%u symbol name allocation", i);
return false;
}
memset(symval, 0, sizeof(char) * used_name_sz + 1);
memcpy(symval, used_name_buf, sizeof(char) * used_name_sz);
fn->symbol_name = symval;
}
char has_return;
if (!vm_rd_char(fd, 1, &has_return))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u return existing flag", i);
return false;
}
fn->has_return = (bool)has_return;
if ((bool)has_return)
{
char is_primitive;
if (!vm_rd_char(fd, 1, &is_primitive))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u return type primitivity flag", i);
return false;
}
fn->ret_type.is_primitive = (bool)is_primitive;
if (is_primitive)
{
char primitive;
if (!vm_rd_char(fd, 1, &primitive))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u return primitive", i);
return false;
}
fn->ret_type.primitive = (fzl_type_t)primitive;
}
else
{
uint16_t type_slot;
if (!vm_rd_u16(fd, 1, &type_slot))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u return type slot", i);
return false;
}
fn->ret_type.type_slot = (size_t)type_slot;
}
}
uint16_t args_count;
if (!vm_rd_u16(fd, 1, &args_count))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u arguments count", i);
return false;
}
fn->args_count = (size_t)args_count;
if (args_count > 0)
{
fzl_extern_arg_t *args = malloc(sizeof(fzl_extern_arg_t) * args_count);
if (!args)
{
snprintf(internal_error, sizeof(internal_error),
"out of memory on fn #%u arguments array allocation", i);
return false;
}
memset(args, 0, sizeof(fzl_extern_arg_t) * args_count);
fn->args = args;
for (uint16_t j = 0; j < args_count; j++)
{
fzl_extern_arg_t *arg = &args[j];
char arg_is_out;
if (!vm_rd_char(fd, 1, &arg_is_out))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u arg #%u out flag", i, j);
return false;
}
arg->is_out = (bool)arg_is_out;
char arg_is_primitive;
if (!vm_rd_char(fd, 1, &arg_is_primitive))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u arg #%u return type primitivity flag",
i, j);
return false;
}
arg->type.is_primitive = (bool)arg_is_primitive;
if (arg_is_primitive)
{
char primitive;
if (!vm_rd_char(fd, 1, &primitive))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u #%u return primitive", i, j);
return false;
}
arg->type.primitive = (fzl_type_t)primitive;
}
else
{
uint16_t type_slot;
if (!vm_rd_u16(fd, 1, &type_slot))
{
snprintf(internal_error, sizeof(internal_error),
"failed to read fn #%u #%u return type slot", i, j);
return false;
}
arg->type.type_slot = (size_t)type_slot;
}
}
}
}
return true;
}