fix: fix parser/generator issues

This commit is contained in:
samsonium
2026-11-05 03:46:16 +03:00
parent bd8272abc7
commit 66f31ab865
23 changed files with 264 additions and 1721 deletions
+33 -2
View File
@@ -63,6 +63,38 @@ if (NOT FZL_SKIP_C)
src/compiler/analyzer/an_typedef.c
src/compiler/analyzer/an_unarycond.c
src/compiler/analyzer/an_unarymath.c
src/compiler/generator/context.c
src/compiler/generator/op.c
src/compiler/generator/utility.c
src/compiler/generator/gen_alias.c
src/compiler/generator/gen_assign.c
src/compiler/generator/gen_block.c
src/compiler/generator/gen_break.c
src/compiler/generator/gen_call.c
src/compiler/generator/gen_class.c
src/compiler/generator/gen_common.c
src/compiler/generator/gen_compare.c
src/compiler/generator/gen_condition.c
src/compiler/generator/gen_construct.c
src/compiler/generator/gen_declaration.c
src/compiler/generator/gen_extern.c
src/compiler/generator/gen_externfn.c
src/compiler/generator/gen_field.c
src/compiler/generator/gen_fmtstr.c
src/compiler/generator/gen_fn.c
src/compiler/generator/gen_handle.c
src/compiler/generator/gen_identifier.c
src/compiler/generator/gen_literal.c
src/compiler/generator/gen_logical.c
src/compiler/generator/gen_loop.c
src/compiler/generator/gen_math.c
src/compiler/generator/gen_reference.c
src/compiler/generator/gen_return.c
src/compiler/generator/gen_struct.c
src/compiler/generator/gen_typedef.c
src/compiler/generator/gen_unary_logical.c
src/compiler/generator/gen_unary_math.c
src/compiler/parser/utility.c
src/compiler/parser/pa_and.c
src/compiler/parser/pa_assignment.c
src/compiler/parser/pa_block.c
@@ -91,7 +123,6 @@ if (NOT FZL_SKIP_C)
src/compiler/parser/pa_typedef.c
src/compiler/parser/pa_unary.c
src/compiler/parser/pa_while.c
src/compiler/parser/utility.c
src/compiler/reader/rd_fmtstr.c
src/compiler/reader/rd_name.c
src/compiler/reader/rd_number.c
@@ -99,10 +130,10 @@ if (NOT FZL_SKIP_C)
src/compiler/reader/utility.c
src/compiler/fzl_analyzer.c
src/compiler/fzl_debug.c
src/compiler/fzl_gen.c
src/compiler/fzl_parser.c
src/compiler/fzl_reader.c
src/compiler/fzl_token.c
src/compiler/fzl_walker.c
src/compiler/fzl_writer.c
src/compiler/main.c)
endif ()
-102
View File
@@ -1,102 +0,0 @@
#ifndef FZL_WALKER_H
#define FZL_WALKER_H
#include <common/fzl_extern.h>
#include <common/fzl_opcodes.h>
#include <common/fzl_types.h>
#include <compiler/fzl_parser.h>
#include <compiler/utils/fzl_const_pool.h>
#include <compiler/utils/fzl_ctable.h>
#include <compiler/utils/fzl_symtable.h>
#include <stdbool.h>
#include <stddef.h>
// Type of context
typedef enum
{
FZL_WALK_CTX_TYPE_GLOBAL,
FZL_WALK_CTX_TYPE_FN,
FZL_WALK_CTX_TYPE_CLASS,
FZL_WALK_CTX_TYPE_ASSIGN,
FZL_WALK_CTX_TYPE_LOOP,
} fzl_walk_ctx_type_t;
// Internal walk function result
typedef struct
{
fzl_type_t type;
char *error_msg;
bool error;
char *classname;
} fzl_walk_res_t;
// Function context descriptor
typedef struct fzl_walk_ctx
{
fzl_walk_ctx_type_t type;
struct fzl_walk_ctx *parent;
size_t initial_env_lvl;
union
{
// function info
struct
{
fzl_node_t *fn;
};
// loops `break`s writeback addrs
struct
{
size_t *breaks;
size_t breaks_count;
size_t breaks_remainder;
};
};
} fzl_walk_ctx_t;
// Walker descriptor
typedef struct
{
fzl_node_t *root;
fzl_const_hash_pool_t *consts;
uint64_t *ops;
size_t op_count;
size_t op_remainder;
fzl_symtable_t *syms[64];
size_t sym_top;
fzl_walk_ctx_t *ctx;
fzl_ctable_t *classes[64];
size_t classes_count;
fzl_extern_lib_t extern_libs[64];
size_t extern_libs_count;
fzl_extern_type_t extern_types[256];
size_t extern_types_count;
fzl_extern_fn_t extern_fns[256];
size_t extern_fns_count;
} fzl_walker_t;
// Allocate new walker
fzl_walker_t *fzl_mkwalker(fzl_node_t *root);
// Walk throught the entire AST and build:
// 1. Constants table
// 2. Operations
int fzl_walk(fzl_walker_t *walker);
// Get last error message
char *fzl_walker_geterror();
// Free walker
void fzl_freewalker(fzl_walker_t *walker);
#endif // FZL_WALKER_H
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef FZL_WRITER_H
#define FZL_WRITER_H
#include <compiler/fzl_walker.h>
#include <compiler/fzl_gen.h>
#include <compiler/utils/fzl_const_pool.h>
// File writer descriptor
@@ -14,7 +14,7 @@ typedef struct
fzl_writer_t *fzl_mkwriter(const char *filepath);
// Write out a file
int fzl_write(fzl_writer_t *writer, fzl_walker_t *walker);
int fzl_write(fzl_writer_t *writer, fzl_gen_t *gen);
// Get last writer error message
char *fzl_writer_geterror();
+26 -4
View File
@@ -1,9 +1,10 @@
#include "compiler/fzl_parser.h"
#include "compiler/utils/fzl_ctable.h"
#include "compiler/utils/fzl_symtable.h"
#include <common/fzl_opcodes.h>
#include <compiler/fzl_gen.h>
#include <compiler/fzl_parser.h>
#include <compiler/internals/gen.h>
#include <compiler/utils/fzl_const_pool.h>
#include <compiler/utils/fzl_ctable.h>
#include <compiler/utils/fzl_symtable.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
@@ -36,6 +37,7 @@ fzl_gen_t *fzl_mkgen(fzl_node_t *root)
if (!gen->ctx)
{
fzl_consts_pool_free(gen->consts);
free(gen->ops);
free(gen);
return NULL;
}
@@ -48,10 +50,12 @@ bool fzl_gen_run(fzl_gen_t *gen)
if (!gen)
return false;
gen_op(gen, FZL_OPCODE_MK_ENVTABLE);
fzl_node_t *current = gen->root;
while (current != NULL)
{
if (!gen_common(gen, current))
if (gen_common(gen, current).error)
return false;
current = current->next;
@@ -71,6 +75,9 @@ void fzl_freegen(fzl_gen_t *gen)
if (gen->ops)
free(gen->ops);
while (gen->ctx != NULL)
gen_fin_ctx(gen);
if (gen->syms_top > 0)
for (ssize_t i = gen->syms_top - 1; i >= 0; i--)
fzl_freesymt(gen->syms[i]);
@@ -79,5 +86,20 @@ void fzl_freegen(fzl_gen_t *gen)
for (ssize_t i = gen->classes_count - 1; i >= 0; i--)
fzl_freectable(gen->classes[i]);
for (size_t i = 0; i < gen->extern_types_count; i++)
{
fzl_extern_type_t *type = &gen->extern_types[i];
if (type->kind == FZL_EXTERN_KIND_STRUCT)
if (type->structure.fields)
free(type->structure.fields);
}
for (size_t i = 0; i < gen->extern_fns_count; i++)
{
fzl_extern_fn_t *fn = &gen->extern_fns[i];
if (fn->args)
free(fn->args);
}
free(gen);
}
+1 -1
View File
@@ -33,7 +33,7 @@ void fzl_freetoken(fzl_token_t *tok)
if (!tok)
return;
if (tok->store_value)
if (tok->store_value && tok->value)
free(tok->value);
free(tok);
File diff suppressed because it is too large Load Diff
+9 -8
View File
@@ -1,3 +1,4 @@
#include <compiler/fzl_gen.h>
#include <compiler/fzl_writer.h>
#include <compiler/utils/fzl_const_pool.h>
#include <stddef.h>
@@ -22,9 +23,9 @@ fzl_writer_t *fzl_mkwriter(const char *filepath)
return writer;
}
int fzl_write(fzl_writer_t *writer, fzl_walker_t *walker)
int fzl_write(fzl_writer_t *writer, fzl_gen_t *gen)
{
if (!writer || !walker)
if (!writer || !gen)
return -1;
FILE *fp = fopen(writer->filepath, "wb");
@@ -37,12 +38,12 @@ int fzl_write(fzl_writer_t *writer, fzl_walker_t *walker)
const char hdr[5] = {'F', 'Z', 'L', 0x0, 0x1};
fwrite(hdr, sizeof(char), 5, fp);
fwrite(&walker->consts->size, sizeof(size_t), 1, fp);
fwrite(&walker->op_count, sizeof(size_t), 1, fp);
fwrite(&gen->consts->size, sizeof(size_t), 1, fp);
fwrite(&gen->ops_count, sizeof(size_t), 1, fp);
for (size_t i = 0; i < walker->consts->size; i++)
for (size_t i = 0; i < gen->consts->size; i++)
{
fzl_const_t c = walker->consts->array[i];
fzl_const_t c = gen->consts->array[i];
fwrite(&c.type, sizeof(fzl_consttype_t), 1, fp);
if (c.type == FZL_CONSTTYPE_STRING)
@@ -53,8 +54,8 @@ int fzl_write(fzl_writer_t *writer, fzl_walker_t *walker)
}
}
if (walker->op_count > 0)
fwrite(walker->ops, sizeof(uint64_t), walker->op_count, fp);
if (gen->ops_count > 0)
fwrite(gen->ops, sizeof(uint64_t), gen->ops_count, fp);
fclose(fp);
+20 -13
View File
@@ -10,7 +10,7 @@
fzl_gen_ctx_t *gen_ctx(fzl_gen_t *gen, fzl_gen_ctx_type_t type,
fzl_node_t *node)
{
if (!gen || !type)
if (!gen)
return NULL;
fzl_gen_ctx_t *ctx = malloc(sizeof(fzl_gen_ctx_t));
@@ -18,15 +18,19 @@ fzl_gen_ctx_t *gen_ctx(fzl_gen_t *gen, fzl_gen_ctx_type_t type,
return NULL;
memset(ctx, 0, sizeof(fzl_gen_ctx_t));
ctx->type = type;
fzl_symtable_t *symt = fzl_mksymt();
if (!symt)
if (ctx->type != FZL_GEN_CTX_TYPE_CLASS)
{
free(ctx);
return NULL;
}
fzl_symtable_t *symt = fzl_mksymt();
if (!symt)
{
free(ctx);
return NULL;
}
gen->syms[gen->syms_top++] = symt;
gen->syms[gen->syms_top++] = symt;
}
size_t level = 0;
fzl_gen_ctx_t *parent = gen->ctx;
@@ -36,17 +40,17 @@ fzl_gen_ctx_t *gen_ctx(fzl_gen_t *gen, fzl_gen_ctx_type_t type,
parent = parent->parent;
}
ctx->type = type;
ctx->level = level;
ctx->parent = gen->ctx;
if (type == FZL_GEN_CTX_TYPE_FUNCTION)
{
if (node->type == FZL_NODETYPE_FUNCTION)
if (node->type == FZL_NODETYPE_FUNCTION ||
node->type == FZL_NODETYPE_EXTERN_FN)
ctx->function = node;
else
{
fzl_freesymt(symt);
fzl_freesymt(gen->syms[--gen->syms_top]);
free(ctx);
return NULL;
}
@@ -66,9 +70,12 @@ fzl_gen_ctx_t *gen_fin_ctx(fzl_gen_t *gen)
if (!ctx)
return NULL;
fzl_symtable_t *sym = gen->syms[--gen->syms_top];
if (sym)
fzl_freesymt(sym);
if (ctx->type != FZL_GEN_CTX_TYPE_CLASS)
{
fzl_symtable_t *sym = gen->syms[--gen->syms_top];
if (sym)
fzl_freesymt(sym);
}
gen->ctx = ctx->parent;
free(ctx);
+5 -4
View File
@@ -4,6 +4,8 @@
#include <stdio.h>
#include <string.h>
char alias_typecn[256];
// Type aliasing
gen_res_t gen_alias(fzl_gen_t *gen, fzl_node_t *node)
{
@@ -11,14 +13,13 @@ gen_res_t gen_alias(fzl_gen_t *gen, fzl_node_t *node)
return gen_error;
fzl_type_t type;
char typecn[256];
memset(typecn, 0, sizeof(typecn));
memset(alias_typecn, 0, sizeof(alias_typecn));
bool resolved = gen_resolve_type(gen, node->token, &type, typecn);
bool resolved = gen_resolve_type(gen, node->token, &type, alias_typecn);
if (!resolved)
return gen_error;
ssize_t slot = gen_resolve_extern_type(gen, typecn);
ssize_t slot = gen_resolve_extern_type(gen, alias_typecn);
if (slot == -1)
type_buf.alias_target =
(fzl_extern_type_ref_t){.is_primitive = true, .primitive = type};
+5 -6
View File
@@ -63,7 +63,6 @@ gen_res_t gen_call(fzl_gen_t *gen, fzl_node_t *node)
if (!found)
return gen_error;
gen_res_t result;
if (sym.node->type == FZL_NODETYPE_EXTERN_FN)
{
size_t fn_n = 0;
@@ -146,6 +145,9 @@ gen_res_t gen_call(fzl_gen_t *gen, fzl_node_t *node)
}
}
break;
default:
return gen_error;
}
}
@@ -166,8 +168,6 @@ gen_res_t gen_call(fzl_gen_t *gen, fzl_node_t *node)
return (gen_res_t){
.error = false, .type = sym.type, .classname = sym.classname};
}
return result;
}
if (node->call.callee->type == FZL_NODETYPE_FIELD)
@@ -200,7 +200,7 @@ gen_res_t gen_call(fzl_gen_t *gen, fzl_node_t *node)
size_t fnlen = strlen(method_node->token->value);
char *methodname = malloc(classlen + fnlen + 2);
strcpy(methodname, classname);
strcpy((methodname + classlen + 1), node->call.callee->token->value);
strcpy((methodname + classlen + 1), method_node->token->value);
methodname[classlen] = '_';
methodname[classlen + fnlen + 1] = 0;
@@ -210,11 +210,10 @@ gen_res_t gen_call(fzl_gen_t *gen, fzl_node_t *node)
if ((found_method = fzl_symt_get(gen->syms[i], methodname, &fn_sym)))
break;
free(methodname);
if (!found_method)
return gen_error;
free(methodname);
if (node->call.args_count > 0)
for (size_t i = 0; i < node->call.args_count; i++)
if (gen_common(gen, node->call.args[i]).error)
+10 -12
View File
@@ -1,10 +1,14 @@
#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)
{
@@ -17,7 +21,7 @@ gen_res_t gen_class(fzl_gen_t *gen, fzl_node_t *node)
gen->classes[gen->classes_count] = fzl_mkctable(node->class.name->value);
fzl_ctable_t *class = gen->classes[gen->classes_count++];
class->name = node->class.name->value;
class->name = (char *)node->class.name->value;
for (size_t i = 0; i < node->class.fields_count; i++)
{
@@ -29,16 +33,12 @@ gen_res_t gen_class(fzl_gen_t *gen, fzl_node_t *node)
}
fzl_type_t type;
char typecn[256];
memset(typecn, 0, sizeof(typecn));
memset(class_typecn, 0, sizeof(class_typecn));
bool resolved =
gen_resolve_type(gen, node->class.fields[i]->var.type, &type, typecn);
bool resolved = gen_resolve_type(gen, node->class.fields[i]->var.type,
&type, class_typecn);
if (!resolved)
{
free(class->fields);
return gen_error;
}
class->fields[class->fields_count] = (fzl_ctable_field_t){
.name = node->class.fields[i]->var.identifier->token->value,
@@ -65,17 +65,15 @@ gen_res_t gen_class(fzl_gen_t *gen, fzl_node_t *node)
fn->fn.name->value = method_name;
if (gen_common(gen, fn).error)
{
free(class->fields);
free(method_name);
fn->fn.name->value = NULL;
return gen_error;
}
}
ctx = gen_fin_ctx(gen);
if (!ctx)
{
free(class->fields);
return gen_error;
}
return gen_ok_null;
}
+6
View File
@@ -7,6 +7,8 @@
typedef gen_res_t (*gen_handle_fn)(fzl_gen_t *, fzl_node_t *);
char *null_name = "<null>";
gen_res_t gen_error = (gen_res_t){.error = true};
gen_res_t gen_ok_null =
(gen_res_t){.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
@@ -142,7 +144,11 @@ gen_res_t gen_common(fzl_gen_t *gen, fzl_node_t *node)
}
if (!res)
{
printf("Bruh, you, suka, go fix the generator blyat (%s:%d)\n", __FILE__,
__LINE__);
return gen_error;
}
return res(gen, node);
}
+5 -4
View File
@@ -3,6 +3,8 @@
#include <stdbool.h>
#include <string.h>
char dec_typecn[256];
// Variable (or argument) declaration
gen_res_t gen_declaration(fzl_gen_t *gen, fzl_node_t *node)
{
@@ -11,10 +13,9 @@ gen_res_t gen_declaration(fzl_gen_t *gen, fzl_node_t *node)
char *name = (char *)node->var.identifier->token->value;
fzl_type_t type;
char typecn[256];
memset(typecn, 0, sizeof(typecn));
memset(dec_typecn, 0, sizeof(dec_typecn));
bool resolved = gen_resolve_type(gen, node->var.type, &type, typecn);
bool resolved = gen_resolve_type(gen, node->var.type, &type, dec_typecn);
if (!resolved)
return gen_error;
@@ -56,5 +57,5 @@ gen_res_t gen_declaration(fzl_gen_t *gen, fzl_node_t *node)
gen_op(gen, FZL_OPCODE_LOADCONST);
gen_word(gen, const_n);
return (gen_res_t){.error = false, .type = type, .classname = typecn};
return (gen_res_t){.error = false, .type = type, .classname = dec_typecn};
}
+18 -13
View File
@@ -10,6 +10,9 @@
#include <stdlib.h>
#include <string.h>
char ex_argcn[256];
char ex_retcn[256];
// External function definition
gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
{
@@ -29,7 +32,7 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
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))
if (gen_common(gen, argnode).error)
return gen_error;
if (args_count >= args_remainder)
@@ -55,17 +58,17 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
fzl_extern_arg_t *arg = &args[args_count++];
fzl_type_t argtype;
char argcn[256];
memset(argcn, 0, sizeof(argcn));
memset(ex_argcn, 0, sizeof(ex_argcn));
bool resolved = gen_resolve_type(gen, argnode->var.type, &argtype, argcn);
bool resolved =
gen_resolve_type(gen, argnode->var.type, &argtype, ex_argcn);
if (!resolved)
{
free(args);
return gen_error;
}
ssize_t slot = gen_resolve_extern_type(gen, argcn);
ssize_t slot = gen_resolve_extern_type(gen, ex_argcn);
if (slot == -1)
arg->type =
(fzl_extern_type_ref_t){.is_primitive = true, .primitive = argtype};
@@ -85,10 +88,9 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
}
fzl_type_t ret;
char retname[256];
memset(retname, 0, sizeof(retname));
memset(ex_retcn, 0, sizeof(ex_retcn));
bool resolved = gen_resolve_type(gen, node->ext_fn.type, &ret, retname);
bool resolved = gen_resolve_type(gen, node->ext_fn.type, &ret, ex_retcn);
if (!resolved)
{
free(args);
@@ -103,16 +105,19 @@ gen_res_t gen_externfn(fzl_gen_t *gen, fzl_node_t *node)
return gen_error;
}
res = fzl_symt_setobjclass(gen->syms[0], node->ext_fn.name, retname);
if (res != FZL_SYMTABLE_RESULT_OK)
if (ret != FZL_TYPE_NULL)
{
free(args);
return gen_error;
res = fzl_symt_setobjclass(gen->syms[0], node->ext_fn.name, ex_retcn);
if (res != FZL_SYMTABLE_RESULT_OK)
{
free(args);
return gen_error;
}
}
fzl_extern_fn_t *result = &gen->extern_fns[gen->extern_fns_count++];
ssize_t slot = gen_resolve_extern_type(gen, retname);
ssize_t slot = gen_resolve_extern_type(gen, ex_retcn);
if (slot == -1)
result->ret_type =
(fzl_extern_type_ref_t){.is_primitive = true, .primitive = ret};
+6 -5
View File
@@ -4,6 +4,8 @@
#include <stdio.h>
#include <string.h>
char fn_typecn[256];
// Function definition
gen_res_t gen_fn(fzl_gen_t *gen, fzl_node_t *node)
{
@@ -15,10 +17,9 @@ gen_res_t gen_fn(fzl_gen_t *gen, fzl_node_t *node)
gen_word(gen, (uint64_t)0);
fzl_type_t fntype;
char fntypcn[256];
memset(fntypcn, 0, sizeof(fntypcn));
memset(fn_typecn, 0, sizeof(fn_typecn));
bool resolved = gen_resolve_type(gen, node->fn.type, &fntype, fntypcn);
bool resolved = gen_resolve_type(gen, node->fn.type, &fntype, fn_typecn);
if (!resolved)
return gen_error;
@@ -32,7 +33,7 @@ gen_res_t gen_fn(fzl_gen_t *gen, fzl_node_t *node)
if (fntype == FZL_TYPE_OBJECT)
{
fzl_symtable_res_t updres = fzl_symt_setobjclass(
gen->syms[gen->syms_top - 1], node->fn.name->value, fntypcn);
gen->syms[gen->syms_top - 1], node->fn.name->value, fn_typecn);
if (updres != FZL_SYMTABLE_RESULT_OK)
return gen_error;
}
@@ -62,5 +63,5 @@ gen_res_t gen_fn(fzl_gen_t *gen, fzl_node_t *node)
if (!ctx)
return gen_error;
return (gen_res_t){.error = false, .type = fntype, .classname = fntypcn};
return (gen_res_t){.error = false, .type = fntype, .classname = fn_typecn};
}
+1 -1
View File
@@ -52,7 +52,7 @@ gen_res_t gen_loop(fzl_gen_t *gen, fzl_node_t *node)
gen_op(gen, FZL_OPCODE_RM_ENVTABLE);
for (size_t i = gen->syms_top - 1; i > ctx->level; i--)
for (size_t i = gen->syms_top - 1; i > ctx->level + 1; i--)
fzl_freesymt(gen->syms[--gen->syms_top]);
ctx = gen_fin_ctx(gen);
+23 -6
View File
@@ -2,9 +2,12 @@
#include <compiler/fzl_gen.h>
#include <compiler/internals/gen.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
char ret_typecn[256];
// Return keyword
gen_res_t gen_return(fzl_gen_t *gen, fzl_node_t *node)
{
@@ -31,17 +34,17 @@ gen_res_t gen_return(fzl_gen_t *gen, fzl_node_t *node)
if (retres.error)
return gen_error;
fzl_node_t *fn_node = gen->ctx->function;
fzl_node_t *fn_node = ctx->function;
fzl_type_t fntype;
char fntypecn[256];
memset(fntypecn, 0, sizeof(fntypecn));
memset(ret_typecn, 0, sizeof(ret_typecn));
bool resolved = gen_resolve_type(gen, fn_node->fn.type, &fntype, fntypecn);
bool resolved =
gen_resolve_type(gen, fn_node->fn.type, &fntype, ret_typecn);
if (!resolved)
return gen_error;
if (!gen_is_types_compatible(retres.type, fntype, retres.classname,
fntypecn))
ret_typecn))
return gen_error;
if (retres.type == FZL_TYPE_OBJECT)
@@ -52,7 +55,21 @@ gen_res_t gen_return(fzl_gen_t *gen, fzl_node_t *node)
else
result = gen_ok_null;
for (size_t i = 0; i < (gen->syms_top - gen->ctx->level); i++)
bool is_method = false;
fzl_gen_ctx_t *cur_ctx = gen->ctx;
while (cur_ctx != NULL)
{
if (cur_ctx && cur_ctx->type == FZL_GEN_CTX_TYPE_CLASS)
{
is_method = true;
break;
}
cur_ctx = cur_ctx->parent;
}
size_t method_dec = is_method;
for (size_t i = 0; i < (gen->syms_top - ctx->level + method_dec); i++)
{
if (returning_object)
gen_op(gen, FZL_OPCODE_ESCAPE_OBJECT);
+10 -8
View File
@@ -9,6 +9,8 @@
#include <stdlib.h>
#include <string.h>
char struct_typecn[256];
// Structure
gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
{
@@ -30,7 +32,7 @@ gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
for (size_t i = 0; i < node->structure.entries_count; i++)
{
fzl_node_t *fnode = node->structure.entries[i];
if (!gen_common(gen, fnode))
if (gen_common(gen, fnode).error)
{
free(fields);
return gen_error;
@@ -50,23 +52,23 @@ gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
}
fzl_type_t type;
char typecn[256];
memset(typecn, 0, sizeof(typecn));
memset(struct_typecn, 0, sizeof(struct_typecn));
fzl_extern_struct_field_t *field = &fields[count++];
if (node->type == FZL_NODETYPE_DECLARATION)
if (fnode->type == FZL_NODETYPE_DECLARATION)
{
field->name = (char *)fnode->var.identifier->token->value;
bool resolved = gen_resolve_type(gen, fnode->var.type, &type, typecn);
bool resolved =
gen_resolve_type(gen, fnode->var.type, &type, struct_typecn);
if (!resolved)
{
free(fields);
return gen_error;
}
ssize_t slot = gen_resolve_extern_type(gen, typecn);
ssize_t slot = gen_resolve_extern_type(gen, struct_typecn);
if (slot == -1)
field->type =
(fzl_extern_type_ref_t){.is_primitive = true, .primitive = type};
@@ -74,11 +76,11 @@ gen_res_t gen_struct(fzl_gen_t *gen, fzl_node_t *node)
field->type =
(fzl_extern_type_ref_t){.is_primitive = false, .type_slot = slot};
}
else if (node->type == FZL_NODETYPE_IDENTIFIER)
else if (fnode->type == FZL_NODETYPE_IDENTIFIER)
{
field->name = (char *)fnode->token->value;
ssize_t slot = gen_resolve_extern_type(gen, typecn);
ssize_t slot = gen_resolve_extern_type(gen, struct_typecn);
if (slot == -1)
{
free(fields);
+34
View File
@@ -2,6 +2,7 @@
#include <common/fzl_types.h>
#include <compiler/fzl_parser.h>
#include <compiler/internals/gen.h>
#include <compiler/utils/fzl_symtable.h>
#include <stdbool.h>
#include <string.h>
@@ -21,26 +22,59 @@ gen_res_t gen_typedef(fzl_gen_t *gen, fzl_node_t *node)
newtype->lib_slot = gen->extern_libs_count - 1;
newtype->name = node->typedefinition.typename;
fzl_type_t type;
switch (type_buf.kind)
{
case FZL_EXTERN_KIND_REF:
newtype->kind = FZL_EXTERN_KIND_REF;
newtype->ref_target = type_buf.ref_target;
type = FZL_TYPE_HANDLE;
break;
case FZL_EXTERN_KIND_HANDLE:
newtype->kind = FZL_EXTERN_KIND_HANDLE;
type = FZL_TYPE_HANDLE;
break;
case FZL_EXTERN_KIND_ALIAS:
newtype->kind = FZL_EXTERN_KIND_ALIAS;
newtype->alias_target = type_buf.alias_target;
if (type_buf.alias_target.is_primitive)
type = type_buf.alias_target.primitive;
else
{
fzl_extern_type_t *aliased =
&gen->extern_types[type_buf.alias_target.type_slot];
if (aliased->kind == FZL_EXTERN_KIND_ALIAS)
return gen_error;
else if (aliased->kind == FZL_EXTERN_KIND_REF)
type = FZL_TYPE_HANDLE;
else if (aliased->kind == FZL_EXTERN_KIND_STRUCT)
type = FZL_TYPE_STRUCT;
else
type = FZL_TYPE_HANDLE;
}
break;
case FZL_EXTERN_KIND_STRUCT:
newtype->kind = FZL_EXTERN_KIND_STRUCT;
newtype->structure.fields = type_buf.structure.fields;
newtype->structure.fields_count = type_buf.structure.fields_count;
type = FZL_TYPE_STRUCT;
break;
}
fzl_symtable_res_t res =
fzl_symt_put(gen->syms[0], node, newtype->name, type, 0);
if (res != FZL_SYMTABLE_RESULT_OK)
return gen_error;
if (type == FZL_TYPE_STRUCT || type == FZL_TYPE_HANDLE)
{
res = fzl_symt_setobjclass(gen->syms[0], newtype->name, newtype->name);
if (res != FZL_SYMTABLE_RESULT_OK)
return gen_error;
}
return gen_ok_null;
}
+22 -6
View File
@@ -39,19 +39,35 @@ bool gen_resolve_type(fzl_gen_t *gen, fzl_token_t *tok, fzl_type_t *t, char *c)
fzl_sym_t sym;
if (!gen_resolve_name(gen, name, &sym))
return false;
{
fzl_ctable_t *class = NULL;
for (size_t i = 0; i < gen->classes_count; i++)
{
if (strcmp(name, gen->classes[i]->name) == 0)
{
class = gen->classes[i];
break;
}
}
if (sym.node && sym.node->type == FZL_NODETYPE_CLASS)
if (!class)
return false;
*t = FZL_TYPE_OBJECT;
if (c && class->name)
strcpy(c, class->name);
}
else if (sym.node && sym.node->type == FZL_NODETYPE_CLASS)
{
*t = FZL_TYPE_OBJECT;
if (c)
c = sym.classname;
if (c && sym.classname)
strcpy(c, sym.classname);
}
else if (sym.node && sym.node->type == FZL_NODETYPE_TYPEDEF)
{
*t = sym.type;
if (c)
c = sym.classname;
if (c && sym.classname)
strcpy(c, sym.classname);
}
else
return false;
+23 -18
View File
@@ -1,9 +1,9 @@
#include <common/fzl_colors.h>
#include <compiler/fzl_analyzer.h>
#include <compiler/fzl_debug.h>
#include <compiler/fzl_gen.h>
#include <compiler/fzl_parser.h>
#include <compiler/fzl_reader.h>
#include <compiler/fzl_walker.h>
#include <compiler/fzl_writer.h>
#include <compiler/utils/fzl_linked.h>
#include <compiler/utils/fzl_options.h>
@@ -122,7 +122,6 @@ int main(int argc, char **argv)
{
printf("%sok%s!\n", FZL_COK, FZL_CRST);
fzl_debug_print_ast(parser->root);
printf("%s> building%s\n", FZL_CDEBUG, FZL_CRST);
printf("%s-> analyzing AST...%s", FZL_CDEBUG, FZL_CRST);
}
@@ -159,10 +158,16 @@ int main(int argc, char **argv)
analyzer->warnings[i]);
}
fzl_walker_t *walker = fzl_mkwalker(parser->root);
if (!walker)
if (opts->verbose)
{
printf("%sError%s: failed to allocate writer\n", FZL_CERROR, FZL_CRST);
printf("%sok%s!\n", FZL_COK, FZL_CRST);
printf("%s> generate\n-> generating bytecode...%s", FZL_CDEBUG, FZL_CRST);
}
fzl_gen_t *gen = fzl_mkgen(parser->root);
if (!gen)
{
printf("%sError%s: failed to allocate generator\n", FZL_CERROR, FZL_CRST);
fzl_freeoptions(opts);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
@@ -172,12 +177,12 @@ int main(int argc, char **argv)
return -1;
}
result = fzl_walk(walker);
if (result != 0)
bool gen_res = fzl_gen_run(gen);
if (!gen_res)
{
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_walker_geterror());
printf("%sError%s: couldn't generate operations\n", FZL_CERROR, FZL_CRST);
fzl_freeoptions(opts);
fzl_freewalker(walker);
fzl_freegen(gen);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
@@ -191,16 +196,16 @@ int main(int argc, char **argv)
printf("%sok%s!\n", FZL_COK, FZL_CRST);
printf("%s--> Constants table%s:\n", FZL_CDEBUG, FZL_CRST);
for (size_t i = 0; i < walker->consts->size; i++)
printf("---> %s\n", walker->consts->array[i].as.string.chars);
for (size_t i = 0; i < gen->consts->size; i++)
printf("---> %s\n", gen->consts->array[i].as.string.chars);
printf("%s--> Ops%s:\n", FZL_CDEBUG, FZL_CRST);
printf("---> ");
for (size_t i = 0; i < walker->op_count; i++)
for (size_t i = 0; i < gen->ops_count; i++)
{
if (i > 0 && i < walker->op_count)
if (i > 0 && i < gen->ops_count)
printf("->");
printf("%lX", walker->ops[i]);
printf("%lX", gen->ops[i]);
}
printf("\n");
@@ -224,7 +229,7 @@ int main(int argc, char **argv)
{
printf("%sError%s: failed to allocate writer\n", FZL_CERROR, FZL_CRST);
fzl_freeoptions(opts);
fzl_freewalker(walker);
fzl_freegen(gen);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
@@ -233,13 +238,13 @@ int main(int argc, char **argv)
return -1;
}
result = fzl_write(writer, walker);
result = fzl_write(writer, gen);
if (result != 0)
{
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_writer_geterror());
fzl_freeoptions(opts);
fzl_freewriter(writer);
fzl_freewalker(walker);
fzl_freegen(gen);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
@@ -257,7 +262,7 @@ int main(int argc, char **argv)
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
fzl_freewalker(walker);
fzl_freegen(gen);
fzl_freewriter(writer);
printf("%sCompiled successfully%s.\n", FZL_COK, FZL_CRST);
+2 -1
View File
@@ -67,7 +67,7 @@ fzl_node_t *pa_primary(fzl_parser_t *parser)
}
fzl_token_t *end = consume(parser);
if (end->type != FZL_TOKTYPE_STR_FORMAT_END)
if (!end || end->type != FZL_TOKTYPE_STR_FORMAT_END)
{
snprintf(plast_err, sizeof(plast_err),
"'%s':%zu:%zu => unterminated format string",
@@ -78,6 +78,7 @@ fzl_node_t *pa_primary(fzl_parser_t *parser)
fzl_freeast(entries[i]);
free(entries);
return NULL;
}
if (count < 1)
+3 -1
View File
@@ -59,7 +59,9 @@ fzl_symtable_res_t fzl_symt_setobjclass(fzl_symtable_t *symt, char *name,
{
if (strcmp(symt->symbols[i].name, name) == 0)
{
if (symt->symbols[i].type != FZL_TYPE_OBJECT)
if (symt->symbols[i].type != FZL_TYPE_OBJECT &&
symt->symbols[i].type != FZL_TYPE_STRUCT &&
symt->symbols[i].type != FZL_TYPE_HANDLE)
return FZL_SYMTABLE_RESULT_NOT_OBJECT;
symt->symbols[i].classname = classname;