diff --git a/src/ast/function/mod.rs b/src/ast/function/mod.rs index 97416816..8dd94ca4 100644 --- a/src/ast/function/mod.rs +++ b/src/ast/function/mod.rs @@ -14,4 +14,5 @@ pub struct Function { pub source: Source, pub abide_abi: bool, pub tag: Option, + pub namespace: Option, } diff --git a/src/c/translation/function.rs b/src/c/translation/function.rs index 195271c4..da5113d7 100644 --- a/src/c/translation/function.rs +++ b/src/c/translation/function.rs @@ -80,6 +80,7 @@ pub fn declare_function( source, abide_abi: true, tag: None, + namespace: None, }); Ok(()) diff --git a/src/interpreter_env/mod.rs b/src/interpreter_env/mod.rs index 9c1478f6..ba02aef8 100644 --- a/src/interpreter_env/mod.rs +++ b/src/interpreter_env/mod.rs @@ -47,6 +47,7 @@ fn thin_cstring_function( is_foreign: false, source, tag: None, + namespace: None, } } @@ -73,6 +74,7 @@ pub fn setup_build_system_interpreter_symbols(file: &mut AstFile) { source, abide_abi: false, tag: Some(Tag::InterpreterEntryPoint), + namespace: None, }); file.enums.insert( @@ -182,6 +184,7 @@ pub fn setup_build_system_interpreter_symbols(file: &mut AstFile) { is_foreign: false, source, tag: None, + namespace: None, }); } diff --git a/src/lower/mod.rs b/src/lower/mod.rs index ad844d0e..f8b6cd2c 100644 --- a/src/lower/mod.rs +++ b/src/lower/mod.rs @@ -161,7 +161,7 @@ fn lower_function( } else { return Err(LowerErrorKind::MustReturnValueOfTypeBeforeExitingFunction { return_type: function.return_type.to_string(), - function: function.name.clone(), + function: function.name.to_string(), } .at(function.source)); } @@ -189,10 +189,19 @@ fn lower_function( } } + eprintln!("warning: name mangling does not take all cases into account yet"); + let mangled_name = if function.name.plain() == "main" { + "main".into() + } else if function.is_foreign { + function.name.plain().to_string() + } else { + function.name.to_string() + }; + ir_module.functions.insert( function_ref, ir::Function { - mangled_name: function.name.clone(), + mangled_name, basicblocks, parameters, return_type, diff --git a/src/name.rs b/src/name.rs index f2bdb589..ab65c256 100644 --- a/src/name.rs +++ b/src/name.rs @@ -42,3 +42,21 @@ pub enum ResolvedName { Remote(Box), Project(Box), } + +impl ResolvedName { + pub fn plain(&self) -> &str { + match self { + ResolvedName::Remote(name) => &**name, + ResolvedName::Project(name) => &**name, + } + } +} + +impl Display for ResolvedName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ResolvedName::Remote(name) => write!(f, "/{}", name), + ResolvedName::Project(name) => write!(f, "/{}", name), + } + } +} diff --git a/src/parser/parse_function.rs b/src/parser/parse_function.rs index 2685e715..89163671 100644 --- a/src/parser/parse_function.rs +++ b/src/parser/parse_function.rs @@ -16,11 +16,13 @@ impl<'a, I: Inflow> Parser<'a, I> { let mut is_foreign = false; let mut abide_abi = false; + let mut namespace = None; for annotation in annotations { match annotation.kind { AnnotationKind::Foreign => is_foreign = true, AnnotationKind::AbideAbi => abide_abi = true, + AnnotationKind::Namespace(new_namespace) => namespace = Some(new_namespace), _ => return Err(self.unexpected_annotation(&annotation, Some("for function"))), } } @@ -63,6 +65,7 @@ impl<'a, I: Inflow> Parser<'a, I> { source, abide_abi, tag: None, + namespace, }) } } diff --git a/src/pragma_section/parse.rs b/src/pragma_section/parse.rs index 82a1b669..7c6f0545 100644 --- a/src/pragma_section/parse.rs +++ b/src/pragma_section/parse.rs @@ -90,6 +90,7 @@ impl PragmaSection { source, abide_abi: false, tag: None, + namespace: None, }); } else { return Err(Box::new(ParseError::expected( diff --git a/src/resolve/expr/call.rs b/src/resolve/expr/call.rs index ff23acc3..f4a3c85b 100644 --- a/src/resolve/expr/call.rs +++ b/src/resolve/expr/call.rs @@ -46,7 +46,7 @@ pub fn resolve_call_expr( if resolved_required_ty != return_type { return Err(ResolveErrorKind::FunctionMustReturnType { of: required_ty.to_string(), - function_name: function.name.clone(), + function_name: function.name.to_string(), } .at(function.return_type.source)); } @@ -93,7 +93,7 @@ pub fn resolve_call_expr( return Err(ResolveErrorKind::BadTypeForArgumentToFunction { expected: preferred_type.to_string(), got: argument.resolved_type.to_string(), - name: function.name.clone(), + name: function.name.to_string(), i, } .at(source)); diff --git a/src/resolve/mod.rs b/src/resolve/mod.rs index 9179490c..b2969b73 100644 --- a/src/resolve/mod.rs +++ b/src/resolve/mod.rs @@ -245,8 +245,14 @@ pub fn resolve<'a>( let type_search_ctx = ctx.type_search_ctxs.get_mut(&file_id).unwrap(); for (function_i, function) in file.functions.iter().enumerate() { + let name = if let Some(namespace) = function.namespace.as_ref() { + ResolvedName::Project(format!("{}/{}", namespace, function.name).into_boxed_str()) + } else { + ResolvedName::Project(function.name.clone().into_boxed_str()) + }; + let function_ref = resolved_ast.functions.insert(resolved::Function { - name: function.name.clone(), + name, parameters: resolve_parameters( type_search_ctx, source_files, diff --git a/src/resolved/mod.rs b/src/resolved/mod.rs index 42fb0439..083d8183 100644 --- a/src/resolved/mod.rs +++ b/src/resolved/mod.rs @@ -8,6 +8,7 @@ pub use crate::ast::{ use crate::{ ast::fmt_c_integer, ir::InterpreterSyscallKind, + name::ResolvedName, source_files::{Source, SourceFiles}, tag::Tag, target::Target, @@ -70,7 +71,7 @@ pub struct GlobalVar { #[derive(Clone, Debug)] pub struct Function { - pub name: String, + pub name: ResolvedName, pub parameters: Parameters, pub return_type: Type, pub stmts: Vec,