Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lib/Translation/ForthToMLIR/ForthToMLIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,11 @@ LogicalResult ForthParser::parseBody(Value &stack) {
builder.create<cf::BranchOp>(loc, mergeBlock, ValueRange{stack});

// Pop the false-path block (from IF) - this becomes else-body start.
if (cfStack.empty())
return emitError("ELSE without matching IF");
auto [tag, joinBlock] = cfStack.pop_back_val();
if (tag != CFTag::Orig)
return emitError("ELSE without matching IF");

// Push merge block for THEN to pick up.
cfStack.push_back({CFTag::Orig, mergeBlock});
Expand All @@ -777,7 +781,11 @@ LogicalResult ForthParser::parseBody(Value &stack) {
consume();

// Pop the join/merge block.
if (cfStack.empty())
return emitError("THEN without matching IF");
auto [tag, joinBlock] = cfStack.pop_back_val();
if (tag != CFTag::Orig)
return emitError("THEN without matching IF");

// Branch from current block to join.
builder.create<cf::BranchOp>(loc, joinBlock, ValueRange{stack});
Expand Down Expand Up @@ -810,7 +818,11 @@ LogicalResult ForthParser::parseBody(Value &stack) {

auto [s1, flag] = emitPopFlag(loc, stack);

if (cfStack.empty())
return emitError("UNTIL without matching BEGIN");
auto [tag, loopBlock] = cfStack.pop_back_val();
if (tag != CFTag::Dest)
return emitError("UNTIL without matching BEGIN");

auto *exitBlock = createStackBlock(parentRegion, loc);

Expand All @@ -829,7 +841,11 @@ LogicalResult ForthParser::parseBody(Value &stack) {

auto [s1, flag] = emitPopFlag(loc, stack);

if (cfStack.empty())
return emitError("WHILE without matching BEGIN");
auto [tag, loopBlock] = cfStack.pop_back_val();
if (tag != CFTag::Dest)
return emitError("WHILE without matching BEGIN");

auto *bodyBlock = createStackBlock(parentRegion, loc);
auto *exitBlock = createStackBlock(parentRegion, loc);
Expand All @@ -851,13 +867,21 @@ LogicalResult ForthParser::parseBody(Value &stack) {
consume();

// Pop loop header (from WHILE's re-push).
if (cfStack.empty())
return emitError("REPEAT without matching WHILE");
auto [destTag, loopBlock] = cfStack.pop_back_val();
if (destTag != CFTag::Dest)
return emitError("REPEAT without matching WHILE");

// Branch back to loop header.
builder.create<cf::BranchOp>(loc, loopBlock, ValueRange{stack});

// Pop exit block (from WHILE).
if (cfStack.empty())
return emitError("REPEAT without matching WHILE");
auto [origTag, exitBlock] = cfStack.pop_back_val();
if (origTag != CFTag::Orig)
return emitError("REPEAT without matching WHILE");

// Continue after exit.
builder.setInsertionPointToStart(exitBlock);
Expand Down Expand Up @@ -1007,6 +1031,11 @@ LogicalResult ForthParser::parseBody(Value &stack) {
}
}

if (!cfStack.empty()) {
cfStack.clear();
return emitError("unclosed control flow (missing THEN, REPEAT, or UNTIL?)");
}

return success();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: REPEAT without matching WHILE
\! kernel main
BEGIN BEGIN REPEAT
4 changes: 4 additions & 0 deletions test/Translation/Forth/begin-then-mismatch-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: THEN without matching IF
\! kernel main
BEGIN THEN
4 changes: 4 additions & 0 deletions test/Translation/Forth/else-without-if-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: ELSE without matching IF
\! kernel main
ELSE
4 changes: 4 additions & 0 deletions test/Translation/Forth/if-repeat-mismatch-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: REPEAT without matching WHILE
\! kernel main
1 IF REPEAT
4 changes: 4 additions & 0 deletions test/Translation/Forth/if-until-mismatch-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: UNTIL without matching BEGIN
\! kernel main
IF UNTIL
4 changes: 4 additions & 0 deletions test/Translation/Forth/repeat-without-while-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: REPEAT without matching WHILE
\! kernel main
REPEAT
4 changes: 4 additions & 0 deletions test/Translation/Forth/then-without-if-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: THEN without matching IF
\! kernel main
THEN
4 changes: 4 additions & 0 deletions test/Translation/Forth/unclosed-begin-while-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: unclosed control flow (missing THEN, REPEAT, or UNTIL?)
\! kernel main
BEGIN 1 WHILE 42
4 changes: 4 additions & 0 deletions test/Translation/Forth/unclosed-if-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: unclosed control flow (missing THEN, REPEAT, or UNTIL?)
\! kernel main
1 IF 42
4 changes: 4 additions & 0 deletions test/Translation/Forth/until-without-begin-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: UNTIL without matching BEGIN
\! kernel main
UNTIL
4 changes: 4 additions & 0 deletions test/Translation/Forth/while-without-begin-error.forth
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s
\ CHECK: WHILE without matching BEGIN
\! kernel main
WHILE