summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oryxc/src/lexer.rs2
-rw-r--r--oryxc/src/parser.rs41
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();
}