diff --git a/crates/concrete_ast/src/statements.rs b/crates/concrete_ast/src/statements.rs index b3de285..f836281 100644 --- a/crates/concrete_ast/src/statements.rs +++ b/crates/concrete_ast/src/statements.rs @@ -53,10 +53,11 @@ pub struct Binding { #[derive(Clone, Debug, Eq, PartialEq)] pub struct ForStmt { - pub name: Ident, - pub from: Expression, - pub to: Expression, + pub init: Option, + pub condition: Option, + pub post: Option, pub contents: Vec, + pub span: Span, } #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/crates/concrete_parser/src/grammar.lalrpop b/crates/concrete_parser/src/grammar.lalrpop index e3fdd9f..20bad8e 100644 --- a/crates/concrete_parser/src/grammar.lalrpop +++ b/crates/concrete_parser/src/grammar.lalrpop @@ -517,6 +517,7 @@ pub(crate) Statement: ast::statements::Statement = { ";"? => ast::statements::Statement::Match(<>), ";"? => ast::statements::Statement::If(<>), ";"? => ast::statements::Statement::While(<>), + ";"? => ast::statements::Statement::For(<>), ";" => ast::statements::Statement::Let(<>), ";" => ast::statements::Statement::Assign(<>), ";" => ast::statements::Statement::FnCall(<>), @@ -574,3 +575,34 @@ pub(crate) WhileStmt: ast::statements::WhileStmt = { } } } + + +pub(crate) ForStmt: ast::statements::ForStmt = { + "for" "(" ";" ";" ")" "{" "}" => { + ast::statements::ForStmt { + init, + condition, + post, + contents, + span: Span::new(lo, hi) + } + }, + "for" "(" ")" "{" "}" => { + ast::statements::ForStmt { + init: None, + condition: Some(condition), + post: None, + contents, + span: Span::new(lo, hi) + } + }, + "for" "{" "}" => { + ast::statements::ForStmt { + init: None, + condition: None, + post: None, + contents, + span: Span::new(lo, hi) + } + } +} diff --git a/crates/concrete_parser/src/lib.rs b/crates/concrete_parser/src/lib.rs index 2881a4a..c41ed18 100644 --- a/crates/concrete_parser/src/lib.rs +++ b/crates/concrete_parser/src/lib.rs @@ -150,6 +150,75 @@ mod ModuleName { fn parse_empty_fn() { let source = r##"mod MyMod { fn hello() {} +}"##; + let lexer = Lexer::new(source); + let parser = grammar::ProgramParser::new(); + parser.parse(lexer).unwrap(); + } + + #[test] + fn parse_for() { + let source = r##"mod MyMod { + fn hello() { + let mut result: i64 = 0; + + for (let n: usize = 1; n <= limit; n = n + 1) { + result = result + n; + } + + return result; + } +}"##; + let lexer = Lexer::new(source); + let parser = grammar::ProgramParser::new(); + parser.parse(lexer).unwrap(); + } + + #[test] + fn parse_for_while() { + let source = r##"mod MyMod { + fn hello() { + let mut result: i64 = 0; + + let n: i64 = 1; + for (; n <= limit ;) { + result = result + n; + n = n + 1; + } + + n = 1; + for (n <= limit) { + result = result + n; + n = n + 1; + } + + return result; + } +}"##; + let lexer = Lexer::new(source); + let parser = grammar::ProgramParser::new(); + parser.parse(lexer).unwrap(); + } + + #[test] + fn parse_for_loop() { + let source = r##"mod MyMod { + fn hello() { + let mut result: i64 = 0; + + let n: i64 = 1; + for (;;) { + result = result + n; + n = n + 1; + } + + for { + result = result + n; + n = n + 1; + } + + return result; + } }"##; let lexer = Lexer::new(source); let parser = grammar::ProgramParser::new(); diff --git a/examples/for.con b/examples/for.con new file mode 100644 index 0000000..1f2ddd0 --- /dev/null +++ b/examples/for.con @@ -0,0 +1,15 @@ +mod Example { + fn main() -> i64 { + return sum_to(4); + } + + fn sum_to(limit: i64) -> i64 { + let mut result: i64 = 0; + + for (let n: i64 = 1; n <= limit; n = n + 1) { + result = result + n; + } + + return result; + } +} diff --git a/examples/for_loop.con b/examples/for_loop.con new file mode 100644 index 0000000..fb57b29 --- /dev/null +++ b/examples/for_loop.con @@ -0,0 +1,22 @@ +mod Example { + fn main() -> i64 { + return sum_to(4); + } + + fn sum_to(limit: i64) -> i64 { + let mut result: i64 = 0; + + let n: i64 = 1; + for (;;) { + result = result + n; + n = n + 1; + } + + for { + result = result + n; + n = n + 1; + } + + return result; + } +} diff --git a/examples/for_while.con b/examples/for_while.con new file mode 100644 index 0000000..80f9d3e --- /dev/null +++ b/examples/for_while.con @@ -0,0 +1,23 @@ +mod Example { + fn main() -> i64 { + return sum_to(4); + } + + fn sum_to(limit: i64) -> i64 { + let mut result: i64 = 0; + + let n: i64 = 1; + for (; n <= limit ;) { + result = result + n; + n = n + 1; + } + + n = 1; + for (n <= limit) { + result = result + n; + n = n + 1; + } + + return result; + } +}