🎨 clean main introducing modules.

main
bog 2024-03-27 20:53:06 +01:00
parent e5b7eea0cf
commit 1875adc48d
7 changed files with 176 additions and 74 deletions

View File

@ -18,6 +18,7 @@ add_library(moka-core
moka.c
symtable.c
native.c
module.c
)
target_compile_options(moka-core

View File

@ -33,6 +33,11 @@ struct token* lexer_try_new_next(struct lexer* self)
assert(self);
struct token* tok = NULL;
if (!status_is_ok(self->status) > 0)
{
return NULL;
}
lexer_skip_spaces(self);
if ( (tok=lexer_try_new_text(self, TOKEN_OPAR, "(")) )
@ -348,12 +353,17 @@ struct token* lexer_try_new_ident(struct lexer* self)
cursor++;
}
struct token* tok = malloc(sizeof(struct token));
token_init(tok, TOKEN_IDENT, value.value);
str_free(&value);
if (value.size > 0)
{
struct token* tok = malloc(sizeof(struct token));
token_init(tok, TOKEN_IDENT, value.value);
str_free(&value);
self->context.cursor = cursor;
return tok;
self->context.cursor = cursor;
return tok;
}
return NULL;
}
bool lexer_is_sep(struct lexer* self, size_t index)

90
lib/module.c Normal file
View File

@ -0,0 +1,90 @@
#include "module.h"
void module_init(struct module* self)
{
assert(self);
status_init(&self->status);
moka_init(&self->moka, &self->status);
prog_init(&self->prog);
}
void module_free(struct module* self)
{
assert(self);
status_free(&self->status);
prog_free(&self->prog);
moka_free(&self->moka);
}
int module_load_from_file(struct module* self, char const* path)
{
assert(self);
assert(path);
struct str source;
str_init(&source);
FILE* file = fopen(path, "r+");
size_t sz;
char buf;
while ( (sz=fread(&buf, sizeof(char), 1, file)) )
{
str_push(&source, buf);
}
fclose(file);
int ret = module_load_from_str(self, source.value);
str_free(&source);
return ret;
}
int module_load_from_str(struct module* self, char const* source)
{
status_init(&self->status);
struct lexer lex;
lexer_init(&lex, source, &self->status);
struct parser parser;
parser_init(&parser, &lex);
struct node* root = parser_try_new_root(&parser);
if (!root || !status_is_ok(&self->status))
{
status_dump(&self->status);
goto free_parser;
}
struct compiler compiler;
compiler_init(&compiler, &self->status);
compiler_compile(&compiler, root, &self->prog, &self->moka.symtable);
if (!status_is_ok(&self->status))
{
status_dump(&self->status);
goto free_compiler;
}
struct exec exec;
exec_init(&exec);
exec_prog(&exec, &self->moka, &self->prog);
exec_free(&exec);
free_compiler:
compiler_free(&compiler);
node_free(root);
free(root);
free_parser:
parser_free(&parser);
lexer_free(&lex);
int ret = status_is_ok(&self->status) ? EXIT_SUCCESS : EXIT_FAILURE;
return ret;
}

27
lib/module.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef MK_MODULE_H
#define MK_MODULE_H
#include "commons.h"
#include "status.h"
#include "lexer.h"
#include "parser.h"
#include "prog.h"
#include "moka.h"
#include "compiler.h"
#include "exec.h"
#include "status.h"
struct module
{
struct status status;
struct prog prog;
struct moka moka;
};
void module_init(struct module* self);
void module_free(struct module* self);
int module_load_from_file(struct module* self, char const* path);
int module_load_from_str(struct module* self, char const* source);
#endif

View File

@ -3,6 +3,23 @@
#include "compiler.h"
#include "prog.h"
#include "exec.h"
#include "module.h"
void moka_mod_init(struct moka_mod* self,
char* name,
struct module* new_module)
{
assert(self);
self->name = strdup(name);
self->module = new_module;
}
void moka_mod_free(struct moka_mod* self)
{
free(self->name);
module_free(self->module);
free(self->module);
}
void moka_init(struct moka* self, struct status* status)
{
@ -11,6 +28,7 @@ void moka_init(struct moka* self, struct status* status)
symtable_init(&self->symtable);
vec_init(&self->frame_stack);
vec_init(&self->global_values);
vec_init(&self->modules);
struct frame* frame = malloc(sizeof(struct frame));
frame_init(frame);
@ -37,6 +55,10 @@ void moka_free(struct moka* self)
symtable_free(&self->symtable);
vec_free_elements(&self->frame_stack, (void*) frame_free);
vec_free(&self->frame_stack);
vec_free_elements(&self->modules, (void*) moka_mod_free);
vec_free(&self->modules);
vec_free_elements(&self->global_values, (void*) value_free);
vec_free(&self->global_values);
}

View File

@ -12,14 +12,26 @@ struct frame
struct vec local_values;
};
struct moka_mod
{
char* name;
struct module* module;
};
struct moka
{
struct status* status;
struct symtable symtable;
struct vec frame_stack;
struct vec global_values;
struct vec modules;
};
void moka_mod_init(struct moka_mod* self,
char* name,
struct module* new_module);
void moka_mod_free(struct moka_mod* self);
void moka_init(struct moka* self, struct status* status);
void frame_init(struct frame* self);
void frame_free(struct frame* self);

View File

@ -5,85 +5,25 @@
#include <compiler.h>
#include <exec.h>
#include <moka.h>
#include <module.h>
int main(int argc, char** argv)
{
if (argc <= 1) { return EXIT_FAILURE; }
struct module module;
module_init(&module);
struct status status;
status_init(&status);
struct str source;
str_init(&source);
int ret = module_load_from_file(&module, argv[1]);
if (moka_has_top(&module.moka))
{
FILE* file = fopen(argv[1], "r+");
size_t sz;
char buf;
while ( (sz=fread(&buf, sizeof(char), 1, file)) )
{
str_push(&source, buf);
}
fclose(file);
}
struct lexer lex;
lexer_init(&lex, source.value, &status);
struct parser parser;
parser_init(&parser, &lex);
struct node* root = parser_try_new_root(&parser);
if (!root || !status_is_ok(&status))
{
status_dump(&status);
goto free_parser;
}
struct compiler compiler;
compiler_init(&compiler, &status);
struct prog prog;
prog_init(&prog);
struct moka moka;
moka_init(&moka, &status);
compiler_compile(&compiler, root, &prog, &moka.symtable);
if (!status_is_ok(&status))
{
status_dump(&status);
goto free_moka;
}
struct exec exec;
exec_init(&exec);
exec_prog(&exec, &moka, &prog);
if (moka_has_top(&moka))
{
MOKA value = moka_top(&moka);
moka_dump(&moka, value);
MOKA value = moka_top(&module.moka);
moka_dump(&module.moka, value);
printf("\n");
}
exec_free(&exec);
free_moka:
moka_free(&moka);
prog_free(&prog);
compiler_free(&compiler);
node_free(root);
free(root);
free_parser:
parser_free(&parser);
lexer_free(&lex);
str_free(&source);
int ret = status_is_ok(&status) ? EXIT_SUCCESS : EXIT_FAILURE;
status_free(&status);
module_free(&module);
return ret;
}