From 735c4370aa446eb40222d392459d4cbe83fd838c Mon Sep 17 00:00:00 2001 From: sofia Date: Mon, 14 Jul 2025 18:47:02 +0300 Subject: [PATCH] Add pub keyword --- reid-llvm-lib/src/compile.rs | 10 +++++++++- reid-llvm-lib/src/lib.rs | 6 +++++- reid/examples/testcodegen.rs | 2 ++ reid/src/ast/mod.rs | 2 +- reid/src/ast/parse.rs | 12 +++++++++++- reid/src/ast/process.rs | 4 +++- reid/src/codegen.rs | 5 ++++- reid/src/lexer.rs | 3 +++ reid/src/mir/mod.rs | 1 + reid_src/std.reid | 10 ++++++++++ 10 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 reid_src/std.reid diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 1c0e6bd..134fc0a 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -205,9 +205,17 @@ impl FunctionHolder { let own_function = *module.functions.get(&self.value).unwrap(); if self.data.flags.is_extern { - LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMExternalLinkage); + LLVMSetLinkage( + own_function.value_ref, + LLVMLinkage::LLVMAvailableExternallyLinkage, + ); return; } + if self.data.flags.is_pub { + LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMCommonLinkage); + } else { + LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMPrivateLinkage); + } for block in &self.blocks { if block.data.deleted { diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 819f93b..a4eb318 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -89,11 +89,15 @@ pub struct FunctionData { #[derive(Debug, Clone, Copy, Hash)] pub struct FunctionFlags { pub is_extern: bool, + pub is_pub: bool, } impl Default for FunctionFlags { fn default() -> FunctionFlags { - FunctionFlags { is_extern: false } + FunctionFlags { + is_extern: false, + is_pub: false, + } } } diff --git a/reid/examples/testcodegen.rs b/reid/examples/testcodegen.rs index dc31b03..9e7aa60 100644 --- a/reid/examples/testcodegen.rs +++ b/reid/examples/testcodegen.rs @@ -7,6 +7,7 @@ fn main() { let fibonacci = FunctionDefinition { name: fibonacci_name.clone(), + is_pub: false, return_type: TypeKind::I32, parameters: vec![(fibonacci_n.clone(), TypeKind::I32)], kind: FunctionDefinitionKind::Local( @@ -127,6 +128,7 @@ fn main() { let main = FunctionDefinition { name: "main".to_owned(), + is_pub: false, return_type: TypeKind::I32, parameters: vec![], kind: FunctionDefinitionKind::Local( diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index ab28c46..9c0cea5 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -110,7 +110,7 @@ pub struct LetStatement( pub struct ImportStatement(pub Vec, pub TokenRange); #[derive(Debug)] -pub struct FunctionDefinition(pub FunctionSignature, pub Block, pub TokenRange); +pub struct FunctionDefinition(pub FunctionSignature, pub bool, pub Block, pub TokenRange); #[derive(Debug, Clone)] pub struct FunctionSignature { diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index c861a0e..a7a51e5 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -308,9 +308,17 @@ impl Parse for ImportStatement { impl Parse for FunctionDefinition { fn parse(mut stream: TokenStream) -> Result { + let is_pub = if let Some(Token::PubKeyword) = stream.peek() { + stream.next(); // Consume pub + true + } else { + false + }; + stream.expect(Token::FnKeyword)?; Ok(FunctionDefinition( stream.parse()?, + is_pub, stream.parse()?, stream.get_range().unwrap(), )) @@ -482,7 +490,9 @@ impl Parse for TopLevelStatement { stream.expect(Token::Semi)?; extern_fn } - Some(Token::FnKeyword) => Stmt::FunctionDefinition(stream.parse()?), + Some(Token::FnKeyword) | Some(Token::PubKeyword) => { + Stmt::FunctionDefinition(stream.parse()?) + } _ => Err(stream.expected_err("import or fn")?)?, }) } diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 2745378..af1942e 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -24,9 +24,10 @@ impl ast::Module { imports.push(mir::Import(name.clone(), import.1.into())); } } - FunctionDefinition(ast::FunctionDefinition(signature, block, range)) => { + FunctionDefinition(ast::FunctionDefinition(signature, is_pub, block, range)) => { let def = mir::FunctionDefinition { name: signature.name.clone(), + is_pub: *is_pub, return_type: signature .return_type .clone() @@ -45,6 +46,7 @@ impl ast::Module { ExternFunction(signature) => { let def = mir::FunctionDefinition { name: signature.name.clone(), + is_pub: false, return_type: signature .return_type .clone() diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 53eb947..6b2c770 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -64,7 +64,10 @@ impl mir::Module { &function.name, function.return_type.get_type(), param_types, - FunctionFlags::default(), + FunctionFlags { + is_pub: function.is_pub, + ..FunctionFlags::default() + }, ), mir::FunctionDefinitionKind::Extern => module.function( &function.name, diff --git a/reid/src/lexer.rs b/reid/src/lexer.rs index 3623dad..edd5698 100644 --- a/reid/src/lexer.rs +++ b/reid/src/lexer.rs @@ -22,6 +22,8 @@ pub enum Token { ReturnKeyword, /// `fn` FnKeyword, + /// `pub` + PubKeyword, /// `->` Arrow, /// `if` @@ -208,6 +210,7 @@ pub fn tokenize>(to_tokenize: T) -> Result, Error "true" => Token::True, "false" => Token::False, "extern" => Token::Extern, + "pub" => Token::PubKeyword, _ => Token::Identifier(value), }; variant diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 2fe9e9d..2578145 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -240,6 +240,7 @@ pub struct FunctionCall { #[derive(Debug)] pub struct FunctionDefinition { pub name: String, + pub is_pub: bool, pub return_type: TypeKind, pub parameters: Vec<(String, TypeKind)>, pub kind: FunctionDefinitionKind, diff --git a/reid_src/std.reid b/reid_src/std.reid new file mode 100644 index 0000000..1b69685 --- /dev/null +++ b/reid_src/std.reid @@ -0,0 +1,10 @@ + +extern fn puts(message: string) -> i32; + +pub fn print(message: string) { + puts(message); +} + +fn main() -> u16 { + return 0; +}