80 lines
2.2 KiB
C
80 lines
2.2 KiB
C
#include <common/fzl_types.h>
|
|
#include <compiler/fzl_gen.h>
|
|
#include <compiler/internals/gen.h>
|
|
#include <compiler/utils/fzl_symtable.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
char class_typecn[256];
|
|
|
|
// Class definition
|
|
gen_res_t gen_class(fzl_gen_t *gen, fzl_node_t *node)
|
|
{
|
|
if (!gen || !node)
|
|
return gen_error;
|
|
|
|
fzl_gen_ctx_t *ctx = gen_ctx(gen, FZL_GEN_CTX_TYPE_CLASS, node);
|
|
if (!ctx)
|
|
return gen_error;
|
|
|
|
gen->classes[gen->classes_count] = fzl_mkctable(node->class.name->value);
|
|
fzl_ctable_t *class = gen->classes[gen->classes_count++];
|
|
class->name = (char *)node->class.name->value;
|
|
|
|
for (size_t i = 0; i < node->class.fields_count; i++)
|
|
{
|
|
if (class->fields_remainder <= class->fields_count)
|
|
{
|
|
class->fields_remainder *= 2;
|
|
class->fields = realloc(class->fields, class->fields_remainder *
|
|
sizeof(fzl_ctable_field_t));
|
|
}
|
|
|
|
fzl_type_t type;
|
|
memset(class_typecn, 0, sizeof(class_typecn));
|
|
|
|
bool resolved = gen_resolve_type(gen, node->class.fields[i]->var.type,
|
|
&type, class_typecn);
|
|
if (!resolved)
|
|
return gen_error;
|
|
|
|
class->fields[class->fields_count] = (fzl_ctable_field_t){
|
|
.name = node->class.fields[i]->var.identifier->token->value,
|
|
.type = type,
|
|
.slot_index = class->fields_count++};
|
|
}
|
|
|
|
for (size_t i = 0; i < node->class.methods_count; i++)
|
|
{
|
|
fzl_node_t *fn = node->class.methods[i];
|
|
|
|
size_t classname_len = strlen(class->name);
|
|
size_t fnname_len = strlen(fn->fn.name->value);
|
|
char *method_name = malloc(classname_len + fnname_len + 2);
|
|
|
|
strcpy(method_name, class->name);
|
|
method_name[classname_len] = '_';
|
|
strcpy((method_name + classname_len + 1), fn->fn.name->value);
|
|
method_name[classname_len + fnname_len + 1] = 0;
|
|
|
|
if (fn->fn.name->value)
|
|
free(fn->fn.name->value);
|
|
|
|
fn->fn.name->value = method_name;
|
|
if (gen_common(gen, fn).error)
|
|
{
|
|
free(method_name);
|
|
fn->fn.name->value = NULL;
|
|
return gen_error;
|
|
}
|
|
}
|
|
|
|
ctx = gen_fin_ctx(gen);
|
|
if (!ctx)
|
|
return gen_error;
|
|
|
|
return gen_ok_null;
|
|
}
|