feat: added module reference to AST
This commit is contained in:
parent
805bb3972a
commit
55cd8cac40
|
@ -267,7 +267,8 @@ static void AST_fprint_graphviz_node_definition(FILE* stream,
|
|||
assert(stream != NULL);
|
||||
assert(node != NULL);
|
||||
|
||||
fprintf(stream, "\tnode%p [label=\"%s\"]\n", (void*) node,
|
||||
char* module_path = module_ref_to_str(node->location.module_ref);
|
||||
fprintf(stream, "\tnode%p [label=\"@%s\\n%s\"]\n", (void*) node, module_path,
|
||||
AST_node_to_string(node));
|
||||
|
||||
if (node->children == NULL) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <cfg/opt.h>
|
||||
#include <glib.h>
|
||||
#include <io/files.h>
|
||||
#include <link/driver.h>
|
||||
#include <mem/cache.h>
|
||||
|
@ -152,6 +153,58 @@ const char* extract_env_from_triple(const char* triple)
|
|||
return find_string(triple, known_envs, sizeof(known_envs));
|
||||
}
|
||||
|
||||
guint module_ref_len(ModuleRef* ref) {
|
||||
return ref->module_path->len;
|
||||
}
|
||||
|
||||
char* module_ref_get(ModuleRef* ref, guint idx) {
|
||||
return g_array_index(ref->module_path, char*, idx);
|
||||
}
|
||||
|
||||
void module_ref_push(ModuleRef* ref, char* name) {
|
||||
char* chached_name = mem_strdup(MemoryNamespaceOpt, name);
|
||||
g_array_append_val(ref->module_path, chached_name);
|
||||
}
|
||||
|
||||
void module_ref_pop(ModuleRef* ref) {
|
||||
g_array_remove_index(ref->module_path, ref->module_path->len - 1);
|
||||
}
|
||||
|
||||
char* module_ref_to_str(ModuleRef* ref) {
|
||||
GString* string = g_string_new("");
|
||||
|
||||
if (NULL != ref) {
|
||||
for (guint n = 0; n < ref->module_path->len; n++) {
|
||||
char* module = g_array_index(ref->module_path, char*, n);
|
||||
g_string_append(string, module);
|
||||
|
||||
if (n + 1 < ref->module_path->len) {
|
||||
g_string_append_unichar(string, ':');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* cached_ref = mem_strdup(MemoryNamespaceAst, string->str);
|
||||
g_string_free(string, true);
|
||||
|
||||
return cached_ref;
|
||||
}
|
||||
|
||||
ModuleRef* module_ref_clone(ModuleRef* ref) {
|
||||
ModuleRef* module = mem_alloc(MemoryNamespaceOpt, sizeof(ModuleRef));
|
||||
|
||||
module->module_path = mem_new_g_array(MemoryNamespaceOpt, sizeof(char*));
|
||||
|
||||
for (guint n = 0; n < ref->module_path->len; n++) {
|
||||
char* cstr = g_array_index(ref->module_path, char*, n);
|
||||
char* copy = mem_strdup(MemoryNamespaceOpt, cstr);
|
||||
|
||||
g_array_append_val(module->module_path, copy);
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
static void clean(void) {
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
|
|
@ -16,6 +16,22 @@
|
|||
|
||||
#define TOML_ERROR_MSG_BUF 256
|
||||
|
||||
typedef struct ModuleRef_t {
|
||||
GArray* module_path;
|
||||
} ModuleRef;
|
||||
|
||||
guint module_ref_len(ModuleRef*);
|
||||
|
||||
char* module_ref_get(ModuleRef*, guint idx);
|
||||
|
||||
void module_ref_push(ModuleRef*, char*);
|
||||
|
||||
void module_ref_pop(ModuleRef*);
|
||||
|
||||
char* module_ref_to_str(ModuleRef*);
|
||||
|
||||
ModuleRef* module_ref_clone(ModuleRef*);
|
||||
|
||||
typedef struct TargetLinkConfig_t {
|
||||
// name of object files to link
|
||||
GArray *object_file_names;
|
||||
|
|
|
@ -32,6 +32,10 @@ AST_NODE_PTR root;
|
|||
[[maybe_unused]]
|
||||
ModuleFile* current_file;
|
||||
|
||||
[[maybe_unused]]
|
||||
ModuleRef* parser_ref;
|
||||
ModuleRef* module_ref;
|
||||
|
||||
static int build_project_targets(ModuleFileStack* unit,
|
||||
const ProjectConfig* config);
|
||||
|
||||
|
@ -64,6 +68,7 @@ static int compile_file_to_ast(AST_NODE_PTR ast, ModuleFile* file) {
|
|||
root = ast;
|
||||
current_file = file;
|
||||
yyin = file->handle;
|
||||
parser_ref = module_ref_clone(module_ref);
|
||||
yyrestart(yyin);
|
||||
lex_reset();
|
||||
|
||||
|
@ -232,6 +237,13 @@ static int compile_module_with_dependencies(ModuleFileStack* unit,
|
|||
const TargetConfig* target,
|
||||
AST_NODE_PTR root_module) {
|
||||
|
||||
if (NULL == module_ref) {
|
||||
module_ref = mem_alloc(MemoryNamespaceOpt, sizeof(ModuleRef));
|
||||
module_ref->module_path = mem_new_g_array(MemoryNamespaceOpt, sizeof(char*));
|
||||
}
|
||||
|
||||
module_ref_push(module_ref, g_filename_display_basename(file->path));
|
||||
|
||||
GHashTable* imports =
|
||||
mem_new_g_hash_table(MemoryNamespaceAst, g_str_hash, g_str_equal);
|
||||
|
||||
|
@ -287,7 +299,7 @@ static int compile_module_with_dependencies(ModuleFileStack* unit,
|
|||
|
||||
ModuleFile* imported_file = push_file(unit, path);
|
||||
AST_NODE_PTR imported_module =
|
||||
AST_new_node(empty_location(imported_file), AST_Module, NULL);
|
||||
AST_new_node(empty_location(imported_file, module_ref), AST_Module, NULL);
|
||||
|
||||
if (compile_module_with_dependencies(unit, imported_file, dep_conf, imported_module)
|
||||
== EXIT_SUCCESS) {
|
||||
|
@ -358,9 +370,11 @@ static int compile_module_with_dependencies(ModuleFileStack* unit,
|
|||
continue;
|
||||
}
|
||||
|
||||
module_ref_push(module_ref, g_filename_display_basename(path));
|
||||
|
||||
ModuleFile* imported_file = push_file(unit, path);
|
||||
AST_NODE_PTR imported_module =
|
||||
AST_new_node(empty_location(imported_file), AST_Module, NULL);
|
||||
AST_new_node(empty_location(imported_file, module_ref), AST_Module, NULL);
|
||||
|
||||
if (compile_file_to_ast(imported_module, imported_file)
|
||||
== EXIT_SUCCESS) {
|
||||
|
@ -376,12 +390,16 @@ static int compile_module_with_dependencies(ModuleFileStack* unit,
|
|||
mem_strdup(MemoryNamespaceLld, directory);
|
||||
g_free(directory);
|
||||
g_array_append_val(target->import_paths, cached_directory);
|
||||
|
||||
module_ref_pop(module_ref);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
module_ref_pop(module_ref);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -397,7 +415,7 @@ static int build_target(ModuleFileStack* unit, const TargetConfig* target) {
|
|||
|
||||
ModuleFile* file = push_file(unit, target->root_module);
|
||||
AST_NODE_PTR root_module =
|
||||
AST_new_node(empty_location(file), AST_Module, NULL);
|
||||
AST_new_node(empty_location(file, module_ref), AST_Module, NULL);
|
||||
|
||||
err = compile_module_with_dependencies(unit, file, target, root_module);
|
||||
if (err == EXIT_SUCCESS) {
|
||||
|
|
|
@ -214,7 +214,8 @@ void print_diagnostic(TokenLocation* location, Message kind,
|
|||
TokenLocation new_location(unsigned long int line_start,
|
||||
unsigned long int col_start,
|
||||
unsigned long int line_end,
|
||||
unsigned long int col_end, ModuleFile* file) {
|
||||
unsigned long int col_end,
|
||||
ModuleFile* file, ModuleRef* ref) {
|
||||
TokenLocation location;
|
||||
|
||||
location.line_start = line_start;
|
||||
|
@ -222,11 +223,12 @@ TokenLocation new_location(unsigned long int line_start,
|
|||
location.col_start = col_start;
|
||||
location.col_end = col_end;
|
||||
location.file = file;
|
||||
location.module_ref = ref;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
TokenLocation empty_location(ModuleFile* file) {
|
||||
TokenLocation empty_location(ModuleFile* file, ModuleRef* ref) {
|
||||
TokenLocation location;
|
||||
|
||||
location.line_start = 0;
|
||||
|
@ -234,6 +236,7 @@ TokenLocation empty_location(ModuleFile* file) {
|
|||
location.col_start = 0;
|
||||
location.col_end = 0;
|
||||
location.file = file;
|
||||
location.module_ref = ref;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef GEMSTONE_FILES_H
|
||||
#define GEMSTONE_FILES_H
|
||||
|
||||
#include <cfg/opt.h>
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -38,6 +39,7 @@ typedef struct TokenLocation_t {
|
|||
unsigned long int line_end;
|
||||
unsigned long int col_end;
|
||||
ModuleFile* file;
|
||||
ModuleRef* module_ref;
|
||||
} TokenLocation;
|
||||
|
||||
/**
|
||||
|
@ -74,13 +76,14 @@ void delete_files(ModuleFileStack* stack);
|
|||
TokenLocation new_location(unsigned long int line_start,
|
||||
unsigned long int col_start,
|
||||
unsigned long int line_end,
|
||||
unsigned long int col_end, ModuleFile* file);
|
||||
unsigned long int col_end,
|
||||
ModuleFile* file, ModuleRef* ref);
|
||||
|
||||
/**
|
||||
* @brief Create a new empty location with all of its contents set to zero
|
||||
* @return
|
||||
*/
|
||||
TokenLocation empty_location(ModuleFile* file);
|
||||
TokenLocation empty_location(ModuleFile*, ModuleRef* ref);
|
||||
|
||||
/**
|
||||
* @brief Prints some diagnostic message to stdout.
|
||||
|
|
|
@ -599,6 +599,9 @@ typedef struct Module_t {
|
|||
// to be resolved after the module has been parsed completely
|
||||
GArray* imports;
|
||||
GArray* includes;
|
||||
// parent modules in descending order
|
||||
// root > submodule > current-module
|
||||
GArray* path;
|
||||
} Module;
|
||||
|
||||
// .------------------------------------------------.
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
|
||||
extern char* buffer;
|
||||
extern int yylineno;
|
||||
|
||||
|
||||
extern int yylex();
|
||||
extern AST_NODE_PTR root;
|
||||
|
||||
#define new_loc() new_location(yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column, current_file)
|
||||
extern ModuleRef* parser_ref;
|
||||
|
||||
#define new_loc() new_location(yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column, current_file, parser_ref)
|
||||
}
|
||||
|
||||
%union {
|
||||
|
@ -67,7 +69,7 @@
|
|||
%type <node_ptr> paramlist
|
||||
%type <node_ptr> params
|
||||
%type <node_ptr> IOqualifyier
|
||||
%type <node_ptr> paramdecl
|
||||
%type <node_ptr> paramdecl
|
||||
%type <node_ptr> boxbody
|
||||
%type <node_ptr> boxcontent
|
||||
%type <node_ptr> typecast
|
||||
|
@ -84,7 +86,7 @@
|
|||
%token KeyTo
|
||||
%token <string> ValInt
|
||||
%token <string> Ident
|
||||
%token <string> ValFloat
|
||||
%token <string> ValFloat
|
||||
%token <string> ValStr
|
||||
%token <string> ValChar
|
||||
%token <string> ValMultistr
|
||||
|
@ -145,7 +147,7 @@
|
|||
%left '(' ')' '[' ']'
|
||||
|
||||
%%
|
||||
program: program programbody {AST_push_node(root, $2);
|
||||
program: program programbody {AST_push_node(root, $2);
|
||||
}
|
||||
| programbody {AST_push_node(root, $1);};
|
||||
|
||||
|
@ -286,7 +288,7 @@ box: KeyType KeyBox ':' Ident '{' boxbody '}' {AST_NODE_PTR box = AST_new_node(n
|
|||
AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $4);
|
||||
AST_push_node(box, ident);
|
||||
AST_push_node(box, $6);
|
||||
$$ = box;
|
||||
$$ = box;
|
||||
DEBUG("Box"); }
|
||||
| KeyType KeyBox ':' Ident '{' '}' {AST_NODE_PTR box = AST_new_node(new_loc(), AST_Box, NULL);
|
||||
AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $4);
|
||||
|
@ -335,7 +337,7 @@ boxcall: boxaccess argumentlist {AST_NODE_PTR boxcall = AST_new_node(new_loc(),
|
|||
AST_push_node(boxcall, $1);
|
||||
AST_push_node(boxcall, $2);
|
||||
$$ = boxcall;};
|
||||
|
||||
|
||||
|
||||
typecast: expr KeyAs type %prec KeyAs {AST_NODE_PTR cast = AST_new_node(new_loc(), AST_Typecast, NULL);
|
||||
AST_push_node(cast, $1);
|
||||
|
@ -417,7 +419,7 @@ identlist: Ident ',' identlist {AST_NODE_PTR ident = AST_new_node(new_loc(), AST
|
|||
| Ident {AST_NODE_PTR list = AST_new_node(new_loc(), AST_IdentList, NULL);
|
||||
AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $1);
|
||||
AST_push_node(list, ident);
|
||||
$$ = list;};
|
||||
$$ = list;};
|
||||
|
||||
decl: type ':' identlist {AST_NODE_PTR decl = AST_new_node(new_loc(), AST_Decl, NULL);
|
||||
AST_push_node(decl, $1);
|
||||
|
@ -590,4 +592,4 @@ int yyerror(const char *s) {
|
|||
TokenLocation location = new_loc();
|
||||
print_diagnostic(&location, Error, s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue