feat: add modules support, add name mangling

This commit is contained in:
Edgar 2024-02-28 08:54:26 +01:00
parent 478cdca055
commit 54f148b4ef
No known key found for this signature in database
GPG key ID: 70ADAE8F35904387
7 changed files with 37 additions and 16 deletions

View file

@ -221,7 +221,7 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) {
}; };
let fn_value = ctx.module.add_function( let fn_value = ctx.module.add_function(
&body.name, &body.get_mangled_name(),
fn_type, fn_type,
Some(if body.is_extern { Some(if body.is_extern {
inkwell::module::Linkage::AvailableExternally inkwell::module::Linkage::AvailableExternally
@ -256,7 +256,7 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) {
let subprogram = ctx.di_builder.create_function( let subprogram = ctx.di_builder.create_function(
ctx.di_namespace, ctx.di_namespace,
&body.name, &body.name,
Some(&body.name), Some(&body.get_mangled_name()),
ctx.di_unit.get_file(), ctx.di_unit.get_file(),
line as u32 + 1, line as u32 + 1,
di_type, di_type,
@ -273,7 +273,7 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
let body = ctx.ctx.program.functions.get(&fn_id).unwrap(); let body = ctx.ctx.program.functions.get(&fn_id).unwrap();
trace!("compiling fn body: {}", body.name); trace!("compiling fn body: {}", body.name);
let fn_value = ctx.module.get_function(&body.name).unwrap(); let fn_value = ctx.module.get_function(&body.get_mangled_name()).unwrap();
let di_program = fn_value.get_subprogram().unwrap(); let di_program = fn_value.get_subprogram().unwrap();
let mut debug_loc = ctx.set_debug_loc(di_program.as_debug_info_scope(), body.fn_span); let mut debug_loc = ctx.set_debug_loc(di_program.as_debug_info_scope(), body.fn_span);
@ -528,7 +528,10 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
target, target,
} => { } => {
let target_fn_body = ctx.ctx.program.functions.get(func).unwrap(); let target_fn_body = ctx.ctx.program.functions.get(func).unwrap();
let fn_value = ctx.module.get_function(&target_fn_body.name).unwrap(); let fn_value = ctx
.module
.get_function(&target_fn_body.get_mangled_name())
.unwrap();
let args: Vec<_> = args let args: Vec<_> = args
.iter() .iter()
.map(|x| compile_rvalue(ctx, fn_id, &locals, x).unwrap().0.into()) .map(|x| compile_rvalue(ctx, fn_id, &locals, x).unwrap().0.into())

View file

@ -55,10 +55,10 @@ pub fn main() -> Result<(), Box<dyn Error>> {
let path = args.input.display().to_string(); let path = args.input.display().to_string();
let source = std::fs::read_to_string(&args.input)?; let source = std::fs::read_to_string(&args.input)?;
let module = edlang_parser::parse_ast(&source); let modules = edlang_parser::parse_ast(&source);
let module = match module { let modules = match modules {
Ok(module) => module, Ok(modules) => modules,
Err(error) => { Err(error) => {
let report = edlang_parser::error_to_report(&path, &error)?; let report = edlang_parser::error_to_report(&path, &error)?;
edlang_parser::print_report(&path, &source, report)?; edlang_parser::print_report(&path, &source, report)?;
@ -121,11 +121,11 @@ pub fn main() -> Result<(), Box<dyn Error>> {
tracing::debug!("Debug Info: {:#?}", session.debug_info); tracing::debug!("Debug Info: {:#?}", session.debug_info);
if args.ast { if args.ast {
println!("{:#?}", module); println!("{:#?}", modules);
return Ok(()); return Ok(());
} }
let program_ir = match lower_modules(&[module.clone()]) { let program_ir = match lower_modules(&modules) {
Ok(ir) => ir, Ok(ir) => ir,
Err(error) => { Err(error) => {
let report = edlang_check::lowering_error_to_report(error, &session); let report = edlang_check::lowering_error_to_report(error, &session);

View file

@ -34,7 +34,7 @@ pub fn compile_program(
name: &str, name: &str,
library: bool, library: bool,
) -> Result<CompileResult, Box<dyn std::error::Error>> { ) -> Result<CompileResult, Box<dyn std::error::Error>> {
let module = edlang_parser::parse_ast(source).unwrap(); let modules = edlang_parser::parse_ast(source).unwrap();
let test_dir = tempfile::tempdir()?; let test_dir = tempfile::tempdir()?;
let test_dir_path = test_dir.path(); let test_dir_path = test_dir.path();
@ -63,7 +63,7 @@ pub fn compile_program(
output_asm: false, output_asm: false,
}; };
let program_ir = lower_modules(&[module])?; let program_ir = lower_modules(&modules)?;
let object_path = edlang_codegen_llvm::compile(&session, &program_ir)?; let object_path = edlang_codegen_llvm::compile(&session, &program_ir)?;

View file

@ -89,6 +89,17 @@ impl Body {
pub fn get_return_local(&self) -> Local { pub fn get_return_local(&self) -> Local {
self.locals[0].clone() self.locals[0].clone()
} }
pub fn get_mangled_name(&self) -> String {
if self.name == "main" {
"main".to_string()
} else {
format!(
"{}@{}@{}",
self.name, self.def_id.program_id, self.def_id.id
)
}
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -58,11 +58,10 @@ fn lower_module(
} }
} }
let body = ctx.body.modules.get(&id).unwrap();
// fill fn sigs // fill fn sigs
for content in &module.contents { for content in &module.contents {
if let ModuleStatement::Function(fn_def) = content { if let ModuleStatement::Function(fn_def) = content {
let body = ctx.body.modules.get(&id).unwrap();
let fn_id = *body.symbols.functions.get(&fn_def.name.name).unwrap(); let fn_id = *body.symbols.functions.get(&fn_def.name.name).unwrap();
let mut args = Vec::new(); let mut args = Vec::new();
@ -92,7 +91,11 @@ fn lower_module(
ctx = lower_function(ctx, fn_def, id)?; ctx = lower_function(ctx, fn_def, id)?;
} }
// ModuleStatement::Type(_) => todo!(), // ModuleStatement::Type(_) => todo!(),
ModuleStatement::Module(_mod_def) => {} ModuleStatement::Module(mod_def) => {
let body = ctx.body.modules.get(&id).unwrap();
let id = *body.symbols.modules.get(&mod_def.name.name).unwrap();
ctx = lower_module(ctx, mod_def, id)?;
}
_ => {} _ => {}
} }
} }

View file

@ -466,6 +466,10 @@ pub(crate) Import: ast::Import = {
} }
} }
pub Modules: Vec<ast::Module> = {
<Module+> => <>
}
pub Module: ast::Module = { pub Module: ast::Module = {
<lo:@L> "mod" <name:Ident> "{" <imports:List<Import>?> <contents:List<ModuleStatement>> "}" <hi:@R> => ast::Module { <lo:@L> "mod" <name:Ident> "{" <imports:List<Import>?> <contents:List<ModuleStatement>> "}" <hi:@R> => ast::Module {
name, name,

View file

@ -22,9 +22,9 @@ pub mod grammar {
pub fn parse_ast( pub fn parse_ast(
source: &str, source: &str,
) -> Result<edlang_ast::Module, ParseError<usize, Token, LexicalError>> { ) -> Result<Vec<edlang_ast::Module>, ParseError<usize, Token, LexicalError>> {
let lexer = Lexer::new(source); let lexer = Lexer::new(source);
let parser = grammar::ModuleParser::new(); let parser = grammar::ModulesParser::new();
parser.parse(lexer) parser.parse(lexer)
} }