diff --git a/src/ast/ast.c b/src/ast/ast.c index 7c7c98b..67f841a 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -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) { diff --git a/src/cfg/opt.c b/src/cfg/opt.c index 7c83bfe..559cc66 100644 --- a/src/cfg/opt.c +++ b/src/cfg/opt.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -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; diff --git a/src/cfg/opt.h b/src/cfg/opt.h index 281ffb9..4776840 100644 --- a/src/cfg/opt.h +++ b/src/cfg/opt.h @@ -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; diff --git a/src/compiler.c b/src/compiler.c index fac0dba..383ab5e 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -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) { diff --git a/src/io/files.c b/src/io/files.c index 96c7234..dd4d960 100644 --- a/src/io/files.c +++ b/src/io/files.c @@ -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; } diff --git a/src/io/files.h b/src/io/files.h index 2a512a3..6f31108 100644 --- a/src/io/files.h +++ b/src/io/files.h @@ -5,6 +5,7 @@ #ifndef GEMSTONE_FILES_H #define GEMSTONE_FILES_H +#include #include #include @@ -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. diff --git a/src/set/types.h b/src/set/types.h index de294df..a5a37e5 100644 --- a/src/set/types.h +++ b/src/set/types.h @@ -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; // .------------------------------------------------. diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 2b43040..46f4477 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -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 paramlist %type params %type IOqualifyier -%type paramdecl +%type paramdecl %type boxbody %type boxcontent %type typecast @@ -84,7 +86,7 @@ %token KeyTo %token ValInt %token Ident -%token ValFloat +%token ValFloat %token ValStr %token ValChar %token 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; -} \ No newline at end of file +}