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

@ -61,3 +61,11 @@ public partial record Let
return $"Let {{ Bindings = {string.Join(", ", (IEnumerable<object?>)(this.Bindings))}, Body = {this.Body} }}"; 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; 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() private VariantPattern? variantPattern()
@ -190,7 +208,7 @@ class Parser
return new(tag, argument); return new(tag, argument);
} }
private Pattern pattern() private SimplePattern? simplePattern()
{ {
if (match(TokenType.Blank)) if (match(TokenType.Blank))
{ {
@ -203,8 +221,17 @@ class Parser
return new SimplePattern(identifier); return new SimplePattern(identifier);
} }
Pattern? p = recordPattern(); return null;
if (p != null) }
private Pattern pattern()
{
Pattern? p;
if ((p = simplePattern()) != null)
{
return p;
}
if ((p = recordPattern()) != null)
{ {
return p; return p;
} }
@ -212,7 +239,15 @@ class Parser
{ {
return p; 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() private Expr let()