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", "request": "launch",
"name": "Debug", "name": "Debug",
"program": "${workspaceFolder}/build/bolt", "program": "${workspaceFolder}/build/bolt",
"args": [ "--direct-diagnostics", "check", "test.bolt" ], "args": [ "--direct-diagnostics", "verify", "test/checker/wrong_return_type.bolt" ],
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"preLaunchTask": "CMake: build" "preLaunchTask": "CMake: build"
} }

View file

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

View file

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

View file

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

View file

@ -426,77 +426,17 @@ after_string_contents:
Punctuator::Punctuator(Stream<Token*>& Tokens): Punctuator::Punctuator(Stream<Token*>& Tokens):
Tokens(Tokens) { Tokens(Tokens) {
Frames.push({ FrameType::Block }); Frames.push(FrameType::Block);
Locations.push(TextLoc { 0, 0 }); 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() { Token* Punctuator::read() {
auto T0 = Tokens.peek(); auto T0 = Tokens.peek();
auto& RefLoc = Locations.top();
auto& Frame = Frames.top();
switch (T0->getKind()) { switch (T0->getKind()) {
case NodeKind::LParen:
++Frame.Parens;
break;
case NodeKind::LBrace: case NodeKind::LBrace:
++Frame.Braces; Frames.push(FrameType::Fallthrough);
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;
break; break;
case NodeKind::EndOfFile: case NodeKind::EndOfFile:
{ {
@ -505,7 +445,9 @@ after_string_contents:
} }
auto Frame = Frames.top(); auto Frame = Frames.top();
Frames.pop(); Frames.pop();
switch (Frame.Type) { switch (Frame) {
case FrameType::Fallthrough:
break;
case FrameType::Block: case FrameType::Block:
return new BlockEnd(T0->getStartLoc()); return new BlockEnd(T0->getStartLoc());
case FrameType::LineFold: case FrameType::LineFold:
@ -516,17 +458,20 @@ after_string_contents:
break; 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: case FrameType::LineFold:
{ {
if (ShouldYieldNextTokenInLineFold) { if (T0->getStartLine() > RefLoc.Line
ShouldYieldNextTokenInLineFold = false; && T0->getStartColumn() <= RefLoc.Column) {
return Tokens.get();
}
ShouldYieldNextTokenInLineFold = isTerminal(T0->getKind());
if (ShouldYieldNextTokenInLineFold
|| (T0->getStartLine() > RefLoc.Line
&& T0->getStartColumn() <= RefLoc.Column)) {
Frames.pop(); Frames.pop();
Locations.pop(); Locations.pop();
return new LineFoldEnd(T0->getStartLoc()); return new LineFoldEnd(T0->getStartLoc());
@ -535,7 +480,7 @@ after_string_contents:
auto T1 = Tokens.peek(1); auto T1 = Tokens.peek(1);
if (T1->getStartLine() > T0->getEndLine()) { if (T1->getStartLine() > T0->getEndLine()) {
Tokens.get(); Tokens.get();
Frames.push({ FrameType::Block }); Frames.push(FrameType::Block);
return new BlockStart(T0->getStartLoc()); return new BlockStart(T0->getStartLoc());
} }
} }
@ -543,12 +488,12 @@ after_string_contents:
} }
case FrameType::Block: case FrameType::Block:
{ {
if (T0->getStartColumn() <= RefLoc.Column || isTerminal(T0->getKind())) { if (T0->getStartColumn() <= RefLoc.Column) {
Frames.pop(); Frames.pop();
return new BlockEnd(T0->getStartLoc()); return new BlockEnd(T0->getStartLoc());
} }
Frames.push({ FrameType::LineFold }); Frames.push(FrameType::LineFold);
Locations.push(T0->getStartLoc()); Locations.push(T0->getStartLoc());
return Tokens.get(); return Tokens.get();