From 41d111fa5f5cf39173778602364639d31886d899 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Mon, 9 Mar 2026 20:44:40 +0100 Subject: Parse module declarations --- oryxc/src/lexer.rs | 2 ++ oryxc/src/parser.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/oryxc/src/lexer.rs b/oryxc/src/lexer.rs index 09e2881..2f82e47 100644 --- a/oryxc/src/lexer.rs +++ b/oryxc/src/lexer.rs @@ -56,6 +56,7 @@ pub enum TokenType { Identifier, KeywordDef, KeywordFunc, + KeywordModule, KeywordReturn, Number, Percent2, @@ -123,6 +124,7 @@ impl<'a> LexerContext<'a> { static KEYWORDS: phf::Map<&'static str, TokenType> = phf::phf_map! { "def" => TokenType::KeywordDef, "func" => TokenType::KeywordFunc, + "module" => TokenType::KeywordModule, "return" => TokenType::KeywordReturn, }; diff --git a/oryxc/src/parser.rs b/oryxc/src/parser.rs index 89e2769..52c2a34 100644 --- a/oryxc/src/parser.rs +++ b/oryxc/src/parser.rs @@ -34,6 +34,7 @@ pub enum AstType { Root, /* (extra-data, extra-data-len) */ String, /* (_, _) */ UnaryOperator, /* (rhs, _) */ + ModuleDecl, /* (ident, _) */ } #[derive(Soars)] @@ -163,6 +164,7 @@ impl<'a> Parser<'a> { AstType::FunProto => node, AstType::Function => node, AstType::Identifier => node, + AstType::ModuleDecl => node, AstType::MultiDefBind => node, AstType::Number => node, AstType::Pointer => node, @@ -227,6 +229,9 @@ impl<'a> Parser<'a> { self.node_leaf_r(self.ast.sub()[node as usize].1) }, AstType::Identifier => node, + AstType::ModuleDecl => { + self.node_leaf_r(self.ast.sub()[node as usize].0) + }, AstType::MultiDefBind => { let i = self.ast.sub()[node as usize].1; let len = self.extra_data[i as usize]; @@ -881,12 +886,48 @@ impl<'a> Parser<'a> { return Ok(lhs); } + + fn parse_module_decl(&mut self) -> bool { + let tok = self.cursor; /* Always 0 */ + if self.get() != TokenType::KeywordModule { + self.new_error(OryxError::new( + self.get_view(), + "file must begin with a module declaration", + )); + return false; + } + if self.next() != TokenType::Identifier { + self.new_error(OryxError::new( + self.get_view(), + format!("expected module name but got {:?}", self.get()), + )); + return true; + } + let ident = self.cursor; + if self.next() != TokenType::Semicolon { + self.new_error(OryxError::new( + self.get_view(), + "expected semicolon", + )); + return true; + } + self.next(); /* Consume ‘;’ */ + self.new_node(AstNode { + kind: AstType::ModuleDecl, + tok, + sub: SubNodes(ident, u32::MAX), + }); + return false; + } } pub fn parse( tokens: &Soa, ) -> Result<(Soa, Vec), Vec> { let mut p = Parser::new(tokens); + if p.parse_module_decl() { + p.sync(&[TokenType::Eof, TokenType::KeywordDef]); + } while p.get() != TokenType::Eof { p.parse_toplevel(); } -- cgit v1.2.3