Add support for parsing record declarations

This commit is contained in:
Sam Vervaeck 2023-05-27 15:25:17 +02:00
parent bed5d3cbc4
commit 16e85f26bd
Signed by: samvv
SSH key fingerprint: SHA256:dIg0ywU1OP+ZYifrYxy8c5esO72cIKB+4/9wkZj1VaY
3 changed files with 86 additions and 2 deletions

View file

@ -1719,14 +1719,14 @@ namespace bolt {
class PubKeyword* PubKeyword;
class StructKeyword* StructKeyword;
Identifier* Name;
IdentifierAlt* Name;
class BlockStart* BlockStart;
std::vector<RecordDeclarationField*> Fields;
RecordDeclaration(
class PubKeyword* PubKeyword,
class StructKeyword* StructKeyword,
Identifier* Name,
IdentifierAlt* Name,
class BlockStart* BlockStart,
std::vector<RecordDeclarationField*> Fields
): Node(NodeKind::RecordDeclaration),

View file

@ -129,6 +129,8 @@ namespace bolt {
InstanceDeclaration* parseInstanceDeclaration();
RecordDeclaration* parseRecordDeclaration();
Node* parseSourceElement();
SourceFile* parseSourceFile();

View file

@ -1054,6 +1054,86 @@ after_vars:
);
}
RecordDeclaration* Parser::parseRecordDeclaration() {
auto T0 = Tokens.peek();
PubKeyword* Pub = nullptr;
if (T0->getKind() == NodeKind::MutKeyword) {
Tokens.get();
Pub = static_cast<PubKeyword*>(T0);
}
auto Struct = expectToken<StructKeyword>();
if (!Struct) {
if (Pub) {
Pub->unref();
}
skipToLineFoldEnd();
return nullptr;
}
auto Name = expectToken<IdentifierAlt>();
if (!Name) {
if (Pub) {
Pub->unref();
}
Struct->unref();
skipToLineFoldEnd();
return nullptr;
}
auto BS = expectToken<BlockStart>();
if (!BS) {
if (Pub) {
Pub->unref();
}
Struct->unref();
Name->unref();
skipToLineFoldEnd();
return nullptr;
}
std::vector<RecordDeclarationField*> Fields;
for (;;) {
auto T1 = Tokens.get();
if (T1->getKind() == NodeKind::BlockEnd) {
break;
}
if (T1->getKind() != NodeKind::Identifier) {
DE.add<UnexpectedTokenDiagnostic>(File, T1, std::vector { NodeKind::Identifier });
if (Pub) {
Pub->unref();
}
Struct->unref();
Name->unref();
T1->unref();
skipToLineFoldEnd();
return nullptr;
}
auto Colon = expectToken<class Colon>();
if (!Colon) {
if (Pub) {
Pub->unref();
}
Struct->unref();
Name->unref();
T1->unref();
skipToLineFoldEnd();
return nullptr;
}
auto TE = parseTypeExpression();
if (!TE) {
if (Pub) {
Pub->unref();
}
Struct->unref();
Name->unref();
T1->unref();
Colon->unref();
skipToLineFoldEnd();
return nullptr;
}
checkLineFoldEnd();
}
Tokens.get(); // Always a LineFoldEnd
return new RecordDeclaration { Pub, Struct, Name, BS, Fields };
}
Node* Parser::parseClassElement() {
auto T0 = Tokens.peek();
switch (T0->getKind()) {
@ -1079,6 +1159,8 @@ after_vars:
return parseClassDeclaration();
case NodeKind::InstanceKeyword:
return parseInstanceDeclaration();
case NodeKind::StructKeyword:
return parseRecordDeclaration();
default:
return parseExpressionStatement();
}