diff --git a/README.md b/README.md index ce3682e..e7f7f36 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ as an argument, prefix the block with `'`. ## Control flow builtins - `cflow.if, cond = ..., then = ..., else = ...` -- `cflow.loop ...` -- `cflow.return ...` (implicit when last expr in a block is not terminated via semicolon) +- `cflow.loop § ...` +- `cflow.return § ...` (implicit when last expr in a block is not terminated via semicolon) ## Modules @@ -61,7 +61,7 @@ with package-lock files or such. Packages (packaged module trees) would then be # 1. final main { args env } = { - std.io.writeln "Hello World!"; + std.io.writeln § "Hello World!"; 0 }; @@ -72,7 +72,7 @@ with package-lock files or such. Packages (packaged module trees) would then be what_now = { self.business_in_the_front; }, self.party_in_the_back { - std.io.writeln "It works"; + std.io.writeln § "It works"; }; # running `what_now` results in "It works" being printed. diff --git a/crates/wafl-parser/src/lex.rs b/crates/wafl-parser/src/lex.rs index 3a2eeaa..801c0f6 100644 --- a/crates/wafl-parser/src/lex.rs +++ b/crates/wafl-parser/src/lex.rs @@ -19,6 +19,7 @@ pub enum Token<'a> { Comma, SemiColon, Dot, + MatchPara, // dynamic stuff /// amount of prefixed `$` to force immediate application @@ -102,7 +103,7 @@ impl<'a> Iterator for Lexer<'a> { let x = self.s.chars().next()?; let loc = self.loc; let rtok = match x { - '{' | '}' | '(' | ')' | '=' | ',' | ';' | '.' => { + '{' | '}' | '(' | ')' | '=' | ',' | ';' | '.' | '§' => { self.eat(x.len_utf8()); match x { '{' => Token::OpenBrace, @@ -113,6 +114,7 @@ impl<'a> Iterator for Lexer<'a> { ',' => Token::Comma, ';' => Token::SemiColon, '.' => Token::Dot, + '§' => Token::MatchPara, _ => unreachable!(), } } diff --git a/crates/wafl-parser/src/parser.rs b/crates/wafl-parser/src/parser.rs index b593cc0..c3cda15 100644 --- a/crates/wafl-parser/src/parser.rs +++ b/crates/wafl-parser/src/parser.rs @@ -249,8 +249,8 @@ impl Expression { _ => FullIdentifier::parse_high(ctx).map(Expression::Alias), }?; - Ok(match ctx.pklx.peek() { - None | Some((_, Token::SemiColon)) => obj, + match ctx.pklx.peek() { + None | Some((_, Token::SemiColon | Token::CloseBrace | Token::CloseParen)) => Ok(obj), Some((_, Token::Comma)) => { let mut args = BTreeMap::new(); while ctx.maybe_eat_token(Token::Comma).is_some() { @@ -264,13 +264,23 @@ impl Expression { }); } } - Expression::InvocationMulti { + Ok(Expression::InvocationMulti { obj: Box::new(obj), args, - } + }) } - _ => Expression::InvocationSingle(Box::new((obj, Expression::parse_high(ctx)?))), - }) + Some((_, Token::MatchPara)) => { + ctx.pklx.next(); + Ok(Expression::InvocationSingle(Box::new(( + obj, + Expression::parse_high(ctx)?, + )))) + } + _ => Err(Error { + loc: ctx.peek_loc(), + kind: ErrorKind::Unexpected("end of expression"), + }), + } } }