wip: working on generator
- Feat: add extern type resolving to type slot - Feat: add extern block handling - Feat: add extern function handling
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#ifndef INTERNALS_GEN_H
|
||||
#define INTERNALS_GEN_H
|
||||
|
||||
#include <common/fzl_extern.h>
|
||||
#include <common/fzl_opcodes.h>
|
||||
#include <common/fzl_types.h>
|
||||
#include <compiler/fzl_gen.h>
|
||||
@@ -10,11 +11,13 @@
|
||||
#include <compiler/utils/fzl_symtable.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern char *null_name;
|
||||
|
||||
bool gen_resolve_name(fzl_gen_t *gen, char *name, fzl_sym_t *sym);
|
||||
bool gen_resolve_type(fzl_gen_t *gen, fzl_token_t *tok, fzl_type_t *t, char *c);
|
||||
ssize_t gen_resolve_extern_type(fzl_gen_t *gen, char *name);
|
||||
bool gen_is_types_compatible(fzl_type_t t1, fzl_type_t t2, char *c1, char *c2);
|
||||
size_t gen_add_const(fzl_gen_t *gen, fzl_const_t c);
|
||||
void gen_op(fzl_gen_t *gen, fzl_opcode_t opcode);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <common/fzl_extern.h>
|
||||
#include <compiler/fzl_gen.h>
|
||||
#include <compiler/internals/gen.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Extern block
|
||||
bool gen_extern(fzl_gen_t *gen, fzl_node_t *node)
|
||||
{
|
||||
if (!gen || !node)
|
||||
return false;
|
||||
|
||||
gen->extern_libs[gen->extern_libs_count++] =
|
||||
(fzl_extern_lib_t){.name = (char *)node->ext.libname};
|
||||
|
||||
for (size_t i = 0; i < node->ext.typedefs_count; i++)
|
||||
if (!gen_common(gen, node->ext.typedefs[i]))
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < node->ext.fns_count; i++)
|
||||
if (!gen_common(gen, node->ext.fns[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
#include <common/fzl_extern.h>
|
||||
#include <common/fzl_types.h>
|
||||
#include <compiler/fzl_gen.h>
|
||||
#include <compiler/fzl_parser.h>
|
||||
#include <compiler/internals/gen.h>
|
||||
#include <compiler/utils/fzl_symtable.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// External function definition
|
||||
bool gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
|
||||
{
|
||||
if (!gen || !node)
|
||||
return false;
|
||||
|
||||
fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_FUNCTION, node);
|
||||
if (!ctx)
|
||||
return false;
|
||||
|
||||
size_t args_remainder = 2;
|
||||
size_t args_count = 0;
|
||||
fzl_extern_arg_t *args = malloc(args_remainder * sizeof(fzl_extern_arg_t));
|
||||
if (!args)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < node->ext_fn.args_count; i++)
|
||||
{
|
||||
fzl_node_t *argnode = node->ext_fn.args[i];
|
||||
if (!gen_common(gen, argnode))
|
||||
return false;
|
||||
|
||||
if (args_count >= args_remainder)
|
||||
{
|
||||
args_remainder *= 2;
|
||||
fzl_extern_arg_t *newargs =
|
||||
realloc(args, args_remainder * sizeof(fzl_extern_arg_t));
|
||||
if (!newargs)
|
||||
{
|
||||
free(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
args = newargs;
|
||||
}
|
||||
|
||||
if (argnode->type != FZL_NODETYPE_DECLARATION)
|
||||
{
|
||||
free(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
fzl_extern_arg_t *arg = &args[args_count++];
|
||||
|
||||
fzl_type_t argtype;
|
||||
char argcn[256];
|
||||
memset(argcn, 0, sizeof(argcn));
|
||||
|
||||
bool resolved = gen_resolve_type(gen, argnode->var.type, &argtype, argcn);
|
||||
if (!resolved)
|
||||
{
|
||||
free(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t slot = gen_resolve_extern_type(gen, argcn);
|
||||
if (slot == -1)
|
||||
arg->type =
|
||||
(fzl_extern_type_ref_t){.is_primitive = true, .primitive = argtype};
|
||||
else
|
||||
arg->type =
|
||||
(fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot};
|
||||
|
||||
arg->name = (char *)argnode->var.identifier->token->value;
|
||||
arg->is_out = argnode->var.is_out;
|
||||
}
|
||||
|
||||
ctx = gen_fin_ctx(gen);
|
||||
if (!ctx)
|
||||
{
|
||||
free(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
fzl_type_t ret;
|
||||
char retname[256];
|
||||
memset(retname, 0, sizeof(retname));
|
||||
|
||||
bool resolved = gen_resolve_type(gen, node->ext_fn.type, &ret, retname);
|
||||
if (!resolved)
|
||||
{
|
||||
free(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
fzl_symtable_res_t res = fzl_symt_put(gen->syms[0], node, node->ext_fn.name,
|
||||
FZL_TYPE_EXTERN_FN, 0);
|
||||
if (res != FZL_SYMTABLE_RESULT_OK)
|
||||
{
|
||||
free(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
fzl_extern_fn_t *result = &gen->extern_fns[gen->extern_fns_count++];
|
||||
|
||||
ssize_t slot = gen_resolve_extern_type(gen, retname);
|
||||
if (slot == -1)
|
||||
result->ret_type =
|
||||
(fzl_extern_type_ref_t){.is_primitive = true, .primitive = ret};
|
||||
else
|
||||
result->ret_type =
|
||||
(fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot};
|
||||
|
||||
result->lib_slot = gen->extern_libs_count - 1;
|
||||
result->args = args;
|
||||
result->args_count = args_count;
|
||||
result->has_return = ret != FZL_TYPE_NULL;
|
||||
result->used_name = node->ext_fn.name;
|
||||
result->symbol_name = node->ext_fn.original_name;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -95,6 +95,21 @@ bool gen_resolve_type(fzl_gen_t *gen, fzl_token_t *tok, fzl_type_t *t, char *c)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolve external type
|
||||
ssize_t gen_resolve_extern_type(fzl_gen_t *gen, char *name)
|
||||
{
|
||||
if (!gen || !name)
|
||||
return -1;
|
||||
|
||||
for (size_t i = 0; i < gen->extern_types_count; i++)
|
||||
{
|
||||
if (strcmp(name, gen->extern_types[i].name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check if left and right types are compatible
|
||||
bool gen_is_types_compatible(fzl_type_t t1, fzl_type_t t2, char *c1, char *c2)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user