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 partial record SimplePattern
|
||||||
{
|
{
|
||||||
public override string ToString()
|
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 partial record Let
|
||||||
{
|
{
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@ -68,4 +76,4 @@ public partial record RecordPattern
|
|||||||
{
|
{
|
||||||
return $"Let {{ Bindings = {string.Join(", ", (IEnumerable<object?>)(this.Fields))}, Rest = {this.Rest} }}";
|
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();
|
return ifExpr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Add function bindings.
|
|
||||||
List<Binding> bindings = new List<Binding>();
|
List<Binding> bindings = new List<Binding>();
|
||||||
Pattern p = pattern();
|
bindings.Add(parseBinding());
|
||||||
consume(TokenType.Equal, "Expect '=' after pattern.");
|
|
||||||
bindings.Add(new(p, expression()));
|
|
||||||
while (match(TokenType.And))
|
while (match(TokenType.And))
|
||||||
{
|
{
|
||||||
p = pattern();
|
bindings.Add(parseBinding());
|
||||||
consume(TokenType.Equal, "Expect '=' after pattern.");
|
|
||||||
bindings.Add(new(p, expression()));
|
|
||||||
}
|
}
|
||||||
consume(TokenType.In, "Expect 'in' after let-bindings.");
|
consume(TokenType.In, "Expect 'in' after let-bindings.");
|
||||||
Expr body = expression();
|
Expr body = expression();
|
||||||
return new Let(bindings.ToArray(), body);
|
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()
|
private Expr ifExpr()
|
||||||
@ -300,7 +333,7 @@ class Parser
|
|||||||
Pattern pat = pattern();
|
Pattern pat = pattern();
|
||||||
consume(TokenType.DoubleArrow, "Expect '=>' after pattern.");
|
consume(TokenType.DoubleArrow, "Expect '=>' after pattern.");
|
||||||
Expr value = expression();
|
Expr value = expression();
|
||||||
return new(pat, value);
|
return new VarBinding(pat, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +390,7 @@ class Parser
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
consume(TokenType.RParen, "Expect '(' after arguments.");
|
consume(TokenType.RParen, "Expect ')' after arguments.");
|
||||||
return new Call(expr, args.ToArray());
|
return new Call(expr, args.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user