diff options
| -rw-r--r-- | oryxc/src/lexer.rs | 2 | ||||
| -rw-r--r-- | oryxc/src/parser.rs | 41 |
2 files changed, 43 insertions, 0 deletions
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<Token>, ) -> Result<(Soa<AstNode>, Vec<u32>), Vec<OryxError>> { 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(); } |