Parse record patterns

This commit is contained in:
Brandon Dyck 2023-07-02 17:07:46 -06:00
parent b5bdd95605
commit f43e0464b6
2 changed files with 48 additions and 5 deletions

8
AST.cs
View File

@ -60,4 +60,12 @@ public partial record Let
{
return $"Let {{ Bindings = {string.Join(", ", (IEnumerable<object?>)(this.Bindings))}, Body = {this.Body} }}";
}
}
public partial record RecordPattern
{
public override string ToString()
{
return $"Let {{ Bindings = {string.Join(", ", (IEnumerable<object?>)(this.Fields))}, Rest = {this.Rest} }}";
}
}

View File

@ -167,7 +167,25 @@ class Parser
{
return null;
}
throw new NotImplementedException("TODO record pattern");
List<FieldPattern> fields = new List<FieldPattern>();
while (!check(TokenType.RBrace, TokenType.Pipe))
{
var fieldName = name();
if (fieldName == null)
{
throw error(peek(), "Expect identifier as field name.");
}
var pat = match(TokenType.Equal) ? pattern() : null;
fields.Add(new(fieldName, pat));
if (!match(TokenType.Comma))
{
break;
}
}
var restPattern = match(TokenType.Pipe) ? simplePattern() : null;
consume(TokenType.RBrace, "Expect '}' at end of record pattern.");
return new(fields.ToArray(), restPattern);
}
private VariantPattern? variantPattern()
@ -190,7 +208,7 @@ class Parser
return new(tag, argument);
}
private Pattern pattern()
private SimplePattern? simplePattern()
{
if (match(TokenType.Blank))
{
@ -203,8 +221,17 @@ class Parser
return new SimplePattern(identifier);
}
Pattern? p = recordPattern();
if (p != null)
return null;
}
private Pattern pattern()
{
Pattern? p;
if ((p = simplePattern()) != null)
{
return p;
}
if ((p = recordPattern()) != null)
{
return p;
}
@ -212,7 +239,15 @@ class Parser
{
return p;
}
throw error(peek(), "Expect pattern after 'let'.");
if (check(TokenType.String))
{
throw error(peek(), "Cannot pattern-match string literals.");
}
if (check(TokenType.Number))
{
throw error(peek(), "Cannot pattern-match numbers.");
}
throw error(peek(), "Expect pattern.");
}
private Expr let()