Parse record patterns
This commit is contained in:
parent
b5bdd95605
commit
f43e0464b6
8
AST.cs
8
AST.cs
@ -60,4 +60,12 @@ 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} }}";
|
||||||
|
}
|
||||||
}
|
}
|
45
Parser.cs
45
Parser.cs
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user