Skip to content
This repository was archived by the owner on Mar 21, 2025. It is now read-only.

Commit 4dc61ef

Browse files
committed
Introduce the metarecord concept to the language.
1 parent fc41f0b commit 4dc61ef

File tree

14 files changed

+96
-19
lines changed

14 files changed

+96
-19
lines changed

doc/language/expressions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ prefix-expression ::= unary-expression |
88
primary-expression ::= parenthesized-expression |
99
block-expression |
1010
this-expression |
11+
meta-expression |
1112
identifier-expression |
1213
literal-expression |
1314
module-expression |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Meta Expression
2+
3+
```ebnf
4+
meta-expression ::= 'meta' expression
5+
```

doc/language/expressions/values/record-expression.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
```ebnf
44
record-expression ::= 'rec' record-expression-with? '{' (record-expression-field (',' record-expression-field)* ','?)? '}'
55
record-expression-with ::= 'with' expression
6+
record-expression-meta ::= 'meta' expression
67
record-expression-field ::= 'mut'? code-identifier ':' expression
78
```

doc/language/lexical-structure/keywords.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ normal-keyword ::= 'and' |
2727
'in' |
2828
'let' |
2929
'match' |
30+
'meta' |
3031
'mod' |
3132
'mut' |
3233
'next' |
@@ -71,7 +72,6 @@ type-keyword ::= 'agent' |
7172
```ebnf
7273
reserved-keyword ::= 'friend' |
7374
'macro' |
74-
'meta' |
7575
'quote' |
7676
'unquote' |
7777
'yield'

doc/language/types/record-type.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Record Type
22

33
```ebnf
4-
record-type ::= 'rec' '{' (record-type-field (',' record-type-field)* ','?)? '}'
4+
record-type ::= 'rec' '{' (record-type-field (',' record-type-field)* ','?)? '}' record-type-meta?
5+
record-type-meta ::= 'meta' type
56
record-type-field ::= 'mut'? code-identifier ':' type
67
```

doc/toc.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
* [Parenthesized Expression](language/expressions/parenthesized-expression.md)
9696
* [Block Expression](language/expressions/block-expression.md)
9797
* [This Expression](language/expressions/this-expression.md)
98+
* [Meta Expression](language/expressions/meta-expression.md)
9899
* [Identifier Expression](language/expressions/identifier-expression.md)
99100
* [Assignment Expression](language/expressions/assignment-expression.md)
100101
* [Field Expression](language/expressions/field-expression.md)

src/extensions/vscode/syntaxes/celerity.tmLanguage.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ patterns:
3838
- name: keyword.declaration.celerity
3939
match: \b(const|ext|fn|mod|opaque|pub|test|type|use)\b
4040
- name: keyword.control.celerity
41-
match: \b(as|assert|break|catch|cond|defer|else|for|if|in|let|match|mut|next|raise|recv|ret|tail|try|while)\b
41+
match: \b(as|assert|break|catch|cond|defer|else|for|if|in|let|match|meta|mut|next|raise|recv|ret|tail|try|while)\b
4242
- name: keyword.expression.celerity
4343
match: \b(and|err|not|or|rec|this|with)\b
4444
- name: keyword.type.celerity
4545
match: \b(agent|any|atom|bool|handle|int|none|real|ref|str|unk)\b
4646
- name: keyword.other.celerity
47-
match: \b(friend|macro|meta|quote|unquote|yield)\b
47+
match: \b(friend|macro|quote|unquote|yield)\b
4848
# Identifiers
4949
- name: support.type.celerity
5050
match: '[A-Z][0-9a-zA-Z]*'

src/language/core/Semantics/LanguageAnalyzer.cs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -381,12 +381,16 @@ public SubmissionSemantics VisitSubmission(SubmissionSyntax node)
381381

382382
public override DeclarationSubmissionSemantics VisitDeclarationSubmission(DeclarationSubmissionSyntax node)
383383
{
384-
return new(node, VisitDeclaration(node.Declaration));
384+
var decl = VisitDeclaration(node.Declaration);
385+
386+
return new(node, decl);
385387
}
386388

387389
public override StatementSubmissionSemantics VisitStatementSubmission(StatementSubmissionSyntax node)
388390
{
389-
return new(node, VisitStatement(node.Statement));
391+
var stmt = VisitStatement(node.Statement);
392+
393+
return new(node, stmt);
390394
}
391395

392396
// Declarations
@@ -580,26 +584,30 @@ public override ModuleExpressionSemantics VisitModuleExpression(ModuleExpression
580584
public override AggregateExpressionFieldSemantics VisitAggregateExpressionField(
581585
AggregateExpressionFieldSyntax node)
582586
{
583-
return new(node, VisitExpression(node.Value));
587+
var field = VisitExpression(node.Value);
588+
589+
return new(node, field);
584590
}
585591

586592
public override RecordExpressionSemantics VisitRecordExpression(RecordExpressionSyntax node)
587593
{
594+
var with = node.With?.Operand is { } w ? VisitExpression(w) : null;
588595
var fields = ConvertList(node.Fields, static (@this, field) => @this.VisitAggregateExpressionField(field));
596+
var meta = node.Meta?.Operand is { } m ? VisitExpression(m) : null;
589597

590598
CheckDuplicateFields(fields, static field => field.Syntax.NameToken, "Record", "assigned");
591599

592-
return new(node, node.With?.Operand is { } with ? VisitExpression(with) : null, fields);
600+
return new(node, with, fields, meta);
593601
}
594602

595603
public override ErrorExpressionSemantics VisitErrorExpression(ErrorExpressionSyntax node)
596604
{
597-
var fields = ConvertList(
598-
node.Fields, static (@this, field) => @this.VisitAggregateExpressionField(field));
605+
var with = node.With?.Operand is { } w ? VisitExpression(w) : null;
606+
var fields = ConvertList(node.Fields, static (@this, field) => @this.VisitAggregateExpressionField(field));
599607

600608
CheckDuplicateFields(fields, static field => field.Syntax.NameToken, "Error", "assigned");
601609

602-
return new(node, node.With?.Operand is { } with ? VisitExpression(with) : null, fields);
610+
return new(node, with, fields);
603611
}
604612

605613
public override TupleExpressionSemantics VisitTupleExpression(TupleExpressionSyntax node)
@@ -982,7 +990,9 @@ public override BreakExpressionSemantics VisitBreakExpression(BreakExpressionSyn
982990
public override ParenthesizedExpressionSemantics VisitParenthesizedExpression(
983991
ParenthesizedExpressionSyntax node)
984992
{
985-
return new(node, VisitExpression(node.Expression));
993+
var expr = VisitExpression(node.Expression);
994+
995+
return new(node, expr);
986996
}
987997

988998
public override BlockExpressionSemantics VisitBlockExpression(BlockExpressionSyntax node)
@@ -1065,6 +1075,13 @@ public override ThisExpressionSemantics VisitThisExpression(ThisExpressionSyntax
10651075
return sema;
10661076
}
10671077

1078+
public override MetaExpressionSemantics VisitMetaExpression(MetaExpressionSyntax node)
1079+
{
1080+
var oper = VisitExpression(node.Operand);
1081+
1082+
return new(node, oper);
1083+
}
1084+
10681085
public override AssignmentExpressionSemantics VisitAssignmentExpression(AssignmentExpressionSyntax node)
10691086
{
10701087
var left = VisitExpression(node.LeftOperand);
@@ -1101,7 +1118,9 @@ public override AssignmentExpressionSemantics VisitAssignmentExpression(Assignme
11011118

11021119
public override FieldExpressionSemantics VisitFieldExpression(FieldExpressionSyntax node)
11031120
{
1104-
return new(node, VisitExpression(node.Subject));
1121+
var subject = VisitExpression(node.Subject);
1122+
1123+
return new(node, subject);
11051124
}
11061125

11071126
public override IndexExpressionSemantics VisitIndexExpression(IndexExpressionSyntax node)

src/language/core/Semantics/Tree/SemanticTree.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
<Type Name="RecordExpression" Base="AggregateExpression">
142142
<Node Name="With" Type="Expression" Optional="true" Override="true" />
143143
<Nodes Name="Field" Type="AggregateExpressionField" Separated="true" Override="true" />
144+
<Node Name="Meta" Type="Expression" Optional="true" />
144145
</Type>
145146

146147
<Type Name="ErrorExpression" Base="AggregateExpression">
@@ -341,6 +342,10 @@
341342

342343
<Type Name="ThisExpression" Base="Expression" />
343344

345+
<Type Name="MetaExpression">
346+
<Node Name="Operand" Type="Expression" />
347+
</Type>
348+
344349
<Type Name="IdentifierExpression" Base="Expression">
345350
<Value Name="Symbol" Type="Symbol?" />
346351
</Type>

src/language/core/Syntax/LanguageParser.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,8 +866,17 @@ private RecordTypeSyntax ParseRecordType()
866866
allowEmpty: true,
867867
allowTrailing: true);
868868
var close = Expect(SyntaxTokenKind.CloseBrace);
869+
var meta = ParseOptional(SyntaxTokenKind.MetaKeyword, static @this => @this.ParseRecordTypeMeta());
869870

870-
return new(rec, open, List(fields, seps), close);
871+
return new(rec, open, List(fields, seps), close, meta);
872+
}
873+
874+
private RecordTypeMetaSyntax ParseRecordTypeMeta()
875+
{
876+
var meta = Read();
877+
var type = ParseType();
878+
879+
return new(meta, type);
871880
}
872881

873882
private ErrorTypeSyntax ParseErrorType()
@@ -1284,6 +1293,7 @@ private ExpressionSyntax ParsePrimaryExpression()
12841293
(var ident, _, _) when SyntaxFacts.IsBindingIdentifier(ident) => ParseIdentifierExpression(),
12851294
(var literal, _, _) when SyntaxFacts.IsLiteral(literal) => ParseLiteralExpression(),
12861295
(SyntaxTokenKind.ThisKeyword, _, _) => ParseThisExpression(),
1296+
(SyntaxTokenKind.MetaKeyword, _, _) => ParseMetaExpression(),
12871297
(SyntaxTokenKind.UpperIdentifier, _, _) => ParseModuleExpression(),
12881298
(SyntaxTokenKind.FnKeyword, _, _) or
12891299
(SyntaxTokenKind.ErrKeyword, SyntaxTokenKind.FnKeyword, _) => ParseLambdaExpression(),
@@ -1389,6 +1399,14 @@ private ThisExpressionSyntax ParseThisExpression()
13891399
return new(@this);
13901400
}
13911401

1402+
private MetaExpressionSyntax ParseMetaExpression()
1403+
{
1404+
var meta = Read();
1405+
var oper = ParseExpression();
1406+
1407+
return new(meta, oper);
1408+
}
1409+
13921410
private LiteralExpressionSyntax ParseLiteralExpression()
13931411
{
13941412
var literal = Read();
@@ -1415,8 +1433,17 @@ private RecordExpressionSyntax ParseRecordExpression()
14151433
allowEmpty: true,
14161434
allowTrailing: true);
14171435
var close = Expect(SyntaxTokenKind.CloseBrace);
1436+
var meta = ParseOptional(SyntaxTokenKind.MetaKeyword, static @this => @this.ParseRecordExpressionMeta());
1437+
1438+
return new(rec, with, open, List(fields, seps), close, meta);
1439+
}
1440+
1441+
private RecordExpressionMetaSyntax ParseRecordExpressionMeta()
1442+
{
1443+
var meta = Read();
1444+
var operand = ParseExpression();
14181445

1419-
return new(rec, with, open, List(fields, seps), close);
1446+
return new(meta, operand);
14201447
}
14211448

14221449
private ErrorExpressionSyntax ParseErrorExpression()

0 commit comments

Comments
 (0)