From bedf01796b20b7aaac5f18c0834b9ea1801cd1cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:58:06 +0800 Subject: [PATCH 01/26] check for main --- src/codegen.c | 17 +++++++++++++++-- src/main.c | 18 ++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 364e77eb..9aaa83c4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -497,8 +497,10 @@ static void codegen_function_or_method_def(struct State *st, const CfGraph *cfg) free(st->llvm_locals); } -LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft) +LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft, bool checkmain) { + bool mainflag = false; + struct State st = { .module = LLVMModuleCreateWithName(cfgfile->filename), .builder = LLVMCreateBuilder(), @@ -514,8 +516,19 @@ LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft) LLVMSetInitializer(globalptr, LLVMConstNull(t)); } - for (CfGraph **g = cfgfile->graphs.ptr; g < End(cfgfile->graphs); g++) + for (CfGraph **g = cfgfile->graphs.ptr; g < End(cfgfile->graphs); g++) { + if (strcmp((*g)->signature.name, "main") == 0) + mainflag = true; codegen_function_or_method_def(&st, *g); + } + + if (checkmain && mainflag == false) { + struct Location l = { + .filename = cfgfile->filename, + .lineno = 1, + }; + fail(l, "missing `main` function to execute the program"); + } LLVMDisposeBuilder(st.builder); return st.module; diff --git a/src/main.c b/src/main.c index c37a9882..b47a5766 100644 --- a/src/main.c +++ b/src/main.c @@ -243,7 +243,7 @@ static void parse_all_pending_files(struct CompileState *compst) free(compst->parse_queue.ptr); } -static char *compile_ast_to_object_file(struct FileState *fs) +static char *compile_ast_to_object_file(struct FileState *fs, bool checkmain) { if (command_line_args.verbosity >= 1) printf("Building Control Flow Graphs: %s\n", fs->path); @@ -265,7 +265,7 @@ static char *compile_ast_to_object_file(struct FileState *fs) if (command_line_args.verbosity >= 1) printf("Building LLVM IR: %s\n", fs->path); - LLVMModuleRef mod = codegen(&cfgfile, &fs->types); + LLVMModuleRef mod = codegen(&cfgfile, &fs->types, checkmain); free_control_flow_graphs(&cfgfile); if (command_line_args.verbosity >= 2) @@ -439,7 +439,8 @@ int main(int argc, char **argv) printf("Data layout: %s\n", get_target()->data_layout); } - if (command_line_args.tokenize_only || command_line_args.parse_only) { + if (command_line_args.tokenize_only || command_line_args.parse_only) + { FILE *f = open_the_file(command_line_args.infile, NULL); Token *tokens = tokenize(f, command_line_args.infile); fclose(f); @@ -490,7 +491,16 @@ int main(int argc, char **argv) char **objpaths = calloc(sizeof objpaths[0], compst.files.len + 1); for (struct FileState *fs = compst.files.ptr; fs < End(compst.files); fs++) - objpaths[fs - compst.files.ptr] = compile_ast_to_object_file(fs); + { + if (strcmp(command_line_args.infile, fs->path) == 0) + { + objpaths[fs - compst.files.ptr] = compile_ast_to_object_file(fs, true); + } + else + { + objpaths[fs - compst.files.ptr] = compile_ast_to_object_file(fs, false); + } + } for (struct FileState *fs = compst.files.ptr; fs < End(compst.files); fs++) { free_ast(&fs->ast); From c41f337315e79729844766724504c678bd6fc8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:59:20 +0800 Subject: [PATCH 02/26] add test --- tests/other_errors/missing_main_function.jou | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/other_errors/missing_main_function.jou diff --git a/tests/other_errors/missing_main_function.jou b/tests/other_errors/missing_main_function.jou new file mode 100644 index 00000000..1ea2cacb --- /dev/null +++ b/tests/other_errors/missing_main_function.jou @@ -0,0 +1,4 @@ +# Error: missing `main` function to execute the program +def test() -> None: + _ = "lol no main func" + From f6ddffb64229a8d536c7cb3d288729fc628e9e62 Mon Sep 17 00:00:00 2001 From: littlewhitecloud Date: Tue, 9 Jul 2024 12:03:02 +0000 Subject: [PATCH 03/26] Change files to use LF line endings --- tests/other_errors/missing_main_function.jou | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/other_errors/missing_main_function.jou b/tests/other_errors/missing_main_function.jou index 1ea2cacb..83c6d85d 100644 --- a/tests/other_errors/missing_main_function.jou +++ b/tests/other_errors/missing_main_function.jou @@ -1,4 +1,4 @@ -# Error: missing `main` function to execute the program -def test() -> None: - _ = "lol no main func" - +# Error: missing `main` function to execute the program +def test() -> None: + _ = "lol no main func" + From b9f835b1e145a1d95aa0673452607169c5e9fed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:04:36 +0800 Subject: [PATCH 04/26] forget it --- src/jou_compiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jou_compiler.h b/src/jou_compiler.h index c505e4a4..cc990c22 100644 --- a/src/jou_compiler.h +++ b/src/jou_compiler.h @@ -628,7 +628,7 @@ AstFile parse(const Token *tokens, const char *stdlib_path); // Type checking happens between parsing and building CFGs. CfGraphFile build_control_flow_graphs(const AstFile *ast, FileTypes *ft); void simplify_control_flow_graphs(const CfGraphFile *cfgfile); -LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft); +LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft, bool checkmain); char *compile_to_object_file(LLVMModuleRef module); char *get_default_exe_path(void); void run_linker(const char *const *objpaths, const char *exepath); From f39c38292ae8542069732a4aa6f4310baaeb31d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:06:36 +0800 Subject: [PATCH 05/26] del tra line --- src/codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen.c b/src/codegen.c index 9aaa83c4..4ea198e1 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -521,7 +521,7 @@ LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft, bool chec mainflag = true; codegen_function_or_method_def(&st, *g); } - + if (checkmain && mainflag == false) { struct Location l = { .filename = cfgfile->filename, From 05330b00803de65ea721ff7ab69e6741cac769d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Fri, 12 Jul 2024 22:05:52 +0800 Subject: [PATCH 06/26] don't need a linenumber anymore --- src/codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen.c b/src/codegen.c index 4ea198e1..35bcc6b0 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -525,7 +525,7 @@ LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft, bool chec if (checkmain && mainflag == false) { struct Location l = { .filename = cfgfile->filename, - .lineno = 1, + .lineno = 0, }; fail(l, "missing `main` function to execute the program"); } From ccda81f4f15c6f66e09ebbf7f5868d72e87495d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Fri, 12 Jul 2024 22:17:49 +0800 Subject: [PATCH 07/26] Update missing_main_function.jou --- tests/other_errors/missing_main_function.jou | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/other_errors/missing_main_function.jou b/tests/other_errors/missing_main_function.jou index 83c6d85d..dbf251de 100644 --- a/tests/other_errors/missing_main_function.jou +++ b/tests/other_errors/missing_main_function.jou @@ -1,4 +1,3 @@ -# Error: missing `main` function to execute the program def test() -> None: _ = "lol no main func" - + # Output: missing `main` function to execute the program From 3f1622fdb608ea9868ab946fddefe97ad5c8117d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Fri, 12 Jul 2024 23:02:37 +0800 Subject: [PATCH 08/26] self_hosted_compiler --- self_hosted/create_llvm_ir.jou | 9 ++++++++- self_hosted/main.jou | 6 +++++- self_hosted/runs_wrong.txt | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/self_hosted/create_llvm_ir.jou b/self_hosted/create_llvm_ir.jou index ddd0d4ff..764a94ee 100644 --- a/self_hosted/create_llvm_ir.jou +++ b/self_hosted/create_llvm_ir.jou @@ -858,7 +858,7 @@ def file_defines_global_var(ast: AstFile*, name: byte*) -> bool: return False -def create_llvm_ir(ast: AstFile*, ft: FileTypes*) -> LLVMModule*: +def create_llvm_ir(ast: AstFile*, ft: FileTypes*, checkmain: bool) -> LLVMModule*: module = LLVMModuleCreateWithName(ast->path) LLVMSetTarget(module, target.triple) LLVMSetDataLayout(module, target.data_layout) @@ -874,9 +874,12 @@ def create_llvm_ir(ast: AstFile*, ft: FileTypes*) -> LLVMModule*: builder = LLVMCreateBuilder(), file_types = ft } + mainflag: bool = False for s = ast->body.statements; s < &ast->body.statements[ast->body.nstatements]; s++: if s->kind == AstStatementKind::Function and s->function.body.nstatements > 0: + if strcmp((&s->function.signature)->name, "main") == 0: + mainflag = True a2i.define_function_or_method(&s->function, NULL) elif s->kind == AstStatementKind::Class: classdef = &s->classdef @@ -889,5 +892,9 @@ def create_llvm_ir(ast: AstFile*, ft: FileTypes*) -> LLVMModule*: # TODO: need to handle some others? pass + if not mainflag and checkmain: + l: Location = Location{path = ast->path, lineno = 0} + fail(l, "missing `main` function to execute the program") + LLVMDisposeBuilder(a2i.builder) return module diff --git a/self_hosted/main.jou b/self_hosted/main.jou index 8be8f3aa..18297ec2 100644 --- a/self_hosted/main.jou +++ b/self_hosted/main.jou @@ -347,10 +347,14 @@ class Compiler: paths = self->get_object_file_paths() for i = 0; i < self->nfiles; i++: + checkmain: bool = False if self->verbosity >= 1: printf("Build LLVM IR: %s\n", self->files[i].ast.path) - module = create_llvm_ir(&self->files[i].ast, &self->files[i].typectx) + if strcmp(self->args->main_path, self->files[i].ast.path) == 0: + checkmain = True + + module = create_llvm_ir(&self->files[i].ast, &self->files[i].typectx, checkmain) if self->verbosity >= 2: # Don't want to use LLVMDumpModule() because it dumps to stdout. # When redirected, stdout and stderr tend to get mixed up into a weird order. diff --git a/self_hosted/runs_wrong.txt b/self_hosted/runs_wrong.txt index 429a878e..3a2f2392 100644 --- a/self_hosted/runs_wrong.txt +++ b/self_hosted/runs_wrong.txt @@ -16,3 +16,4 @@ tests/syntax_error/assign_to_None.jou tests/syntax_error/None_as_value.jou tests/should_succeed/method_by_value.jou tests/wrong_type/self_annotation.jou +tests/should_succeed/file.jou From 73dc4268f2eed170e9a1e16bd17c9238e163a887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Fri, 12 Jul 2024 23:05:26 +0800 Subject: [PATCH 09/26] remove --fix --- self_hosted/runs_wrong.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/self_hosted/runs_wrong.txt b/self_hosted/runs_wrong.txt index 3a2f2392..429a878e 100644 --- a/self_hosted/runs_wrong.txt +++ b/self_hosted/runs_wrong.txt @@ -16,4 +16,3 @@ tests/syntax_error/assign_to_None.jou tests/syntax_error/None_as_value.jou tests/should_succeed/method_by_value.jou tests/wrong_type/self_annotation.jou -tests/should_succeed/file.jou From 3055a32ae94e5fa7f01d305c9e24e791e56cdb26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 12:05:17 +0800 Subject: [PATCH 10/26] output --- tests/other_errors/missing_main_function.jou | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/other_errors/missing_main_function.jou b/tests/other_errors/missing_main_function.jou index dbf251de..4f4cbb4f 100644 --- a/tests/other_errors/missing_main_function.jou +++ b/tests/other_errors/missing_main_function.jou @@ -1,3 +1,3 @@ +# Output: compiler error in file "tests/other_errors/missing_main_function.jou": missing `main` function to execute the program def test() -> None: _ = "lol no main func" - # Output: missing `main` function to execute the program From caa512cd21c38f3a3ab5e9864dea6df45f6fa981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 13:04:26 +0800 Subject: [PATCH 11/26] check for import --- src/codegen.c | 16 +++++++++++----- src/main.c | 8 ++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 35bcc6b0..8fe8c1b1 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -516,20 +516,26 @@ LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft, bool chec LLVMSetInitializer(globalptr, LLVMConstNull(t)); } - for (CfGraph **g = cfgfile->graphs.ptr; g < End(cfgfile->graphs); g++) { - if (strcmp((*g)->signature.name, "main") == 0) + for (CfGraph **g = cfgfile->graphs.ptr; g < End(cfgfile->graphs); g++) + if (strcmp((*g)->signature.name, "main") == 0) { mainflag = true; - codegen_function_or_method_def(&st, *g); - } + break; + } - if (checkmain && mainflag == false) { + + if (checkmain && mainflag == false) + { struct Location l = { .filename = cfgfile->filename, .lineno = 0, }; + // check main function for the file fail(l, "missing `main` function to execute the program"); } + for (CfGraph **g = cfgfile->graphs.ptr; g < End(cfgfile->graphs); g++) + codegen_function_or_method_def(&st, *g); + LLVMDisposeBuilder(st.builder); return st.module; } diff --git a/src/main.c b/src/main.c index b47a5766..77988796 100644 --- a/src/main.c +++ b/src/main.c @@ -392,6 +392,14 @@ static void add_imported_symbols(struct CompileState *compst) Append(&seen_before, from); for (struct ExportSymbol *es = from->pending_exports; es->name[0]; es++) { + if (strcmp(es->name, "main") == 0) + { + struct Location l = { + .filename = from->path, + .lineno = 0, + }; + fail(l, "imported file should not have `main` function"); + } if (command_line_args.verbosity >= 2) { const char *kindstr; switch(es->kind) { From 86992de935c7affb269edc20996c3d2bb3e17e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 13:04:48 +0800 Subject: [PATCH 12/26] check for import --- self_hosted/main.jou | 3 +++ 1 file changed, 3 insertions(+) diff --git a/self_hosted/main.jou b/self_hosted/main.jou index 18297ec2..b9aabc9d 100644 --- a/self_hosted/main.jou +++ b/self_hosted/main.jou @@ -258,6 +258,9 @@ class Compiler: " %s: imported in %s, exported in %s\n", exp->name, src->ast.path, dest->ast.path, ) + if strcmp(exp->name, "main") == 0: + l: Location = Location{path=src->ast.path, lineno = 0} + fail(l, "imported file should not have `main` function") check_ast_and_import_conflicts(&dest->ast, exp) dest->typectx.add_imported_symbol(exp) From 26214bd37df93a5fa66d1022f67b0b36f3be8952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 13:05:31 +0800 Subject: [PATCH 13/26] add test --- tests/other_errors/import_file_with_main.jou | 7 +++++++ tests/other_errors/imported.jou | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/other_errors/import_file_with_main.jou create mode 100644 tests/other_errors/imported.jou diff --git a/tests/other_errors/import_file_with_main.jou b/tests/other_errors/import_file_with_main.jou new file mode 100644 index 00000000..f03af8d6 --- /dev/null +++ b/tests/other_errors/import_file_with_main.jou @@ -0,0 +1,7 @@ +import "./imported.jou" +import "stdlib/io.jou" + +def main() -> int: + printf("%d", add(114, 514)) + + return 0 diff --git a/tests/other_errors/imported.jou b/tests/other_errors/imported.jou new file mode 100644 index 00000000..e695b03a --- /dev/null +++ b/tests/other_errors/imported.jou @@ -0,0 +1,9 @@ +import "stdlib/io.jou" + +def add(a: int, b: int) -> int: + return a + b + +def main() -> int: # Output: compiler error in file "tests/other_errors/imported.jou": imported file should not have `main` function + printf("%d", add(1, 2)) + + return 0 From f231a200aa451166962f74a1c7eb2b68c5f21230 Mon Sep 17 00:00:00 2001 From: littlewhitecloud Date: Sat, 13 Jul 2024 05:06:29 +0000 Subject: [PATCH 14/26] Change files to use LF line endings --- tests/other_errors/import_file_with_main.jou | 14 +++++++------- tests/other_errors/imported.jou | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/other_errors/import_file_with_main.jou b/tests/other_errors/import_file_with_main.jou index f03af8d6..4f9171f5 100644 --- a/tests/other_errors/import_file_with_main.jou +++ b/tests/other_errors/import_file_with_main.jou @@ -1,7 +1,7 @@ -import "./imported.jou" -import "stdlib/io.jou" - -def main() -> int: - printf("%d", add(114, 514)) - - return 0 +import "./imported.jou" +import "stdlib/io.jou" + +def main() -> int: + printf("%d", add(114, 514)) + + return 0 diff --git a/tests/other_errors/imported.jou b/tests/other_errors/imported.jou index e695b03a..df6f5d81 100644 --- a/tests/other_errors/imported.jou +++ b/tests/other_errors/imported.jou @@ -1,9 +1,9 @@ -import "stdlib/io.jou" - -def add(a: int, b: int) -> int: - return a + b - -def main() -> int: # Output: compiler error in file "tests/other_errors/imported.jou": imported file should not have `main` function - printf("%d", add(1, 2)) - - return 0 +import "stdlib/io.jou" + +def add(a: int, b: int) -> int: + return a + b + +def main() -> int: # Output: compiler error in file "tests/other_errors/imported.jou": imported file should not have `main` function + printf("%d", add(1, 2)) + + return 0 From f9f9dfaf42922cc30481f4bbf8aa946fc7df0fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 15:46:07 +0800 Subject: [PATCH 15/26] Delete tests/other_errors/imported.jou --- tests/other_errors/imported.jou | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 tests/other_errors/imported.jou diff --git a/tests/other_errors/imported.jou b/tests/other_errors/imported.jou deleted file mode 100644 index df6f5d81..00000000 --- a/tests/other_errors/imported.jou +++ /dev/null @@ -1,9 +0,0 @@ -import "stdlib/io.jou" - -def add(a: int, b: int) -> int: - return a + b - -def main() -> int: # Output: compiler error in file "tests/other_errors/imported.jou": imported file should not have `main` function - printf("%d", add(1, 2)) - - return 0 From 3a8615accd92fb7ec8d8aece5694991b62dba18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 15:47:10 +0800 Subject: [PATCH 16/26] update test --- tests/other_errors/import_file_with_main.jou | 14 +++++++------- tests/other_errors/imported/imported.jou | 10 ++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 tests/other_errors/imported/imported.jou diff --git a/tests/other_errors/import_file_with_main.jou b/tests/other_errors/import_file_with_main.jou index 4f9171f5..ff4a1c08 100644 --- a/tests/other_errors/import_file_with_main.jou +++ b/tests/other_errors/import_file_with_main.jou @@ -1,7 +1,7 @@ -import "./imported.jou" -import "stdlib/io.jou" - -def main() -> int: - printf("%d", add(114, 514)) - - return 0 +import "./imported/imported.jou" +import "stdlib/io.jou" + +def main() -> int: # Output: compiler error in file "tests/other_errors/imported/imported.jou": imported file should not have `main` function + printf("%d", add(114, 514)) + + return 0 diff --git a/tests/other_errors/imported/imported.jou b/tests/other_errors/imported/imported.jou new file mode 100644 index 00000000..846baf44 --- /dev/null +++ b/tests/other_errors/imported/imported.jou @@ -0,0 +1,10 @@ +# This file is meant to be imported, not ran directly. + +import "stdlib/io.jou" + +def add(a: int, b: int) -> int: + return a + b + +def main() -> int: + printf("%d", add(1, 2)) + return 0 From 54c6dfd466f88b0aa3b834af7bfce0f3509600ee Mon Sep 17 00:00:00 2001 From: littlewhitecloud Date: Sat, 13 Jul 2024 07:47:25 +0000 Subject: [PATCH 17/26] Change files to use LF line endings --- tests/other_errors/import_file_with_main.jou | 14 +++++++------- tests/other_errors/imported/imported.jou | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/other_errors/import_file_with_main.jou b/tests/other_errors/import_file_with_main.jou index ff4a1c08..687dd656 100644 --- a/tests/other_errors/import_file_with_main.jou +++ b/tests/other_errors/import_file_with_main.jou @@ -1,7 +1,7 @@ -import "./imported/imported.jou" -import "stdlib/io.jou" - -def main() -> int: # Output: compiler error in file "tests/other_errors/imported/imported.jou": imported file should not have `main` function - printf("%d", add(114, 514)) - - return 0 +import "./imported/imported.jou" +import "stdlib/io.jou" + +def main() -> int: # Output: compiler error in file "tests/other_errors/imported/imported.jou": imported file should not have `main` function + printf("%d", add(114, 514)) + + return 0 diff --git a/tests/other_errors/imported/imported.jou b/tests/other_errors/imported/imported.jou index 846baf44..332d8231 100644 --- a/tests/other_errors/imported/imported.jou +++ b/tests/other_errors/imported/imported.jou @@ -1,10 +1,10 @@ -# This file is meant to be imported, not ran directly. - -import "stdlib/io.jou" - -def add(a: int, b: int) -> int: - return a + b - -def main() -> int: - printf("%d", add(1, 2)) - return 0 +# This file is meant to be imported, not ran directly. + +import "stdlib/io.jou" + +def add(a: int, b: int) -> int: + return a + b + +def main() -> int: + printf("%d", add(1, 2)) + return 0 From 8d86e969f381e44c6bf8a2d1481e746ac1abc611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 22:27:17 +0800 Subject: [PATCH 18/26] move --- tests/should_succeed/import_cycle.jou | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 tests/should_succeed/import_cycle.jou diff --git a/tests/should_succeed/import_cycle.jou b/tests/should_succeed/import_cycle.jou deleted file mode 100644 index 88ca31b6..00000000 --- a/tests/should_succeed/import_cycle.jou +++ /dev/null @@ -1,22 +0,0 @@ -import "stdlib/io.jou" -import "./imported/cycle.jou" - -def a(x: int) -> None: - printf("a %d\n", x) - if x > 0: - b(x-1) - -# Output: a 10 -# Output: b 9 -# Output: a 8 -# Output: b 7 -# Output: a 6 -# Output: b 5 -# Output: a 4 -# Output: b 3 -# Output: a 2 -# Output: b 1 -# Output: a 0 -def main() -> int: - a(10) - return 0 From 6ccdab5b719aa6ed31488091e0968fbeeb5a53b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 22:27:30 +0800 Subject: [PATCH 19/26] move --- tests/should_succeed/imported/cycle.jou | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 tests/should_succeed/imported/cycle.jou diff --git a/tests/should_succeed/imported/cycle.jou b/tests/should_succeed/imported/cycle.jou deleted file mode 100644 index eab37a1d..00000000 --- a/tests/should_succeed/imported/cycle.jou +++ /dev/null @@ -1,9 +0,0 @@ -# This file is meant to be imported, not ran directly. - -import "stdlib/io.jou" -import "../import_cycle.jou" - -def b(x: int) -> None: - printf("b %d\n", x) - if x > 0: - a(x-1) From 424e17f428343c17c35c057f8fd2fbb1f9b2b8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Sat, 13 Jul 2024 22:27:52 +0800 Subject: [PATCH 20/26] move --- tests/other_errors/import_cycle.jou | 12 ++++++++++++ tests/other_errors/imported/cycle.jou | 9 +++++++++ tests/other_errors/imported/imported.jou | 20 ++++++++++---------- 3 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 tests/other_errors/import_cycle.jou create mode 100644 tests/other_errors/imported/cycle.jou diff --git a/tests/other_errors/import_cycle.jou b/tests/other_errors/import_cycle.jou new file mode 100644 index 00000000..ba369ae6 --- /dev/null +++ b/tests/other_errors/import_cycle.jou @@ -0,0 +1,12 @@ +import "stdlib/io.jou" +import "./imported/cycle.jou" + +def a(x: int) -> None: + printf("a %d\n", x) + if x > 0: + b(x-1) + +# Output: compiler error in file "tests/other_errors/import_cycle.jou": imported file should not have `main` function +def main() -> int: + a(10) + return 0 diff --git a/tests/other_errors/imported/cycle.jou b/tests/other_errors/imported/cycle.jou new file mode 100644 index 00000000..eab37a1d --- /dev/null +++ b/tests/other_errors/imported/cycle.jou @@ -0,0 +1,9 @@ +# This file is meant to be imported, not ran directly. + +import "stdlib/io.jou" +import "../import_cycle.jou" + +def b(x: int) -> None: + printf("b %d\n", x) + if x > 0: + a(x-1) diff --git a/tests/other_errors/imported/imported.jou b/tests/other_errors/imported/imported.jou index 332d8231..846baf44 100644 --- a/tests/other_errors/imported/imported.jou +++ b/tests/other_errors/imported/imported.jou @@ -1,10 +1,10 @@ -# This file is meant to be imported, not ran directly. - -import "stdlib/io.jou" - -def add(a: int, b: int) -> int: - return a + b - -def main() -> int: - printf("%d", add(1, 2)) - return 0 +# This file is meant to be imported, not ran directly. + +import "stdlib/io.jou" + +def add(a: int, b: int) -> int: + return a + b + +def main() -> int: + printf("%d", add(1, 2)) + return 0 From 5370732546ed34b78eefa6dd7b57c007ae987930 Mon Sep 17 00:00:00 2001 From: littlewhitecloud Date: Sat, 13 Jul 2024 14:28:07 +0000 Subject: [PATCH 21/26] Change files to use LF line endings --- tests/other_errors/imported/imported.jou | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/other_errors/imported/imported.jou b/tests/other_errors/imported/imported.jou index 846baf44..332d8231 100644 --- a/tests/other_errors/imported/imported.jou +++ b/tests/other_errors/imported/imported.jou @@ -1,10 +1,10 @@ -# This file is meant to be imported, not ran directly. - -import "stdlib/io.jou" - -def add(a: int, b: int) -> int: - return a + b - -def main() -> int: - printf("%d", add(1, 2)) - return 0 +# This file is meant to be imported, not ran directly. + +import "stdlib/io.jou" + +def add(a: int, b: int) -> int: + return a + b + +def main() -> int: + printf("%d", add(1, 2)) + return 0 From 0e3b24c5e2460ad3d49849df22cfc4b803d661cb Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 18 Aug 2024 00:49:11 +0300 Subject: [PATCH 22/26] New implementation that passes existing tests --- src/codegen.c | 21 +------------------ src/jou_compiler.h | 2 +- src/main.c | 52 ++++++++++++++++++++++++++-------------------- 3 files changed, 32 insertions(+), 43 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 8fe8c1b1..364e77eb 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -497,10 +497,8 @@ static void codegen_function_or_method_def(struct State *st, const CfGraph *cfg) free(st->llvm_locals); } -LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft, bool checkmain) +LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft) { - bool mainflag = false; - struct State st = { .module = LLVMModuleCreateWithName(cfgfile->filename), .builder = LLVMCreateBuilder(), @@ -516,23 +514,6 @@ LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft, bool chec LLVMSetInitializer(globalptr, LLVMConstNull(t)); } - for (CfGraph **g = cfgfile->graphs.ptr; g < End(cfgfile->graphs); g++) - if (strcmp((*g)->signature.name, "main") == 0) { - mainflag = true; - break; - } - - - if (checkmain && mainflag == false) - { - struct Location l = { - .filename = cfgfile->filename, - .lineno = 0, - }; - // check main function for the file - fail(l, "missing `main` function to execute the program"); - } - for (CfGraph **g = cfgfile->graphs.ptr; g < End(cfgfile->graphs); g++) codegen_function_or_method_def(&st, *g); diff --git a/src/jou_compiler.h b/src/jou_compiler.h index cc990c22..c505e4a4 100644 --- a/src/jou_compiler.h +++ b/src/jou_compiler.h @@ -628,7 +628,7 @@ AstFile parse(const Token *tokens, const char *stdlib_path); // Type checking happens between parsing and building CFGs. CfGraphFile build_control_flow_graphs(const AstFile *ast, FileTypes *ft); void simplify_control_flow_graphs(const CfGraphFile *cfgfile); -LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft, bool checkmain); +LLVMModuleRef codegen(const CfGraphFile *cfgfile, const FileTypes *ft); char *compile_to_object_file(LLVMModuleRef module); char *get_default_exe_path(void); void run_linker(const char *const *objpaths, const char *exepath); diff --git a/src/main.c b/src/main.c index 77988796..8eca622d 100644 --- a/src/main.c +++ b/src/main.c @@ -243,7 +243,7 @@ static void parse_all_pending_files(struct CompileState *compst) free(compst->parse_queue.ptr); } -static char *compile_ast_to_object_file(struct FileState *fs, bool checkmain) +static char *compile_ast_to_object_file(struct FileState *fs) { if (command_line_args.verbosity >= 1) printf("Building Control Flow Graphs: %s\n", fs->path); @@ -265,7 +265,7 @@ static char *compile_ast_to_object_file(struct FileState *fs, bool checkmain) if (command_line_args.verbosity >= 1) printf("Building LLVM IR: %s\n", fs->path); - LLVMModuleRef mod = codegen(&cfgfile, &fs->types, checkmain); + LLVMModuleRef mod = codegen(&cfgfile, &fs->types); free_control_flow_graphs(&cfgfile); if (command_line_args.verbosity >= 2) @@ -392,14 +392,6 @@ static void add_imported_symbols(struct CompileState *compst) Append(&seen_before, from); for (struct ExportSymbol *es = from->pending_exports; es->name[0]; es++) { - if (strcmp(es->name, "main") == 0) - { - struct Location l = { - .filename = from->path, - .lineno = 0, - }; - fail(l, "imported file should not have `main` function"); - } if (command_line_args.verbosity >= 2) { const char *kindstr; switch(es->kind) { @@ -426,6 +418,30 @@ static void add_imported_symbols(struct CompileState *compst) } } +static const AstStatement *find_main_definition(const AstFile *ast) +{ + for (int i = 0; i < ast->body.nstatements; i++) { + const AstStatement *s = &ast->body.statements[i]; + if (s->kind == AST_STMT_FUNCTION && !strcmp(s->data.function.signature.name, "main")) + return s; + } + return NULL; +} + +static void check_main_definitions(const struct CompileState *compst) +{ + struct FileState *mainfile = find_file(compst, command_line_args.infile); + + for (struct FileState *fs = compst->files.ptr; fs < End(compst->files); fs++) { + const AstStatement *maindef = find_main_definition(&fs->ast); + + if (fs != mainfile && maindef) + fail(maindef->location, "imported file should not have `main` function"); + if (fs == mainfile && !maindef) + fail((Location){.filename=fs->path, .lineno=0}, "missing `main` function to execute the program"); + } +} + static void include_special_stdlib_file(struct CompileState *compst, const char *filename) { char *path = malloc(strlen(compst->stdlib_path) + strlen(filename) + 123); @@ -447,8 +463,7 @@ int main(int argc, char **argv) printf("Data layout: %s\n", get_target()->data_layout); } - if (command_line_args.tokenize_only || command_line_args.parse_only) - { + if (command_line_args.tokenize_only || command_line_args.parse_only) { FILE *f = open_the_file(command_line_args.infile, NULL); Token *tokens = tokenize(f, command_line_args.infile); fclose(f); @@ -499,16 +514,9 @@ int main(int argc, char **argv) char **objpaths = calloc(sizeof objpaths[0], compst.files.len + 1); for (struct FileState *fs = compst.files.ptr; fs < End(compst.files); fs++) - { - if (strcmp(command_line_args.infile, fs->path) == 0) - { - objpaths[fs - compst.files.ptr] = compile_ast_to_object_file(fs, true); - } - else - { - objpaths[fs - compst.files.ptr] = compile_ast_to_object_file(fs, false); - } - } + objpaths[fs - compst.files.ptr] = compile_ast_to_object_file(fs); + + check_main_definitions(&compst); for (struct FileState *fs = compst.files.ptr; fs < End(compst.files); fs++) { free_ast(&fs->ast); From f9dcd7ce6b862fc5d724fc64aed6c7797bd66f73 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 18 Aug 2024 00:52:49 +0300 Subject: [PATCH 23/26] Revert test file rename --- .../import_cycle.jou | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) rename tests/{other_errors => should_succeed}/import_cycle.jou (52%) diff --git a/tests/other_errors/import_cycle.jou b/tests/should_succeed/import_cycle.jou similarity index 52% rename from tests/other_errors/import_cycle.jou rename to tests/should_succeed/import_cycle.jou index ba369ae6..88ca31b6 100644 --- a/tests/other_errors/import_cycle.jou +++ b/tests/should_succeed/import_cycle.jou @@ -6,7 +6,17 @@ def a(x: int) -> None: if x > 0: b(x-1) -# Output: compiler error in file "tests/other_errors/import_cycle.jou": imported file should not have `main` function +# Output: a 10 +# Output: b 9 +# Output: a 8 +# Output: b 7 +# Output: a 6 +# Output: b 5 +# Output: a 4 +# Output: b 3 +# Output: a 2 +# Output: b 1 +# Output: a 0 def main() -> int: a(10) return 0 From ff40f0f8d4cbd6808341a75e4b9f3c2298fd38f6 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 18 Aug 2024 01:41:10 +0300 Subject: [PATCH 24/26] now good? --- src/main.c | 53 ++++++++++--------- tests/other_errors/import_file_with_main.jou | 8 +-- tests/other_errors/imported/imported.jou | 10 ---- .../imported/cycle.jou | 0 4 files changed, 29 insertions(+), 42 deletions(-) delete mode 100644 tests/other_errors/imported/imported.jou rename tests/{other_errors => should_succeed}/imported/cycle.jou (100%) diff --git a/src/main.c b/src/main.c index 8eca622d..23996951 100644 --- a/src/main.c +++ b/src/main.c @@ -196,6 +196,16 @@ static FILE *open_the_file(const char *path, const Location *import_location) return f; } +static bool defines_main(const AstFile *ast) +{ + for (int i = 0; i < ast->body.nstatements; i++) { + const AstStatement *s = &ast->body.statements[i]; + if (s->kind == AST_STMT_FUNCTION && !strcmp(s->data.function.signature.name, "main")) + return true; + } + return false; +} + static void parse_file(struct CompileState *compst, const char *filename, const Location *import_location) { if (find_file(compst, filename)) @@ -224,6 +234,16 @@ static void parse_file(struct CompileState *compst, const char *filename, const if(command_line_args.verbosity >= 2) print_ast(&fs.ast); + // If it's not the file passed on command line, it shouldn't define main() + if (strcmp(filename, command_line_args.infile) && defines_main(&fs.ast)) { + /* + Set error location to import, so user immediately knows which file + imports something that defines main(). + */ + assert(import_location); + fail(*import_location, "imported file should not have `main` function"); + } + for (const AstImport *imp = fs.ast.imports.ptr; imp < End(fs.ast.imports); imp++) { Append(&compst->parse_queue, (struct ParseQueueItem){ .filename = imp->resolved_path, @@ -418,30 +438,6 @@ static void add_imported_symbols(struct CompileState *compst) } } -static const AstStatement *find_main_definition(const AstFile *ast) -{ - for (int i = 0; i < ast->body.nstatements; i++) { - const AstStatement *s = &ast->body.statements[i]; - if (s->kind == AST_STMT_FUNCTION && !strcmp(s->data.function.signature.name, "main")) - return s; - } - return NULL; -} - -static void check_main_definitions(const struct CompileState *compst) -{ - struct FileState *mainfile = find_file(compst, command_line_args.infile); - - for (struct FileState *fs = compst->files.ptr; fs < End(compst->files); fs++) { - const AstStatement *maindef = find_main_definition(&fs->ast); - - if (fs != mainfile && maindef) - fail(maindef->location, "imported file should not have `main` function"); - if (fs == mainfile && !maindef) - fail((Location){.filename=fs->path, .lineno=0}, "missing `main` function to execute the program"); - } -} - static void include_special_stdlib_file(struct CompileState *compst, const char *filename) { char *path = malloc(strlen(compst->stdlib_path) + strlen(filename) + 123); @@ -516,7 +512,14 @@ int main(int argc, char **argv) for (struct FileState *fs = compst.files.ptr; fs < End(compst.files); fs++) objpaths[fs - compst.files.ptr] = compile_ast_to_object_file(fs); - check_main_definitions(&compst); + /* + Check for missing main() as late as possible, so that other errors come first. + This way Jou users can work on other functions before main() function is written. + */ + struct FileState *mainfile = find_file(&compst, command_line_args.infile); + assert(mainfile); + if (!defines_main(&mainfile->ast)) + fail((Location){.filename=mainfile->path, .lineno=0}, "missing `main` function to execute the program"); for (struct FileState *fs = compst.files.ptr; fs < End(compst.files); fs++) { free_ast(&fs->ast); diff --git a/tests/other_errors/import_file_with_main.jou b/tests/other_errors/import_file_with_main.jou index 687dd656..4fe9630e 100644 --- a/tests/other_errors/import_file_with_main.jou +++ b/tests/other_errors/import_file_with_main.jou @@ -1,7 +1 @@ -import "./imported/imported.jou" -import "stdlib/io.jou" - -def main() -> int: # Output: compiler error in file "tests/other_errors/imported/imported.jou": imported file should not have `main` function - printf("%d", add(114, 514)) - - return 0 +import "../../examples/hello.jou" # Error: imported file should not have `main` function diff --git a/tests/other_errors/imported/imported.jou b/tests/other_errors/imported/imported.jou deleted file mode 100644 index 332d8231..00000000 --- a/tests/other_errors/imported/imported.jou +++ /dev/null @@ -1,10 +0,0 @@ -# This file is meant to be imported, not ran directly. - -import "stdlib/io.jou" - -def add(a: int, b: int) -> int: - return a + b - -def main() -> int: - printf("%d", add(1, 2)) - return 0 diff --git a/tests/other_errors/imported/cycle.jou b/tests/should_succeed/imported/cycle.jou similarity index 100% rename from tests/other_errors/imported/cycle.jou rename to tests/should_succeed/imported/cycle.jou From d05da703e069f75730ec8d852ce83ff6fae19e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:45:34 +0800 Subject: [PATCH 25/26] revert and tmp --- self_hosted/create_llvm_ir.jou | 9 +-------- self_hosted/main.jou | 32 ++++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/self_hosted/create_llvm_ir.jou b/self_hosted/create_llvm_ir.jou index 764a94ee..ddd0d4ff 100644 --- a/self_hosted/create_llvm_ir.jou +++ b/self_hosted/create_llvm_ir.jou @@ -858,7 +858,7 @@ def file_defines_global_var(ast: AstFile*, name: byte*) -> bool: return False -def create_llvm_ir(ast: AstFile*, ft: FileTypes*, checkmain: bool) -> LLVMModule*: +def create_llvm_ir(ast: AstFile*, ft: FileTypes*) -> LLVMModule*: module = LLVMModuleCreateWithName(ast->path) LLVMSetTarget(module, target.triple) LLVMSetDataLayout(module, target.data_layout) @@ -874,12 +874,9 @@ def create_llvm_ir(ast: AstFile*, ft: FileTypes*, checkmain: bool) -> LLVMModule builder = LLVMCreateBuilder(), file_types = ft } - mainflag: bool = False for s = ast->body.statements; s < &ast->body.statements[ast->body.nstatements]; s++: if s->kind == AstStatementKind::Function and s->function.body.nstatements > 0: - if strcmp((&s->function.signature)->name, "main") == 0: - mainflag = True a2i.define_function_or_method(&s->function, NULL) elif s->kind == AstStatementKind::Class: classdef = &s->classdef @@ -892,9 +889,5 @@ def create_llvm_ir(ast: AstFile*, ft: FileTypes*, checkmain: bool) -> LLVMModule # TODO: need to handle some others? pass - if not mainflag and checkmain: - l: Location = Location{path = ast->path, lineno = 0} - fail(l, "missing `main` function to execute the program") - LLVMDisposeBuilder(a2i.builder) return module diff --git a/self_hosted/main.jou b/self_hosted/main.jou index b9aabc9d..8485fe60 100644 --- a/self_hosted/main.jou +++ b/self_hosted/main.jou @@ -90,6 +90,10 @@ def parse_args(argc: int, argv: byte**) -> CommandLineArgs: return result +def find_file(files: FileState*, nfiles: int, path: byte*) -> FileState: + for i = 0; i < nfiles; i++: + if strcmp(files[i].ast.path, path) == 0: + return files[i] # C:\Users\myname\.foo-bar.jou --> "_foo_bar" # Result never contains "-", so you can add "-" separated suffixes without conflicts. @@ -117,6 +121,14 @@ def get_sane_filename(path: byte*) -> byte[50]: name[i] = '_' return name + +def check_main_function(ast: AstFile*) -> bool: + for i = 0; i < ast->body.nstatements; i++: + s = &ast->body.statements[i] + if (s->kind == AstStatementKind::Function and strcmp(s->function.signature.name, "main") == 0): + return True + return False + def check_ast_and_import_conflicts(ast: AstFile*, symbol: ExportSymbol*) -> None: for i = 0; i < ast->body.nstatements; i++: ts = &ast->body.statements[i] @@ -210,6 +222,10 @@ class Compiler: evaluate_compile_time_if_statements_in_body(&ast.body) + if (strcmp(item.path, self->args->main_path) == 0 and check_main_function(&self->files->ast)): + assert item.import_location.path != NULL + fail(item.import_location, "imported file should not have `main` function") + self->files = realloc(self->files, sizeof self->files[0] * (self->nfiles + 1)) self->files[self->nfiles++] = FileState{ast = ast} @@ -258,9 +274,6 @@ class Compiler: " %s: imported in %s, exported in %s\n", exp->name, src->ast.path, dest->ast.path, ) - if strcmp(exp->name, "main") == 0: - l: Location = Location{path=src->ast.path, lineno = 0} - fail(l, "imported file should not have `main` function") check_ast_and_import_conflicts(&dest->ast, exp) dest->typectx.add_imported_symbol(exp) @@ -350,14 +363,10 @@ class Compiler: paths = self->get_object_file_paths() for i = 0; i < self->nfiles; i++: - checkmain: bool = False if self->verbosity >= 1: printf("Build LLVM IR: %s\n", self->files[i].ast.path) - if strcmp(self->args->main_path, self->files[i].ast.path) == 0: - checkmain = True - - module = create_llvm_ir(&self->files[i].ast, &self->files[i].typectx, checkmain) + module = create_llvm_ir(&self->files[i].ast, &self->files[i].typectx) if self->verbosity >= 2: # Don't want to use LLVMDumpModule() because it dumps to stdout. # When redirected, stdout and stderr tend to get mixed up into a weird order. @@ -474,6 +483,13 @@ def main(argc: int, argv: byte**) -> int: compiler.process_imports_and_exports() compiler.typecheck_stage3_all_files() + mainfile = find_file(compiler.files, compiler.nfiles, args.main_path) + assert mainfile + + if (not check_main_function(&mainfile.ast)): + l = Location{path=mainfile->path, lineno=0} + fail(l, "missing `main` function to execute the program") + object_files = compiler.create_object_files() executable = compiler.link(object_files) for i = 0; object_files[i] != NULL; i++: From 5a9779b143f30b113c0eadc949d9473497776e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD=E4=BA=91?= <71159641+littlewhitecloud@users.noreply.github.com> Date: Wed, 21 Aug 2024 20:05:02 +0800 Subject: [PATCH 26/26] fix and update --- self_hosted/main.jou | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/self_hosted/main.jou b/self_hosted/main.jou index 8485fe60..75932da6 100644 --- a/self_hosted/main.jou +++ b/self_hosted/main.jou @@ -90,10 +90,11 @@ def parse_args(argc: int, argv: byte**) -> CommandLineArgs: return result -def find_file(files: FileState*, nfiles: int, path: byte*) -> FileState: +def find_file(files: FileState*, nfiles: int, path: byte*) -> FileState*: for i = 0; i < nfiles; i++: if strcmp(files[i].ast.path, path) == 0: - return files[i] + return &files[i] + return NULL # C:\Users\myname\.foo-bar.jou --> "_foo_bar" # Result never contains "-", so you can add "-" separated suffixes without conflicts. @@ -125,7 +126,7 @@ def get_sane_filename(path: byte*) -> byte[50]: def check_main_function(ast: AstFile*) -> bool: for i = 0; i < ast->body.nstatements; i++: s = &ast->body.statements[i] - if (s->kind == AstStatementKind::Function and strcmp(s->function.signature.name, "main") == 0): + if s->kind == AstStatementKind::Function and strcmp(s->function.signature.name, "main") == 0: return True return False @@ -222,7 +223,7 @@ class Compiler: evaluate_compile_time_if_statements_in_body(&ast.body) - if (strcmp(item.path, self->args->main_path) == 0 and check_main_function(&self->files->ast)): + if item.is_imported and check_main_function(&ast): assert item.import_location.path != NULL fail(item.import_location, "imported file should not have `main` function") @@ -484,10 +485,10 @@ def main(argc: int, argv: byte**) -> int: compiler.typecheck_stage3_all_files() mainfile = find_file(compiler.files, compiler.nfiles, args.main_path) - assert mainfile + assert mainfile != NULL - if (not check_main_function(&mainfile.ast)): - l = Location{path=mainfile->path, lineno=0} + if not check_main_function(&mainfile->ast): + l = Location{path=mainfile->ast.path, lineno=0} fail(l, "missing `main` function to execute the program") object_files = compiler.create_object_files()