muScript: support complex bind expressions

This commit is contained in:
Johannes Frohnmeyer 2023-03-11 14:30:42 +01:00
parent 044f468024
commit 7440920099
Signed by: Johannes
GPG Key ID: E76429612C2929F4
2 changed files with 22 additions and 2 deletions

View File

@ -242,8 +242,14 @@ public class Parser {
yield new Get(start, end, asDynamic(expr), Expr.literal(name.start, name.current - 1, name.lexeme));
}
case DoubleColon -> {
TokenData name = consume(Token.Identifier, "Expected variable name after '::'.");
yield new Bind(start, end, new Variable(name.start, name.current - 1, name.lexeme), expr.asDynamicExpr());
DynamicExpr callable;
if (match(Token.Identifier)) {
callable = new Variable(previous.start, previous.current - 1, previous.lexeme);
} else if (match(Token.LeftParen)) {
callable = expression().asDynamicExpr();
consume(Token.RightParen, "Expected ')' after expression.");
} else throw error("Bind operator requires right side to be a literal identifier or to be wrapped in parentheses.");
yield new Bind(start, end, callable, expr.asDynamicExpr());
}
case LeftBracket -> {
expr = new Get(start, end, asDynamic(expr), expression());

View File

@ -21,4 +21,18 @@ class BindTest {
numbers::map({n->n::function(2)})::filter({n->n%2!=0})
""").asExpr().asStringExpr().get(makeArgs()));
}
@Test
void complexBind() {
// fn = {b -> 2 * b}
assertEquals(6, Parser.parseScript("""
fn = 2::({a, b -> a * b})
fn(3)
""").asExpr().asNumberExpr().get(makeArgs()));
// {a, b, c -> a(b(c))}(fn, {a -> a + 5}, 3)
assertEquals(16, Parser.parseScript("""
fn = 2::({a, b -> a * b})
fn::({a, b, c -> a(b(c))})({a -> a + 5}, 3)
""").asExpr().asNumberExpr().get(makeArgs()));
}
}