From c2886e2532745e4a5a74f335738c75d6d629d779 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sat, 16 Oct 2021 10:49:11 +0200 Subject: [PATCH] Fix infinite for(;;) loop --- oscar64/InterCode.cpp | 14 +++++++++++++- oscar64/Parser.cpp | 12 ++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 218d266..ac2a3ce 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -1856,6 +1856,18 @@ void InterCodeBasicBlock::CollectEntries(void) } } +static bool IsInfiniteLoop(const InterCodeBasicBlock* block) +{ + const InterCodeBasicBlock* nblock = block; + while (nblock->mTrueJump && !nblock->mFalseJump) + { + nblock = nblock->mTrueJump; + if (nblock == block) + return true; + } + return false; +} + void InterCodeBasicBlock::GenerateTraces(void) { int i; @@ -1884,7 +1896,7 @@ void InterCodeBasicBlock::GenerateTraces(void) if (mFalseJump) mFalseJump->mNumEntries++; } - else if (mTrueJump && !mFalseJump && ((mTrueJump->mInstructions.Size() < 10 && mTrueJump->mInstructions.Size() > 1) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead) + else if (mTrueJump && !mFalseJump && ((mTrueJump->mInstructions.Size() < 10 && mTrueJump->mInstructions.Size() > 1) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead && !IsInfiniteLoop(mTrueJump)) { mTrueJump->mNumEntries--; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 5c0a632..bad405c 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1721,16 +1721,24 @@ Expression* Parser::ParseStatement(void) exp = new Expression(mScanner->mLocation, EX_FOR); exp->mLeft = new Expression(mScanner->mLocation, EX_SEQUENCE); exp->mLeft->mLeft = new Expression(mScanner->mLocation, EX_SEQUENCE); - exp->mLeft->mRight = ParseExpression(); + + // Assignment + if (mScanner->mToken != TK_SEMICOLON) + exp->mLeft->mRight = ParseExpression(); if (mScanner->mToken == TK_SEMICOLON) mScanner->NextToken(); else mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected"); - exp->mLeft->mLeft->mLeft = ParseExpression(); + + // Condition + if (mScanner->mToken != TK_SEMICOLON) + exp->mLeft->mLeft->mLeft = ParseExpression(); if (mScanner->mToken == TK_SEMICOLON) mScanner->NextToken(); else mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected"); + + // Iteration if (mScanner->mToken != TK_CLOSE_PARENTHESIS) exp->mLeft->mLeft->mRight = ParseExpression(); if (mScanner->mToken == TK_CLOSE_PARENTHESIS)