From fbf28748c745dfe3a1fe7eaf3757787d7d4f69a1 Mon Sep 17 00:00:00 2001 From: Toni Date: Thu, 18 Dec 2025 16:15:56 +0100 Subject: [PATCH] add export keyword --- src/analyzer.rs | 2 ++ src/codegen_x86_64.rs | 3 ++- src/parser.rs | 10 ++++++++-- src/std.zr | 6 ++++++ src/tokenizer.rs | 2 ++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/analyzer.rs b/src/analyzer.rs index 7dbed93..7dae999 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -22,6 +22,7 @@ impl Analyzer { params, return_type: _, body: _, + exported: _, } = stmt { if self.functions.contains_key(&name.lexeme) { @@ -65,6 +66,7 @@ impl Analyzer { params: _, return_type, body, + exported: _, } => { if name.lexeme == "main" && return_type.lexeme != "I64" { return error!(&name.loc, "main must return I64"); diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 127437a..d92799e 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -232,8 +232,9 @@ _builtin_environ: params, return_type: _, body, + exported, } => { - if name.lexeme == "main" { + if exported || name.lexeme == "main" { emit!(&mut self.output, "global {}", name.lexeme); } emit!(&mut self.output, "section .text.{}", name.lexeme); diff --git a/src/parser.rs b/src/parser.rs index 16f7017..d90ad45 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -35,6 +35,7 @@ pub enum Stmt { params: Vec, return_type: Token, body: Box, + exported: bool, }, Return(Expr), Break, @@ -101,7 +102,11 @@ impl Parser { fn declaration(&mut self) -> Result { if !self.is_inside_function { if self.match_token(&[TokenType::KeywordFunc]) { - return self.func_declaration(); + return self.func_declaration(false); + } + if self.match_token(&[TokenType::KeywordExport]) { + self.consume(TokenType::KeywordFunc, "expected 'func' after 'export'")?; + return self.func_declaration(true); } if self.match_token(&[TokenType::KeywordExtern]) { return self.extern_declaration(); @@ -119,7 +124,7 @@ impl Parser { } } - fn func_declaration(&mut self) -> Result { + fn func_declaration(&mut self, exported: bool) -> Result { let name = self.consume(TokenType::Identifier, "expected function name")?; self.consume(TokenType::LeftBracket, "expected '[' after function name")?; @@ -157,6 +162,7 @@ impl Parser { params, return_type, body, + exported, }) } diff --git a/src/std.zr b/src/std.zr index 9915e2e..ba1bb28 100644 --- a/src/std.zr +++ b/src/std.zr @@ -229,6 +229,12 @@ func str.from_i64[n: I64] : String mem.free(buf) return s +func str.from_char[c: U8] : String + let s: String = mem.alloc(2) + str.set(s, 0, c) + str.set(s, 1, 0) + return s + func str.parse_i64[s: String] : I64 let len: I64 = str.len(s) let i: I64 = 0 diff --git a/src/tokenizer.rs b/src/tokenizer.rs index cdf00d8..f781f37 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -48,6 +48,7 @@ pub enum TokenType { KeywordBreak, KeywordContinue, KeywordExtern, + KeywordExport, Indent, Dedent, @@ -340,6 +341,7 @@ impl Tokenizer { "break" => TokenType::KeywordBreak, "continue" => TokenType::KeywordContinue, "extern" => TokenType::KeywordExtern, + "export" => TokenType::KeywordExport, "true" => TokenType::True, "false" => TokenType::False, _ => TokenType::Identifier,