Revert "Make it possible to nest match-expressions"

This reverts commit ac7467bccb.

The commit breaks too much syntax.
This commit is contained in:
Sam Vervaeck 2023-06-15 16:29:35 +02:00
parent ac7467bccb
commit 8b1263c376
Signed by: samvv
SSH key fingerprint: SHA256:dIg0ywU1OP+ZYifrYxy8c5esO72cIKB+4/9wkZj1VaY
5 changed files with 31 additions and 102 deletions

2
.vscode/launch.json vendored
View file

@ -9,7 +9,7 @@
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/build/bolt",
"args": [ "--direct-diagnostics", "check", "test.bolt" ],
"args": [ "--direct-diagnostics", "verify", "test/checker/wrong_return_type.bolt" ],
"cwd": "${workspaceFolder}",
"preLaunchTask": "CMake: build"
}

View file

@ -99,9 +99,6 @@ namespace bolt {
void checkLineFoldEnd();
void skipToLineFoldEnd();
void disablePunctuation();
void enablePunctuation();
public:
Parser(TextFile& File, Stream<Token*>& S, DiagnosticEngine& DE);

View file

@ -61,25 +61,16 @@ namespace bolt {
enum class FrameType {
Block,
LineFold,
};
struct Frame {
FrameType Type;
int Parens = 0;
int Braces = 0;
int Brackets = 0;
Fallthrough,
};
class Punctuator : public BufferedStream<Token*> {
Stream<Token*>& Tokens;
std::stack<Frame> Frames;
std::stack<FrameType> Frames;
std::stack<TextLoc> Locations;
bool ShouldYieldNextTokenInLineFold = false;
bool isTerminal(NodeKind Kind);
protected:
virtual Token* read() override;

View file

@ -492,8 +492,8 @@ after_tuple_element:
}
MatchExpression* Parser::parseMatchExpression() {
auto Match = expectToken<MatchKeyword>();
if (!Match) {
auto T0 = expectToken<MatchKeyword>();
if (!T0) {
return nullptr;
}
auto T1 = Tokens.peek();
@ -506,12 +506,12 @@ after_tuple_element:
} else {
Value = parseExpression();
if (!Value) {
Match->unref();
T0->unref();
return nullptr;
}
BlockStart = expectToken<class BlockStart>();
if (!BlockStart) {
Match->unref();
T0->unref();
Value->unref();
return nullptr;
}
@ -544,7 +544,7 @@ after_tuple_element:
checkLineFoldEnd();
Cases.push_back(new MatchCase { Pattern, RArrowAlt, Expression });
}
return new MatchExpression(Match, Value, BlockStart, Cases);
return new MatchExpression(static_cast<MatchKeyword*>(T0), Value, BlockStart, Cases);
}
RecordExpression* Parser::parseRecordExpression() {
@ -688,13 +688,10 @@ after_tuple_element:
case NodeKind::LineFoldEnd:
case NodeKind::BlockStart:
case NodeKind::EndOfFile:
// Can recover from this one
RParen = nullptr;
DE.add<UnexpectedTokenDiagnostic>(File, T2, std::vector { NodeKind::RParen, NodeKind::Comma });
LParen->unref();
for (auto [E, Comma]: Elements) {
E->unref();
Comma->unref();
}
return nullptr;
goto after_tuple_elements;
}
}
after_tuple_elements:
@ -767,7 +764,6 @@ finish:
if (T1->getKind() == NodeKind::LineFoldEnd
|| T1->getKind() == NodeKind::RParen
|| T1->getKind() == NodeKind::RBrace
|| T1->getKind() == NodeKind::RBracket
|| T1->getKind() == NodeKind::BlockStart
|| T1->getKind() == NodeKind::Comma
|| ExprOperators.isInfix(T1)) {

View file

@ -426,77 +426,17 @@ after_string_contents:
Punctuator::Punctuator(Stream<Token*>& Tokens):
Tokens(Tokens) {
Frames.push({ FrameType::Block });
Frames.push(FrameType::Block);
Locations.push(TextLoc { 0, 0 });
}
static bool isCloseDelim(NodeKind Kind) {
switch (Kind) {
case NodeKind::RParen:
case NodeKind::RBrace:
case NodeKind::RBracket:
return true;
default:
return false;
}
}
// struct DelimCounter {
// int Parens = 0;
// int Braces = 0;
// int Brackets = 0;
// };
bool Punctuator::isTerminal(NodeKind Kind) {
auto& Frame = Frames.top();
switch (Kind) {
case NodeKind::RParen:
return Frame.Parens == 0;
case NodeKind::RBrace:
return Frame.Braces == 0;
case NodeKind::RBracket:
return Frame.Brackets == 0;
default:
return false;
}
}
Token* Punctuator::read() {
auto T0 = Tokens.peek();
auto& RefLoc = Locations.top();
auto& Frame = Frames.top();
switch (T0->getKind()) {
case NodeKind::LParen:
++Frame.Parens;
break;
case NodeKind::LBrace:
++Frame.Braces;
break;
case NodeKind::LBracket:
++Frame.Brackets;
break;
case NodeKind::RParen:
if (Frame.Parens == 0) {
// TODO add diagnostic?
break;
}
--Frame.Parens;
break;
case NodeKind::RBrace:
if (Frame.Braces == 0) {
// TODO add diagnostic?
break;
}
--Frame.Braces;
break;
case NodeKind::RBracket:
if (Frame.Brackets == 0) {
// TODO add diagnostic?
break;
}
--Frame.Brackets;
Frames.push(FrameType::Fallthrough);
break;
case NodeKind::EndOfFile:
{
@ -505,7 +445,9 @@ after_string_contents:
}
auto Frame = Frames.top();
Frames.pop();
switch (Frame.Type) {
switch (Frame) {
case FrameType::Fallthrough:
break;
case FrameType::Block:
return new BlockEnd(T0->getStartLoc());
case FrameType::LineFold:
@ -516,17 +458,20 @@ after_string_contents:
break;
}
switch (Frame.Type) {
auto RefLoc = Locations.top();
switch (Frames.top()) {
case FrameType::Fallthrough:
{
if (T0->getKind() == NodeKind::RBrace) {
Frames.pop();
}
Tokens.get();
return T0;
}
case FrameType::LineFold:
{
if (ShouldYieldNextTokenInLineFold) {
ShouldYieldNextTokenInLineFold = false;
return Tokens.get();
}
ShouldYieldNextTokenInLineFold = isTerminal(T0->getKind());
if (ShouldYieldNextTokenInLineFold
|| (T0->getStartLine() > RefLoc.Line
&& T0->getStartColumn() <= RefLoc.Column)) {
if (T0->getStartLine() > RefLoc.Line
&& T0->getStartColumn() <= RefLoc.Column) {
Frames.pop();
Locations.pop();
return new LineFoldEnd(T0->getStartLoc());
@ -535,7 +480,7 @@ after_string_contents:
auto T1 = Tokens.peek(1);
if (T1->getStartLine() > T0->getEndLine()) {
Tokens.get();
Frames.push({ FrameType::Block });
Frames.push(FrameType::Block);
return new BlockStart(T0->getStartLoc());
}
}
@ -543,12 +488,12 @@ after_string_contents:
}
case FrameType::Block:
{
if (T0->getStartColumn() <= RefLoc.Column || isTerminal(T0->getKind())) {
if (T0->getStartColumn() <= RefLoc.Column) {
Frames.pop();
return new BlockEnd(T0->getStartLoc());
}
Frames.push({ FrameType::LineFold });
Frames.push(FrameType::LineFold);
Locations.push(T0->getStartLoc());
return Tokens.get();