Skip to content

Commit

Permalink
complete improved parser
Browse files Browse the repository at this point in the history
  • Loading branch information
edg-l committed Jan 8, 2024
1 parent f438e47 commit 3b4d7a0
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 24 deletions.
10 changes: 2 additions & 8 deletions crates/concrete_ast/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@ use crate::common::Ident;

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct ImportStmt {
module: Vec<Ident>,
symbols: Vec<ImportedSymbol>,
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct ImportedSymbol {
import_name: Ident,
rename_into: Option<Ident>,
pub module: Vec<Ident>,
pub symbols: Vec<Ident>,
}
5 changes: 3 additions & 2 deletions crates/concrete_ast/src/statements.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
common::Ident,
expressions::{Expression, MatchExpr, IfExpr},
operations::{Operation, PathOp},
expressions::{Expression, IfExpr, MatchExpr},
operations::{FnCallOp, Operation, PathOp},
types::TypeSpec,
};

Expand All @@ -14,6 +14,7 @@ pub enum Statement {
Let(LetStmt),
Return(ReturnStmt),
While(WhileStmt),
FnCall(FnCallOp),
}

#[derive(Clone, Debug, PartialEq)]
Expand Down
76 changes: 63 additions & 13 deletions crates/concrete_parser/src/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern {
"mod" => Token::KeywordMod,
"pub" => Token::KeywordPub,
"mut" => Token::KeywordMut,
"import" => Token::KeywordImport,

// literals
"identifier" => Token::Identifier(<String>),
Expand Down Expand Up @@ -66,6 +67,16 @@ extern {

// lalrpop macros

Dot<T>: Vec<T> = {
<mut v:(<T> ".")*> <e:T?> => match e {
None => v,
Some(e) => {
v.push(e);
v
}
}
};

Comma<T>: Vec<T> = {
<mut v:(<T> ",")*> <e:T?> => match e {
None => v,
Expand Down Expand Up @@ -156,16 +167,35 @@ pub Program: ast::Program = {
// Modules

pub(crate) Module: ast::modules::Module = {
"mod" <name:Ident> "{" <contents:ModuleItems> "}" => {
"mod" <name:Ident> "{" <imports:ImportList?> <contents:ModuleItems> "}" => {
ast::modules::Module {
doc_string: None,
imports: vec![], // todo: add imports
imports: imports.unwrap_or_else(|| vec![]),
name,
contents
}
}
}

pub(crate) ImportList: Vec<ast::imports::ImportStmt> = {
<ImportStmt> => vec![<>],
<mut s:ImportList> <n:ImportStmt> => {
s.push(n);
s
},
}


pub(crate) ImportStmt: ast::imports::ImportStmt = {
"import" <module:Dot<Ident>> "{" <symbols:Comma<Ident>> "}" ";" => {
ast::imports::ImportStmt {
module,
symbols,
}
}
}


pub(crate) ModuleItems: Vec<ast::modules::ModuleDefItem> = {
<ModuleDefItem> => vec![<>],
<mut s:ModuleItems> <n:ModuleDefItem> => {
Expand Down Expand Up @@ -213,7 +243,7 @@ pub(crate) Param: ast::functions::Param = {

pub(crate) FunctionDef: ast::functions::FunctionDef = {
<is_pub:"pub"?> "fn" <name:Ident> <generic_params:GenericParams?> "(" <params:Comma<Param>> ")" <ret_type:FunctionRetType?> "{"
<statements:SemiColonSeparated<Statement>>
<statements:StatementList>
"}" => {
ast::functions::FunctionDef {
decl: ast::functions::FunctionDecl {
Expand All @@ -237,8 +267,8 @@ pub(crate) Expression: ast::expressions::Expression = {
}

pub(crate) IfExpr: ast::expressions::IfExpr = {
"if" <value:Operation> "{" <contents:SemiColonSeparated<Statement>> "}"
<else_stmts:("else" "{" <SemiColonSeparated<Statement>> "}")?> => {
"if" <value:Operation> "{" <contents:StatementList> "}"
<else_stmts:("else" "{" <StatementList> "}")?> => {
ast::expressions::IfExpr {
value,
contents,
Expand All @@ -265,7 +295,7 @@ pub(crate) MatchVariant: ast::expressions::MatchVariant = {
}
},
// x -> { ... }
<case:Operation> "->" "{" <stmts:SemiColonSeparated<Statement>> "}" => {
<case:Operation> "->" "{" <stmts:StatementList> "}" => {
ast::expressions::MatchVariant {
case,
block: stmts
Expand All @@ -284,8 +314,9 @@ pub(crate) AtomicOp: ast::operations::AtomicOp = {
<"integer"> => ast::operations::AtomicOp::ConstInt(<>),
<"boolean"> => ast::operations::AtomicOp::ConstBool(<>),
<"string"> => ast::operations::AtomicOp::ConstStr(<>),
<PathOp> =>ast::operations::AtomicOp::Path(<>),
<FnCallOp> =>ast::operations::AtomicOp::FnCall(<>),
<PathOp> => ast::operations::AtomicOp::Path(<>),
<FnCallOp> => ast::operations::AtomicOp::FnCall(<>),
"(" <op:Operation> ")" => ast::operations::AtomicOp::Paren(Box::new(op)),
}

pub(crate) CompoundOp: ast::operations::CompoundOp = {
Expand Down Expand Up @@ -350,12 +381,22 @@ pub(crate) FnCallOp: ast::operations::FnCallOp = {

// -- Statements

pub StatementList: Vec<ast::statements::Statement> = {
<Statement> => vec![<>],
<mut s:StatementList> <n:Statement> => {
s.push(n);
s
},
}

pub(crate) Statement: ast::statements::Statement = {
<MatchExpr> => ast::statements::Statement::Match(<>),
<IfExpr> => ast::statements::Statement::If(<>),
<LetStmt> => ast::statements::Statement::Let(<>),
<AssignStmt> => ast::statements::Statement::Assign(<>),
<ReturnStmt> => ast::statements::Statement::Return(<>),
<MatchExpr> ";"? => ast::statements::Statement::Match(<>),
<IfExpr> ";"? => ast::statements::Statement::If(<>),
<WhileStmt> ";"? => ast::statements::Statement::While(<>),
<LetStmt> ";" => ast::statements::Statement::Let(<>),
<AssignStmt> ";" => ast::statements::Statement::Assign(<>),
<FnCallOp> ";" => ast::statements::Statement::FnCall(<>),
<ReturnStmt> ";"? => ast::statements::Statement::Return(<>),
}

pub(crate) LetStmt: ast::statements::LetStmt = {
Expand All @@ -381,3 +422,12 @@ pub(crate) ReturnStmt: ast::statements::ReturnStmt = {
value,
},
}

pub(crate) WhileStmt: ast::statements::WhileStmt = {
"while" <value:Operation> "{" <contents:StatementList> "}" => {
ast::statements::WhileStmt {
value,
contents,
}
}
}
17 changes: 16 additions & 1 deletion crates/concrete_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ mod tests {
fn parse_simple_program() {
let source = r##"
mod ModuleName {
import Std.io.{print};
const MY_CONSTANT: u8 = 2;
const MY_CONSTANT2: bool = true;
const MY_CONSTANT3: string = "hello world!";
Expand All @@ -91,12 +93,25 @@ mod ModuleName {
let y: u64 = x * 2;
return y * 10;
},
};
}
if x == 2 {
return 0;
}
let lol: u64 = if x == 3 {
return 4;
} else {
return 5;
};
print("hello world\nwith newlines and \" escapes ");
my_func((4 * 2) / 5);
while x > 0 {
x = x - 1;
}
return x;
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/concrete_parser/src/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pub enum Token {
KeywordPub,
#[token("mut")]
KeywordMut,
#[token("import")]
KeywordImport,

// Modern way of allowing identifiers, read: https://unicode.org/reports/tr31/
#[regex(r"[\p{XID_Start}_]\p{XID_Continue}*", |lex| lex.slice().to_string())]
Expand Down

0 comments on commit 3b4d7a0

Please sign in to comment.