From 16e85f26bd04a410f7f105af2e04b86efac8f0df Mon Sep 17 00:00:00 2001 From: Sam Vervaeck Date: Sat, 27 May 2023 15:25:17 +0200 Subject: [PATCH] Add support for parsing record declarations --- include/bolt/CST.hpp | 4 +- include/bolt/Parser.hpp | 2 + src/Parser.cc | 82 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/include/bolt/CST.hpp b/include/bolt/CST.hpp index 8c05ab47c..36897c05a 100644 --- a/include/bolt/CST.hpp +++ b/include/bolt/CST.hpp @@ -1719,14 +1719,14 @@ namespace bolt { class PubKeyword* PubKeyword; class StructKeyword* StructKeyword; - Identifier* Name; + IdentifierAlt* Name; class BlockStart* BlockStart; std::vector Fields; RecordDeclaration( class PubKeyword* PubKeyword, class StructKeyword* StructKeyword, - Identifier* Name, + IdentifierAlt* Name, class BlockStart* BlockStart, std::vector Fields ): Node(NodeKind::RecordDeclaration), diff --git a/include/bolt/Parser.hpp b/include/bolt/Parser.hpp index d66e1f88a..c578ba446 100644 --- a/include/bolt/Parser.hpp +++ b/include/bolt/Parser.hpp @@ -129,6 +129,8 @@ namespace bolt { InstanceDeclaration* parseInstanceDeclaration(); + RecordDeclaration* parseRecordDeclaration(); + Node* parseSourceElement(); SourceFile* parseSourceFile(); diff --git a/src/Parser.cc b/src/Parser.cc index b7c44c7ce..c76819a54 100644 --- a/src/Parser.cc +++ b/src/Parser.cc @@ -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(T0); + } + auto Struct = expectToken(); + if (!Struct) { + if (Pub) { + Pub->unref(); + } + skipToLineFoldEnd(); + return nullptr; + } + auto Name = expectToken(); + if (!Name) { + if (Pub) { + Pub->unref(); + } + Struct->unref(); + skipToLineFoldEnd(); + return nullptr; + } + auto BS = expectToken(); + if (!BS) { + if (Pub) { + Pub->unref(); + } + Struct->unref(); + Name->unref(); + skipToLineFoldEnd(); + return nullptr; + } + std::vector Fields; + for (;;) { + auto T1 = Tokens.get(); + if (T1->getKind() == NodeKind::BlockEnd) { + break; + } + if (T1->getKind() != NodeKind::Identifier) { + DE.add(File, T1, std::vector { NodeKind::Identifier }); + if (Pub) { + Pub->unref(); + } + Struct->unref(); + Name->unref(); + T1->unref(); + skipToLineFoldEnd(); + return nullptr; + } + auto Colon = expectToken(); + 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(); }