Skip to content

Commit

Permalink
Fixed issue JoeStrout#2 (break before else).
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeStrout committed Jun 11, 2019
1 parent 53dedd1 commit 1caa4f1
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 53 deletions.
4 changes: 4 additions & 0 deletions MiniScript-Release-Notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,7 @@ Version 1.4: Jun 09, 2019

- Host apps can now set an "assignment override function" on any ValMap, allowing a bit of native code to run when user code assigns a value in that map.


Version 1.4.1 (not yet released)
=============
- Fixed a bug that would cause the `break` keyword to throw a compiler error when used before an `else` block {GitHub issue #2}.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "src/MiniScript/MiniscriptParser.cpp"
timestampString = "580045984.968514"
timestampString = "581981021.463745"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "165"
endingLineNumber = "165"
startingLineNumber = "168"
endingLineNumber = "168"
landmarkName = "Parser::ParseStatement(Lexer tokens, bool allowExtra)"
landmarkType = "7">
</BreakpointContent>
Expand All @@ -42,11 +42,11 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "src/MiniScript/MiniscriptParser.cpp"
timestampString = "580045984.968514"
timestampString = "581981021.468098"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "390"
endingLineNumber = "390"
startingLineNumber = "393"
endingLineNumber = "393"
landmarkName = "Parser::ParseFunction(Lexer tokens, bool asLval, bool statementStart)"
landmarkType = "7">
</BreakpointContent>
Expand Down Expand Up @@ -90,7 +90,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.62546"
timestampString = "581981021.888263"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -105,7 +105,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.627781"
timestampString = "581981021.890447"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -120,7 +120,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.629953"
timestampString = "581981021.892839"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -135,7 +135,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.6318949"
timestampString = "581981021.895345"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -150,7 +150,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.633387"
timestampString = "581981021.897827"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -165,7 +165,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.634895"
timestampString = "581981021.900439"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -180,7 +180,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.6364321"
timestampString = "581981021.903125"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -195,7 +195,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.637979"
timestampString = "581981021.90565"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -210,7 +210,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.640102"
timestampString = "581981021.908347"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -225,7 +225,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.642485"
timestampString = "581981021.9108911"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -240,7 +240,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.644118"
timestampString = "581981021.913781"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand All @@ -255,7 +255,7 @@
moduleName = "MiniScript"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/jstrout/Documents/svnrepo/stroutandsons/MiniScript/MiniScript-cpp/src/MiniScript/SimpleVector.h"
timestampString = "581461604.6455491"
timestampString = "581981021.916788"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "193"
Expand Down
31 changes: 17 additions & 14 deletions MiniScript-cpp/src/MiniScript/MiniscriptParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,27 @@ namespace MiniScript {
return result;
}

void ParseState::Patch(String keywordFound, String alsoPatch, long reservingLines) {
// Start by finding the matching backpatch.
long idx;
for (idx = backpatches.Count() - 1; idx >= 0; idx--) {
if (backpatches[idx].waitingFor == keywordFound) break;
if (alsoPatch.empty() or backpatches[idx].waitingFor != alsoPatch) {
void ParseState::Patch(String keywordFound, bool alsoBreak, long reservingLines) {
Value target = code.Count() + reservingLines;
bool done = false;
for (long idx = backpatches.Count() - 1; idx >= 0 and not done; idx--) {
bool patchIt = false;
if (backpatches[idx].waitingFor == keywordFound) patchIt = done = true;
else if (backpatches[idx].waitingFor == "break") {
// Not the expected keyword, but "break"; this is always OK,
// but we may or may not patch it depending on the call.
patchIt = alsoBreak;
} else {
// Not the expected patch, and not "break"; we have a mismatched block start/end.
throw new CompilerException("'" + keywordFound + "' skips expected '" + backpatches[idx].waitingFor + "'");
}
if (patchIt) {
code[backpatches[idx].lineNum].rhsA = target;
backpatches.RemoveAt(idx);
}
}
// Make sure we found one...
if (idx < 0) throw new CompilerException("'" + keywordFound + "' without matching block starter");

// Now, patch all from there to the end.
Value target = code.Count() + reservingLines;
for (long i = backpatches.Count() - 1; i >= idx; i--) {
code[backpatches[i].lineNum].rhsA = target;
}
backpatches.RemoveRange(idx, backpatches.Count() - idx);
if (!done) throw new CompilerException("'" + keywordFound + "' without matching block starter");
}

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions MiniScript-cpp/src/MiniScript/MiniscriptParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace MiniScript {
/// <param name="keywordFound">Keyword found.</param>
/// <param name="reservingLines">Extra lines (after the current position) to patch to.</param>
void Patch(String keywordFound, long reservingLines=0) {
Patch(keywordFound, String(), reservingLines);
Patch(keywordFound, false, reservingLines);
}

/// <summary>
Expand All @@ -89,9 +89,9 @@ namespace MiniScript {
/// matching backpatch (and any after it) to the current code end.
/// </summary>
/// <param name="keywordFound">Keyword found.</param>
/// <param name="alsoPatch">Keyword to also patch, if we see it before keywordFound.</param>
/// <param name="alsoBreak">If true, also patch "break"; otherwise skip it.</param>
/// <param name="reservingLines">Extra lines (after the current position) to patch to.</param>
void Patch(String keywordFound, String alsoPatch, long reservingLines=0);
void Patch(String keywordFound, bool alsoBreak, long reservingLines=0);

/// <summary>
/// Patches up all the branches for a single open if block. That includes
Expand Down
40 changes: 22 additions & 18 deletions MiniScript-cs/MiniscriptParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public JumpPoint CloseJumpPoint(string keyword) {
/// <param name="keywordFound">Keyword found.</param>
/// <param name="reservingLines">Extra lines (after the current position) to patch to.</param>
public void Patch(string keywordFound, int reservingLines=0) {
Patch(keywordFound, null, reservingLines);
Patch(keywordFound, false, reservingLines);
}

/// <summary>
Expand All @@ -81,26 +81,29 @@ public void Patch(string keywordFound, int reservingLines=0) {
/// matching backpatch (and any after it) to the current code end.
/// </summary>
/// <param name="keywordFound">Keyword found.</param>
/// <param name="alsoPatch">Keyword to also patch, if we see it before keywordFound.</param>
/// <param name="alsoBreak">If true, also patch "break"; otherwise skip it.</param>
/// <param name="reservingLines">Extra lines (after the current position) to patch to.</param>
public void Patch(string keywordFound, string alsoPatch, int reservingLines=0) {
// Start by finding the matching backpatch.
int idx;
for (idx = backpatches.Count - 1; idx >= 0; idx--) {
if (backpatches[idx].waitingFor == keywordFound) break;
if (alsoPatch == null || backpatches[idx].waitingFor != alsoPatch) {
public void Patch(string keywordFound, bool alsoBreak, int reservingLines=0) {
Value target = TAC.Num(code.Count + reservingLines);
bool done = false;
for (int idx = backpatches.Count - 1; idx >= 0 && !done; idx--) {
bool patchIt = false;
if (backpatches[idx].waitingFor == keywordFound) patchIt = done = true;
else if (backpatches[idx].waitingFor == "break") {
// Not the expected keyword, but "break"; this is always OK,
// but we may or may not patch it depending on the call.
patchIt = alsoBreak;
} else {
// Not the expected patch, and not "break"; we have a mismatched block start/end.
throw new CompilerException("'" + keywordFound + "' skips expected '" + backpatches[idx].waitingFor + "'");
}
if (patchIt) {
code[backpatches[idx].lineNum].rhsA = target;
backpatches.RemoveAt(idx);
}
}
// Make sure we found one...
if (idx < 0) throw new CompilerException("'" + keywordFound + "' without matching block starter");

// Now, patch all from there to the end.
Value target = TAC.Num(code.Count + reservingLines);
for (int i = backpatches.Count - 1; i >= idx; i--) {
code[backpatches[i].lineNum].rhsA = target;
}
backpatches.RemoveRange(idx, backpatches.Count - idx);
if (!done) throw new CompilerException("'" + keywordFound + "' without matching block starter");
}

/// <summary>
Expand Down Expand Up @@ -352,7 +355,7 @@ void ParseStatement(Lexer tokens, bool allowExtra=false) {
output.Add(new TAC.Line(null, TAC.Line.Op.GotoA, TAC.Num(jump.lineNum)));
// Then, backpatch the open "while" branch to here, right after the loop.
// And also patch any "break" branches emitted after that point.
output.Patch(keyword, "break");
output.Patch(keyword, true);
}
break;
case "for":
Expand Down Expand Up @@ -396,7 +399,7 @@ void ParseStatement(Lexer tokens, bool allowExtra=false) {
output.Add(new TAC.Line(null, TAC.Line.Op.GotoA, TAC.Num(jump.lineNum)));
// Then, backpatch the open "for" branch to here, right after the loop.
// And also patch any "break" branches emitted after that point.
output.Patch(keyword, "break");
output.Patch(keyword, true);
}
break;
case "break":
Expand Down Expand Up @@ -1068,6 +1071,7 @@ public static void RunUnitTests() {
TestValidParse("print true");
TestValidParse("f = function(x)\nprint x\nend function\nf 42");
TestValidParse("myList = [1, null, 3]");
TestValidParse("while true; if true then; break; else; print 1; end if; end while");
}
}
}
Expand Down

0 comments on commit 1caa4f1

Please sign in to comment.