remove tag+match, introduce return

This commit is contained in:
Alain Zscheile 2023-05-23 16:42:24 +02:00
parent 8d693ae99d
commit 5a3254004f
3 changed files with 50 additions and 21 deletions

View file

@ -36,7 +36,7 @@ as an argument, prefix the block with `'`.
- `cflow.if, cond = ..., then = ..., else = ...`
- `cflow.loop § ...`
- `cflow.return § ...` (implicit when last expr in a block is not terminated via semicolon)
- `return ...` (implicit when last expr in a block is not terminated via semicolon)
## Modules
@ -77,3 +77,39 @@ with package-lock files or such. Packages (packaged module trees) would then be
# running `what_now` results in "It works" being printed.
```
## A note about tags, variants, enum
This language doesn't have that anymore (at least for now, I might reintroduce it
if it becomes necessary for performance or readabilitiy reasons or such).
It originally was designed to work like the following:
```
produce = { tag error, kind = "smth. bad" };
consume = {
module {
error { kind } = {
# handle the errors from produce
std.io.write § "Error occured: ";
std.io.write § $kind;
};
} : produce;
};
```
But it should be possible without introducing a new feature with really weird type signatures...
```
final lambda { body } = { module { body { env } = $$body, env = $env; } };
produce = { lambda, body { env } = { env.error, kind = "smth. bad" } };
consume = {
produce.body § module {
error { kind } = {
# handle the errors from produce
std.io.write § "Error occured: ";
std.io.write § $kind;
};
};
};
```

View file

@ -8,7 +8,7 @@ pub enum Token<'a> {
Final,
Module,
Public,
Tag,
Return,
// single-char keywords
Assign,
@ -183,7 +183,7 @@ impl<'a> Iterator for Lexer<'a> {
"final" => Token::Final,
"module" => Token::Module,
"pub" => Token::Public,
"tag" => Token::Tag,
"return" => Token::Return,
_ => Token::Identifier(ident),
}
}

View file

@ -45,14 +45,12 @@ pub enum Expression {
Module(Module),
Alias(FullIdentifier),
Integer(i64),
Return(Box<Expression>),
InvocationSingle(Box<(Expression, Expression)>),
InvocationMulti {
obj: Box<Expression>,
args: BTreeMap<Box<[Atom]>, (Location, Expression)>,
},
// note: an InvocationMulti { obj: Tag(_), .. } has speccial meaning
Tag(Path),
Match(Box<Match>),
}
// a match is the destructuring stmt for tags
@ -191,7 +189,9 @@ impl FullIdentifier {
impl Expression {
fn parse_high(ctx: &mut ParserContext<'_>) -> Result<Self, Error> {
let retwrap = ctx.maybe_eat_token(Token::Return).is_some();
let mut cfe = false;
for (_, i) in ctx
.pklx
.peeking_take_while(|(_, t)| matches!(t, Token::CtrlFlowEdit))
@ -252,23 +252,10 @@ impl Expression {
ctx.expect_token(Token::CloseBrace, "}")?;
Ok(Expression::Module(m))
}
Some((_, Token::Tag)) => {
ctx.pklx.next();
Path::parse_high(ctx).map(Expression::Tag)
}
_ => FullIdentifier::parse_high(ctx).map(Expression::Alias),
}?;
while let Some(loc) = ctx.maybe_eat_token(Token::Colon) {
// dot with dereference
obj = Expression::Match(Box::new(Match {
loc,
module: obj,
key: Expression::parse_high(ctx)?,
}));
}
match ctx.pklx.peek() {
obj = match ctx.pklx.peek() {
None | Some((_, Token::SemiColon | Token::CloseBrace | Token::CloseParen)) => Ok(obj),
Some((_, Token::Comma)) => {
let mut args = BTreeMap::new();
@ -299,7 +286,13 @@ impl Expression {
loc: ctx.peek_loc(),
kind: ErrorKind::Unexpected("end of expression"),
}),
}
}?;
Ok(if retwrap {
Expression::Return(Box::new(obj))
} else {
obj
})
}
}