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] 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