Parse function bindings
This commit is contained in:
parent
4fe56dbdbc
commit
eed952d154
14
AST.cs
14
AST.cs
@ -40,8 +40,6 @@ public partial record Literal
|
||||
}
|
||||
}
|
||||
|
||||
public record Binding(Pattern Pattern, Expr Value);
|
||||
|
||||
public partial record SimplePattern
|
||||
{
|
||||
public override string ToString()
|
||||
@ -54,6 +52,16 @@ public partial record SimplePattern
|
||||
}
|
||||
}
|
||||
|
||||
public abstract record Binding(Expr Value);
|
||||
public record VarBinding(Pattern Pattern, Expr Value) : Binding(Value);
|
||||
public record FuncBinding(Name Name, SimplePattern[] Params, Expr Value) : Binding(Value)
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return $"FuncBinding {{ Name = {Name}, Params = {string.Join(", ", (IEnumerable<object?>)(this.Params))}, Value = {this.Value} }}";
|
||||
}
|
||||
}
|
||||
|
||||
public partial record Let
|
||||
{
|
||||
public override string ToString()
|
||||
@ -68,4 +76,4 @@ public partial record RecordPattern
|
||||
{
|
||||
return $"Let {{ Bindings = {string.Join(", ", (IEnumerable<object?>)(this.Fields))}, Rest = {this.Rest} }}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
Parser.cs
51
Parser.cs
@ -248,20 +248,53 @@ class Parser
|
||||
return ifExpr();
|
||||
}
|
||||
|
||||
// TODO Add function bindings.
|
||||
List<Binding> bindings = new List<Binding>();
|
||||
Pattern p = pattern();
|
||||
consume(TokenType.Equal, "Expect '=' after pattern.");
|
||||
bindings.Add(new(p, expression()));
|
||||
bindings.Add(parseBinding());
|
||||
while (match(TokenType.And))
|
||||
{
|
||||
p = pattern();
|
||||
consume(TokenType.Equal, "Expect '=' after pattern.");
|
||||
bindings.Add(new(p, expression()));
|
||||
bindings.Add(parseBinding());
|
||||
}
|
||||
consume(TokenType.In, "Expect 'in' after let-bindings.");
|
||||
Expr body = expression();
|
||||
return new Let(bindings.ToArray(), body);
|
||||
|
||||
Binding parseBinding()
|
||||
{
|
||||
Pattern p = pattern();
|
||||
switch (p)
|
||||
{
|
||||
case (SimplePattern(var funcName)) when funcName != null && match(TokenType.LParen):
|
||||
List<SimplePattern> funcParams = new List<SimplePattern>();
|
||||
while (!check(TokenType.RParen))
|
||||
{
|
||||
Name? paramName;
|
||||
if (match(TokenType.Blank))
|
||||
{
|
||||
funcParams.Add(new(null));
|
||||
}
|
||||
else if ((paramName = name()) != null)
|
||||
{
|
||||
funcParams.Add(new(paramName));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw error(peek(), "Expect identifier or '_' as function parameter.");
|
||||
}
|
||||
if (!match(TokenType.Comma))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
consume(TokenType.RParen, "Expect ')' at end of parameters.");
|
||||
consume(TokenType.Equal, "Expect '=' after parameters.");
|
||||
return new FuncBinding(funcName, funcParams.ToArray(), expression());
|
||||
default:
|
||||
consume(TokenType.Equal, "Expect '=' after pattern.");
|
||||
return new VarBinding(p, expression());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Expr ifExpr()
|
||||
@ -300,7 +333,7 @@ class Parser
|
||||
Pattern pat = pattern();
|
||||
consume(TokenType.DoubleArrow, "Expect '=>' after pattern.");
|
||||
Expr value = expression();
|
||||
return new(pat, value);
|
||||
return new VarBinding(pat, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,7 +390,7 @@ class Parser
|
||||
break;
|
||||
}
|
||||
}
|
||||
consume(TokenType.RParen, "Expect '(' after arguments.");
|
||||
consume(TokenType.RParen, "Expect ')' after arguments.");
|
||||
return new Call(expr, args.ToArray());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user