Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions subprojects/vinumc/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,49 @@
#include <stdio.h>
#include <string.h>

#include "ast.h"

struct ast_node ast_node_new(const int type, struct vut_sv text, struct vut_allocator allocator) {
struct ast_node ret = { .type = type,
.text = text,
.childs = VUT_VEC_INIT(struct ast_node_childs_t, allocator) };
#include <vutils/arena_allocator.h>

return ret;
}
#include "ast.h"

struct ast ast_new(struct vut_allocator allocator) {
struct ast ret = {
.nodes = VUT_VEC_INIT(struct ast_nodes_t, allocator),
.allocator = allocator,
};

struct vut_arena *arena = vut_allocator_malloc(allocator, sizeof(*arena), 1);
*arena = vut_arena_new(allocator, 10 * 1024);
ret.child_arena = vut_arena_to_vut_allocator(arena);

return ret;
}

ast_node_id_t ast_add_node(struct ast *ast, const struct ast_node node) {
void ast_free(struct ast *ast) {
vut_arena_free_all(ast->child_arena.base_allocator);
vut_allocator_free(ast->allocator, ast->child_arena.base_allocator);
VUT_VEC_FREE(&ast->nodes);

*ast = (struct ast){};
}

static ast_node_id_t ast_add_node(struct ast *ast, const struct ast_node node) {
VUT_VEC_PUT(&ast->nodes, node);
return ast->nodes.len - 1;
}

ast_node_id_t ast_node_new(struct ast *ast, const int type, struct vut_sv text) {
struct ast_node node = { .type = type,
.text = text,
.childs =
VUT_VEC_INIT(struct ast_node_childs_t, ast->child_arena) };

return ast_add_node(ast, node);
}

ast_node_id_t ast_copy_node(struct ast *ast, ast_node_id_t node_id) {
struct ast_node no_childs_copy = VUT_VEC_AT(&ast->nodes, node_id);

no_childs_copy.childs = VUT_VEC_INIT(struct ast_node_childs_t, ast->allocator);
no_childs_copy.childs = VUT_VEC_INIT(struct ast_node_childs_t, ast->child_arena);

size_t node_copy_id = ast_add_node(ast, no_childs_copy);
struct ast_node *node_copy = &VUT_VEC_AT(&ast->nodes, node_copy_id);
Expand Down
9 changes: 5 additions & 4 deletions subprojects/vinumc/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,22 @@ struct ast_node {
struct ast_node_childs_t childs;
};

struct ast_node ast_node_new(const int type, struct vut_sv text, struct vut_allocator allocator);
#define ast_node_new_nvl(type, allocator) (ast_node_new((type), (struct vut_sv){ 0 }, (allocator)))

struct ast_nodes_t VUT_VEC_DEF(struct ast_node);

struct ast {
struct ast_nodes_t nodes;

struct vut_allocator allocator;
struct vut_allocator child_arena;
};

struct ast ast_new(struct vut_allocator allocator);
void ast_free(struct ast *ast);

ast_node_id_t ast_node_new(struct ast *ast, const int type, struct vut_sv text);
#define ast_node_new_nvl(ast, type) (ast_node_new((ast), (type), (struct vut_sv){ 0 }))

const char *token_to_str(enum yytokentype token);
ast_node_id_t ast_add_node(struct ast *ast, const struct ast_node node);
ast_node_id_t ast_copy_node(struct ast *ast, ast_node_id_t node_id);

ast_node_id_t ast_get_num_child(const struct ast *ast, ast_node_id_t id);
Expand Down
15 changes: 7 additions & 8 deletions subprojects/vinumc/dry_bison.y
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ void yyerror(yyscan_t scanner, struct compiler_ctx *ctx, const char *fmt, ...);
program:
{
UNUSED(yynerrs);
struct ast_node node = ast_node_new_nvl(PROGRAM, ctx->ast.allocator);
$$ = ast_add_node(&ctx->ast, node);
$$ = ast_node_new_nvl(&ctx->ast, PROGRAM);
}
| program block {
ast_add_child(&ctx->ast, $1, $2);
Expand All @@ -58,23 +57,23 @@ program:

block:
'[' symbol ':' args ']' {
ast_node_id_t node = ast_add_node(&ctx->ast, ast_node_new_nvl(ASSIGNMENT, ctx->ast.allocator));
ast_node_id_t node = ast_node_new_nvl(&ctx->ast, ASSIGNMENT);

ast_add_child(&ctx->ast, node, $2);
ast_add_child(&ctx->ast, node, $4);

$$ = node;
}
| '[' symbol args ']' {
ast_node_id_t node = ast_add_node(&ctx->ast, ast_node_new_nvl(CALL, ctx->ast.allocator));
ast_node_id_t node = ast_node_new_nvl(&ctx->ast, CALL);

ast_add_child(&ctx->ast, node, $2);
ast_add_child(&ctx->ast, node, $3);

$$ = node;
}
| '[' symbol ']' {
ast_node_id_t node = ast_add_node(&ctx->ast, ast_node_new_nvl(CALL, ctx->ast.allocator));
ast_node_id_t node = ast_node_new_nvl(&ctx->ast, CALL);

ast_add_child(&ctx->ast, node, $2);

Expand All @@ -84,7 +83,7 @@ block:

args:
args_child {
ast_node_id_t node = ast_add_node(&ctx->ast, ast_node_new_nvl(ARGS, ctx->ast.allocator));
ast_node_id_t node = ast_node_new_nvl(&ctx->ast, ARGS);
ast_add_child(&ctx->ast, node, $1);

$$ = node;
Expand All @@ -106,7 +105,7 @@ args_child:
symbol: SYMBOL {
// making so our symbols are case insensitive by making the whole string lowercase
struct vut_sv text = ast_get_text(&ctx->ast, $1);
struct vut_str tmp_str = vut_str_from_vut_sv(text, ctx->alloc);
struct vut_str tmp_str = vut_str_from_vut_sv(text, ctx->dry_arena);

// we need to convert from multi-byte to wide-character string
wchar_t *wtext = (wchar_t*)malloc(text.len * sizeof(wchar_t));
Expand All @@ -127,7 +126,7 @@ symbol: SYMBOL {
$$ = $1;
}
| block {
ast_node_id_t node = ast_add_node(&ctx->ast, ast_node_new_nvl(SYMBOL, ctx->ast.allocator));
ast_node_id_t node = ast_node_new_nvl(&ctx->ast, SYMBOL);
ast_add_child(&ctx->ast, node, $1);

$$ = node;
Expand Down
25 changes: 9 additions & 16 deletions subprojects/vinumc/dry_flex.l
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ BEFORE_TEXT_END ("["|"]"|"$*"|"{#")

<INITIAL>[ \t\r\n]+ ;
<INITIAL>[^\[\] \t\r\n]+ {
struct ast_node node = ast_node_new(TEXT, vut_sv_from_cstr(yytext), yyextra->ast.allocator);
*yylval = ast_add_node(&yyextra->ast, node);
*yylval = ast_node_new(&yyextra->ast, TEXT, vut_sv_from_cstr(yytext));

return TEXT;
}
Expand All @@ -60,8 +59,7 @@ BEFORE_TEXT_END ("["|"]"|"$*"|"{#")
<DEFINE_CALL_NAME,HAS_CALL_NAME>[ \t]*: { replace_state(CONTENT, yyscanner); return ':'; }
<DEFINE_CALL_NAME>[ \t\r\n]+ ;
<DEFINE_CALL_NAME>[^\[\]: \t\r\n]+ {
struct ast_node node = ast_node_new(SYMBOL, vut_sv_from_cstr(yytext), yyextra->ast.allocator);
*yylval = ast_add_node(&yyextra->ast, node);
*yylval = ast_node_new(&yyextra->ast, SYMBOL, vut_sv_from_cstr(yytext));

replace_state(HAS_CALL_NAME, yyscanner);

Expand All @@ -71,16 +69,14 @@ BEFORE_TEXT_END ("["|"]"|"$*"|"{#")
<HAS_CALL_NAME>. { replace_state(CONTENT, yyscanner); yyless(0); }

<CONTENT>"$*" {
struct ast_node node = ast_node_new_nvl(ARG_REF_ALL_ARGS, yyextra->ast.allocator);
*yylval = ast_add_node(&yyextra->ast, node);
*yylval = ast_node_new_nvl(&yyextra->ast, ARG_REF_ALL_ARGS);

return ARG_REF_ALL_ARGS;
}

<CONTENT>"{#" { yy_push_state(IN_LITERAL, yyscanner); }
<IN_LITERAL>"#}" {
struct ast_node node = ast_node_new(LITERAL, vut_sv_from_str(yytext, yyleng - 2), yyextra->ast.allocator);
*yylval = ast_add_node(&yyextra->ast, node);
*yylval = ast_node_new(&yyextra->ast, LITERAL, vut_sv_from_str(yytext, yyleng - 2));

yy_pop_state(yyscanner);
return LITERAL;
Expand All @@ -91,9 +87,7 @@ BEFORE_TEXT_END ("["|"]"|"$*"|"{#")
<IN_LITERAL>(.|\n) {
// the next token is eof, so we yield the
// contents buffered so far
struct ast_node node = ast_node_new(LITERAL, vut_sv_from_str(yytext, yyleng),
yyextra->ast.allocator);
*yylval = ast_add_node(&yyextra->ast, node);
*yylval = ast_node_new(&yyextra->ast, LITERAL, vut_sv_from_str(yytext, yyleng));
yy_pop_state(yyscanner);
return LITERAL;
}
Expand Down Expand Up @@ -142,14 +136,13 @@ static int yield_text_node(yyscan_t yyscanner) {
YYSTYPE * lval = yyget_lval(yyscanner);
struct compiler_ctx * extra = yyget_extra(yyscanner);

struct ast_node node = ast_node_new(
*lval = ast_node_new(
&extra->ast,
TEXT,
vut_sv_from_vut_str(&extra->dry_flex_text_buffer),
extra->ast.allocator
vut_sv_from_vut_str(&extra->dry_flex_text_buffer)
);
// transfers the string to the ast node
extra->dry_flex_text_buffer = vut_str_init(extra->ast.allocator);
extra->dry_flex_text_buffer = vut_str_init(extra->dry_arena);

*lval = ast_add_node(&extra->ast, node);
return TEXT;
}
47 changes: 33 additions & 14 deletions subprojects/vinumc/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>

#include <vutils/arena_allocator.h>
#include <vutils/str.h>
#include <vutils/system_allocator.h>
#include <vutils/vec.h>
Expand All @@ -28,26 +29,45 @@ struct eval_ctx eval_ctx_new(struct vut_allocator allocator) {
.scopes = VUT_VEC_INIT(struct eval_ctx_scopes_t, allocator),
};

struct vut_arena *arena = vut_allocator_malloc(allocator, sizeof(*arena), 1);
*arena = vut_arena_new(allocator, 10 * 1024);
ret.scopes_childs_arena = vut_arena_to_vut_allocator(arena);

arena = vut_allocator_malloc(allocator, sizeof(*arena), 1);
*arena = vut_arena_new(allocator, 10 * 1024);
ret.scopes_namespace_arena = vut_arena_to_vut_allocator(arena);

return ret;
}

static struct scope scope_new(ast_node_id_t node, int father, struct vut_allocator allocator) {
void eval_ctx_free(struct eval_ctx *ctx) {
vut_arena_free_all(ctx->scopes_namespace_arena.base_allocator);
vut_allocator_free(ctx->allocator, ctx->scopes_namespace_arena.base_allocator);

vut_arena_free_all(ctx->scopes_childs_arena.base_allocator);
vut_allocator_free(ctx->allocator, ctx->scopes_childs_arena.base_allocator);

VUT_VEC_FREE(&ctx->scopes);

*ctx = (struct eval_ctx){ 0 };
}

static struct scope scope_new(struct eval_ctx *ctx, ast_node_id_t node, int father) {
struct scope new_scope = {
.father = father,
.node = node,
.childs = VUT_VEC_INIT(struct scope_childs_t, allocator),
.namespace = VUT_VEC_INIT(struct scope_namespace_t, allocator),
.childs = VUT_VEC_INIT(struct scope_childs_t, ctx->scopes_childs_arena),
.namespace = VUT_VEC_INIT(struct scope_namespace_t, ctx->scopes_namespace_arena),
};
return new_scope;
}

static size_t add_scope_child(struct eval_ctx_scopes_t *scope_array, size_t scope_id,
ast_node_id_t node, struct vut_allocator allocator) {
size_t new_scope_id = scope_array->len;
struct scope new_scope = scope_new(node, scope_id, allocator);
static size_t add_scope_child(struct eval_ctx *ctx, size_t father, ast_node_id_t node) {
size_t new_scope_id = ctx->scopes.len;
struct scope new_scope = scope_new(ctx, node, father);

VUT_VEC_PUT(scope_array, new_scope);
struct scope *scope = &scope_array->base[scope_id];
VUT_VEC_PUT(&ctx->scopes, new_scope);
struct scope *scope = &ctx->scopes.base[father];
VUT_VEC_PUT(&scope->childs, new_scope_id);

return new_scope_id;
Expand Down Expand Up @@ -146,8 +166,8 @@ RESOLVE_FUNC_SIGNATURE(resolve_symbols) {
resolve_symbols_assignment(cctx, curr_scope_id, ast_node);
} else {
if (ast_get_type(ast, ast_node) == CALL)
curr_scope_id = add_scope_child(&ctx->scopes, curr_scope_id, ast_node,
ctx->allocator);
curr_scope_id = add_scope_child(ctx, curr_scope_id, ast_node);

resolve_symbols_descent(cctx, curr_scope_id, ast_node);
}
}
Expand Down Expand Up @@ -237,8 +257,7 @@ RESOLVE_FUNC_SIGNATURE(resolve_calls_call) {
if (ast_get_num_child(ast, ast_node) <= 1) {
// ensure that the call node has an ARGS node
// to prevent it from being skipped during evaluation
size_t args_node_id =
ast_add_node(ast, ast_node_new_nvl(ARGS, ast->allocator));
size_t args_node_id = ast_node_new_nvl(ast, ARGS);
ast_add_child(ast, ast_node, args_node_id);
}
}
Expand Down Expand Up @@ -414,7 +433,7 @@ void unload_libs(struct loaded_lib *loaded_libs, struct vut_allocator alloc) {

struct vut_str eval(struct compiler_ctx *cctx) {
struct eval_ctx *ctx = &cctx->eval_ctx;
struct scope base_scope = scope_new(0, -1, ctx->allocator);
struct scope base_scope = scope_new(ctx, 0, -1);
VUT_VEC_PUT(&ctx->scopes, base_scope);

struct loaded_lib *loaded_libs = load_libs(ctx, &cctx->libraries);
Expand Down
4 changes: 4 additions & 0 deletions subprojects/vinumc/eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ struct eval_ctx_scopes_t VUT_VEC_DEF(struct scope);

struct eval_ctx {
struct eval_ctx_scopes_t scopes;

struct vut_allocator allocator;
struct vut_allocator scopes_childs_arena;
struct vut_allocator scopes_namespace_arena;
};

struct eval_ctx eval_ctx_new(struct vut_allocator allocator);
void eval_ctx_free(struct eval_ctx *ctx);

struct sv_vec VUT_VEC_DEF(struct vut_sv);

Expand Down
18 changes: 18 additions & 0 deletions subprojects/vinumc/libvinumc.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "libvinumc.h"
#include "dry_flex.h"
#include <vutils/arena_allocator.h>

struct compiler_ctx compiler_ctx_init(struct vut_allocator alloc) {
struct compiler_ctx ctx = {
Expand All @@ -11,9 +12,26 @@ struct compiler_ctx compiler_ctx_init(struct vut_allocator alloc) {
.alloc = alloc,
};

struct vut_arena *arena = vut_allocator_malloc(alloc, sizeof(*arena), 1);
*arena = vut_arena_new(alloc, 1024),

ctx.dry_arena = vut_arena_to_vut_allocator(arena);
ctx.dry_flex_text_buffer = vut_str_init(ctx.dry_arena);

return ctx;
}

void compiler_ctx_free(struct compiler_ctx *ctx) {
vut_arena_free_all(ctx->dry_arena.base_allocator);
vut_allocator_free(ctx->alloc, ctx->dry_arena.base_allocator);

VUT_VEC_FREE(&ctx->libraries);
eval_ctx_free(&ctx->eval_ctx);
ast_free(&ctx->ast);

*ctx = (struct compiler_ctx){ 0 };
}

typedef struct yy_buffer_state *YY_BUFFER_STATE;

void compiler_parse(struct compiler_ctx *ctx, struct vut_str *program) {
Expand Down
2 changes: 2 additions & 0 deletions subprojects/vinumc/libvinumc.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ struct compiler_ctx {
// that could be just one node
struct vut_str dry_flex_text_buffer;

struct vut_allocator dry_arena;
struct vut_allocator alloc;
};

struct compiler_ctx compiler_ctx_init(struct vut_allocator alloc);
void compiler_ctx_free(struct compiler_ctx *ctx);

void compiler_parse(struct compiler_ctx *ctx, struct vut_str *program);
struct vut_str compiler_eval(struct compiler_ctx *ctx);
Expand Down
7 changes: 7 additions & 0 deletions subprojects/vinumc/vinumc.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ struct ctx ctx_new(struct vut_allocator allocator) {
return ret;
}

void ctx_free(struct ctx *ctx) {
compiler_ctx_free(&ctx->compiler);

*ctx = (struct ctx){ 0 };
}

enum flag_kind {
FLAG_BOOLEAN,
FLAG_ARGUMENT,
Expand Down Expand Up @@ -222,4 +228,5 @@ int main(int argc, char **argv) {
exit:
free_flags(vinumc_flags, ARRAY_SIZE(vinumc_flags));
free(ctx.input_path);
ctx_free(&ctx);
}
Loading