Skip to content

Commit

Permalink
Added module system by introducing the import statement and #export d…
Browse files Browse the repository at this point in the history
…irective.
  • Loading branch information
nicholascc committed Apr 14, 2022
1 parent c8eb61b commit 6d0dba7
Show file tree
Hide file tree
Showing 10 changed files with 429 additions and 238 deletions.
26 changes: 19 additions & 7 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@ void print_symbol(symbol symbol) {
printf("%s", str);
}

void print_ast(Ast ast) {
for(int i = 0; i < ast.compilation_units.length; i++) {
print_compilation_unit(ast.compilation_units.data[i]);
printf("\n\n");
}
}

void print_ast_statement_array(Ast_Node_Ptr_Array nodes) {
for(int i = 0; i < nodes.length; i++) {
Ast_Node *node = nodes.data[i];
Expand Down Expand Up @@ -293,6 +286,12 @@ void print_ast_node(Ast_Node *node) {
break;
}

case NODE_IMPORT: {
Ast_Import *n = (Ast_Import *)node;
printf("import \"%s\"", n->filename);
break;
}

case NODE_BLOCK: {
Ast_Block *n = (Ast_Block *)node;
printf("{\n");
Expand Down Expand Up @@ -394,6 +393,19 @@ void print_compilation_unit(Compilation_Unit *unit) {
printf("\n");
break;
}
case UNIT_IMPORT: {
printf("Import:\n");
print_ast_node(unit->node);
printf("\n");
}
case UNIT_MODULE: {
printf("Module (%i):\n", unit->data.module.file_id);
for(int i = 0; i < unit->data.module.compilation_units.length; i++) {
print_compilation_unit(unit->data.module.compilation_units.data[i]);
printf("\n\n");
}
break;
}
default: {
printf("Unknown type of compilation unit.\n");
}
Expand Down
113 changes: 66 additions & 47 deletions src/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef enum Ast_Node_Type {
NODE_FOREIGN_DEFINITION,
NODE_STRUCT_DEFINITION,
NODE_POLY_STRUCT_DEFINITION,
NODE_IMPORT,
NODE_RETURN
} Ast_Node_Type;

Expand All @@ -59,6 +60,50 @@ Ast_Node NULL_AST_NODE;

GENERATE_DARRAY_HEADER(Ast_Node *, Ast_Node_Ptr_Array);

typedef struct Compilation_Unit Compilation_Unit;

typedef struct Scope_Entry {
symbol symbol;
union { // Determined based on the parent Scope object's type property
struct {
Type type;
} basic;
struct {
Type type;
u32 register_id;
} reg;
struct {
Compilation_Unit *unit;
} unit;
struct {
Ast_Node *node;
u32 param_index;
} struct_;
struct {
Type value; // value of the parameter in this instance
} type;
} data;
} Scope_Entry;

GENERATE_DARRAY_HEADER(Scope_Entry, Scope_Entry_Array);

typedef enum Scope_Type {
SYMBOL_SCOPE, // only stores symbols
BASIC_SCOPE, // only stores type information, without any associated register information.
REGISTER_SCOPE, // things stored in registers
UNIT_SCOPE, // compilation unit scope
STRUCT_SCOPE, // stores struct members
TYPE_SCOPE // stores types
} Scope_Type;

typedef struct Scope {
Scope_Type type;
bool has_parent;
Scope *parent;
Scope_Entry_Array entries;
} Scope;


typedef struct Bytecode_Unit Bytecode_Unit;

typedef enum Compilation_Unit_Type {
Expand All @@ -71,7 +116,10 @@ typedef enum Compilation_Unit_Type {
UNIT_STRUCT_MEMBER, // represents both struct members and poly instance members.
UNIT_POLY_STRUCT,
UNIT_POLY_FUNCTION,
UNIT_FOREIGN_FUNCTION
UNIT_FOREIGN_FUNCTION,
UNIT_IMPORT,

UNIT_MODULE
} Compilation_Unit_Type;

typedef struct Compilation_Unit Compilation_Unit;
Expand Down Expand Up @@ -121,55 +169,18 @@ typedef struct Compilation_Unit {
u32 current_instance_id; // starts at 0, is incremented by one each time an instance is assigned an ID during bytecode generation.
Compilation_Unit_Ptr_Table instances; // hashed by the types of the bound type arguments
} poly_function_def;
} data;
} Compilation_Unit;

typedef struct Scope_Entry {
symbol symbol;
union { // Determined based on the parent Scope object's type property
struct {
Type type;
} basic;
struct {
Type type;
u32 register_id;
} reg;
struct {
Compilation_Unit *unit;
} unit;
struct {
Ast_Node *node;
u32 param_index;
} struct_;
Compilation_Unit *module;
} import;

struct {
Type value; // value of the parameter in this instance
} type;
int file_id;
Compilation_Unit_Ptr_Array compilation_units;
Scope scope;
} module;
} data;
} Scope_Entry;

GENERATE_DARRAY_HEADER(Scope_Entry, Scope_Entry_Array);

typedef enum Scope_Type {
SYMBOL_SCOPE, // only stores symbols
BASIC_SCOPE, // only stores type information, without any associated register information.
REGISTER_SCOPE, // things stored in registers
UNIT_SCOPE, // compilation unit scope
STRUCT_SCOPE, // stores struct members
TYPE_SCOPE // stores types
} Scope_Type;

typedef struct Scope {
Scope_Type type;
bool has_parent;
Scope *parent;
Scope_Entry_Array entries;
} Scope;

typedef struct Ast {
Compilation_Unit_Ptr_Array compilation_units;
Scope scope;
} Ast;

} Compilation_Unit;



Expand Down Expand Up @@ -343,6 +354,7 @@ typedef struct Ast_Function_Definition {
Function_Definition_Type def_type;
bool is_inline;
bool is_operator;
bool is_export;
Type return_type; // not relevant for FN_POLYMORPHIC
Scope bound_type_scope;
Scope parameter_scope; // subscope of bound_type_scope
Expand All @@ -352,6 +364,7 @@ typedef struct Ast_Function_Definition {
typedef struct Ast_Foreign_Definition {
Ast_Node n;
symbol symbol;
bool is_export;
Ast_Node_Ptr_Array parameters;
Type_Array parameter_types;
Ast_Node *return_type_node;
Expand All @@ -361,19 +374,26 @@ typedef struct Ast_Foreign_Definition {
typedef struct Ast_Struct_Definition {
Ast_Node n;
symbol symbol;
bool is_export;
Type type;
Compilation_Unit_Ptr_Array members;
} Ast_Struct_Definition;

typedef struct Ast_Poly_Struct_Definition {
Ast_Node n;
symbol symbol;
bool is_export;
Ast_Node_Ptr_Array parameters;
Scope param_scope;
Scope member_scope;
Ast_Node_Ptr_Array members;
} Ast_Poly_Struct_Definition;

typedef struct Ast_Import {
Ast_Node n;
char *filename;
} Ast_Import;

typedef struct Ast_Return {
Ast_Node n;
bool is_return_nothing;
Expand All @@ -386,7 +406,6 @@ Compilation_Unit *allocate_null_compilation_unit();
Compilation_Unit *allocate_compilation_unit(Compilation_Unit unit);

void print_symbol(symbol symbol);
void print_ast(Ast ast);
void print_ast_statement_array(Ast_Node_Ptr_Array nodes);
void print_ast_node(Ast_Node *node);
void print_scope(Scope scope, bool print_entries);
Expand Down
10 changes: 8 additions & 2 deletions src/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@ void init_file_array(void) {
}

// @Incomplete: check if file has already been added
char *add_file(char *filename) {
int add_file(char *filename) {
for(int i = 0; i < files.length; i++) {
if(strcmp(filename, files.data[i].filename) == 0) {
return i;
}
}
File_Data d;
d.filename = filename;
d.contents = os_load_file(filename);
d.parsed = false;
File_Array_push(&files, d);
return d.contents;
return files.length-1;
}
10 changes: 9 additions & 1 deletion src/files.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
#ifndef FILES_H
#define FILES_H

#include "stdbool.h"

#include "c-utils/darray.h"
#include "lexer.h"

typedef struct Compilation_Unit Compilation_Unit;

typedef struct File_Data {
char *filename;
char *contents;
bool parsed;
Token_Array tokens;
Compilation_Unit *module;
} File_Data;

GENERATE_DARRAY_HEADER(File_Data, File_Array);

extern File_Array files;

void init_file_array(void);
char *add_file(char *filename);
int add_file(char *filename);

#endif /* end of include guard: FILES_H */
5 changes: 4 additions & 1 deletion src/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ void print_token(Token t) {
case TFN: printf("fn"); break;
case TSTRUCT: printf("struct"); break;
case TFOREIGN: printf("foreign"); break;
case TIMPORT: printf("import"); break;
case TRETURN: printf("return"); break;
case TIF: printf("if"); break;
case TELSE: printf("else"); break;
Expand Down Expand Up @@ -262,6 +263,8 @@ Token_Array lex_string(char *to_lex, int file_id) {
t.type = TSTRUCT;
} else if(len == 7 && 0 == memcmp(symbol_str, "foreign", 7)) {
t.type = TFOREIGN;
} else if(len == 6 && 0 == memcmp(symbol_str, "import", 6)) {
t.type = TIMPORT;
} else if(len == 5 && 0 == memcmp(symbol_str, "while", 5)) {
t.type = TWHILE;
} else if(len == 4 && 0 == memcmp(symbol_str, "each", 4)) {
Expand Down Expand Up @@ -317,7 +320,7 @@ Token_Array lex_string(char *to_lex, int file_id) {
loc.character++;
i += 1;
}
result_str[i-1] = 0;
result_str[len-1] = 0;

t.data.literal_string = result_str;
Token_Array_push(&tokens, t);
Expand Down
1 change: 1 addition & 0 deletions src/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef enum Token_Type {
TFN,
TSTRUCT,
TFOREIGN,
TIMPORT,
TRETURN,
TIF,
TELSE,
Expand Down
20 changes: 8 additions & 12 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,25 @@ int main(int argc, char *argv[]) {
init_file_array();
bytecode_units = init_Bytecode_Unit_Ptr_Array(2);

char *contents = add_file(source_file);

Ast *ast;
{
Token_Array tokens = lex_string(contents, 0);
Token_Reader reader = (Token_Reader){tokens, 0, 0};
ast = parse_file(&reader);
free(tokens.data);
}
int main_file_id = add_file(source_file);

Compilation_Unit *main_module = parse_file(main_file_id);
assert(main_module->type == UNIT_MODULE);

if(should_exit_after_parsing) {
printf("An error occurred during parsing, exiting.\n");
exit(1);
}

//printf("\n\nParsed result:\n\n");
//print_ast(*ast);
// print_compilation_unit(main_module);

bool compilation_has_errors = false;

Bytecode_Unit *main;
bool main_found = false;
for(int i = 0; i < ast->scope.entries.length; i++) {
Scope_Entry entry = ast->scope.entries.data[i];
for(int i = 0; i < main_module->data.module.scope.entries.length; i++) {
Scope_Entry entry = main_module->data.module.scope.entries.data[i];
Compilation_Unit *unit = entry.data.unit.unit;
if(unit->type == UNIT_FUNCTION_SIGNATURE) {
Compilation_Unit *body = unit->data.signature.body;
Expand Down
Loading

0 comments on commit 6d0dba7

Please sign in to comment.