forked from mirror/openmw-tes3mp
implemented while loops
This commit is contained in:
parent
69342f320d
commit
46fab68d44
3 changed files with 74 additions and 3 deletions
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "scanner.hpp"
|
#include "scanner.hpp"
|
||||||
#include "generator.hpp"
|
#include "generator.hpp"
|
||||||
|
@ -36,6 +37,14 @@ namespace Compiler
|
||||||
mState = IfEndState;
|
mState = IfEndState;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (keyword==Scanner::K_while)
|
||||||
|
{
|
||||||
|
mExprParser.reset();
|
||||||
|
scanner.scan (mExprParser);
|
||||||
|
|
||||||
|
mState = WhileEndState;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (mState==IfBodyState || mState==IfElseifBodyState || mState==IfElseBodyState)
|
else if (mState==IfBodyState || mState==IfElseifBodyState || mState==IfElseBodyState)
|
||||||
{
|
{
|
||||||
|
@ -123,6 +132,61 @@ namespace Compiler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mState==WhileBodyState)
|
||||||
|
{
|
||||||
|
if (keyword==Scanner::K_endwhile)
|
||||||
|
{
|
||||||
|
Codes loop;
|
||||||
|
|
||||||
|
Codes expr;
|
||||||
|
mExprParser.append (expr);
|
||||||
|
|
||||||
|
Generator::jump (loop, -mCodeBlock.size()-expr.size());
|
||||||
|
|
||||||
|
std::copy (expr.begin(), expr.end(), std::back_inserter (mCode));
|
||||||
|
|
||||||
|
Codes skip;
|
||||||
|
|
||||||
|
Generator::jumpOnZero (skip, mCodeBlock.size()+loop.size()+1);
|
||||||
|
|
||||||
|
std::copy (skip.begin(), skip.end(), std::back_inserter (mCode));
|
||||||
|
|
||||||
|
std::copy (mCodeBlock.begin(), mCodeBlock.end(), std::back_inserter (mCode));
|
||||||
|
|
||||||
|
Codes loop2;
|
||||||
|
|
||||||
|
Generator::jump (loop2, -mCodeBlock.size()-expr.size()-skip.size());
|
||||||
|
|
||||||
|
if (loop.size()!=loop2.size())
|
||||||
|
throw std::logic_error (
|
||||||
|
"internal compiler error: failed to generate a while loop");
|
||||||
|
|
||||||
|
std::copy (loop2.begin(), loop2.end(), std::back_inserter (mCode));
|
||||||
|
|
||||||
|
mState = WhileEndwhileState;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (keyword==Scanner::K_if || keyword==Scanner::K_while)
|
||||||
|
{
|
||||||
|
// nested
|
||||||
|
ControlParser parser (getErrorHandler(), getContext(), mLocals, mLiterals);
|
||||||
|
|
||||||
|
if (parser.parseKeyword (keyword, loc, scanner))
|
||||||
|
scanner.scan (parser);
|
||||||
|
|
||||||
|
parser.appendCode (mCodeBlock);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLineParser.reset();
|
||||||
|
if (mLineParser.parseKeyword (keyword, loc, scanner))
|
||||||
|
scanner.scan (mLineParser);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Parser::parseKeyword (keyword, loc, scanner);
|
return Parser::parseKeyword (keyword, loc, scanner);
|
||||||
}
|
}
|
||||||
|
@ -137,12 +201,17 @@ namespace Compiler
|
||||||
case IfElseifEndState: mState = IfElseifBodyState; return true;
|
case IfElseifEndState: mState = IfElseifBodyState; return true;
|
||||||
case IfElseEndState: mState = IfElseBodyState; return true;
|
case IfElseEndState: mState = IfElseBodyState; return true;
|
||||||
|
|
||||||
|
case WhileEndState: mState = WhileBodyState; return true;
|
||||||
|
|
||||||
case IfBodyState:
|
case IfBodyState:
|
||||||
case IfElseifBodyState:
|
case IfElseifBodyState:
|
||||||
case IfElseBodyState:
|
case IfElseBodyState:
|
||||||
|
case WhileBodyState:
|
||||||
|
|
||||||
return true; // empty line
|
return true; // empty line
|
||||||
|
|
||||||
case IfEndifState:
|
case IfEndifState:
|
||||||
|
case WhileEndwhileState:
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,12 @@ namespace Compiler
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
StartState,
|
StartState,
|
||||||
IfState, IfEndState, IfBodyState,
|
IfEndState, IfBodyState,
|
||||||
IfElseifEndState, IfElseifBodyState,
|
IfElseifEndState, IfElseifBodyState,
|
||||||
IfElseEndState, IfElseBodyState,
|
IfElseEndState, IfElseBodyState,
|
||||||
IfEndifState
|
IfEndifState,
|
||||||
|
WhileEndState, WhileBodyState,
|
||||||
|
WhileEndwhileState
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Interpreter::Type_Code> Codes;
|
typedef std::vector<Interpreter::Type_Code> Codes;
|
||||||
|
|
|
@ -415,7 +415,7 @@ namespace Compiler
|
||||||
if (offset>0)
|
if (offset>0)
|
||||||
opJumpForward (code, offset);
|
opJumpForward (code, offset);
|
||||||
else if (offset<0)
|
else if (offset<0)
|
||||||
opJumpBackward (code, offset);
|
opJumpBackward (code, -offset);
|
||||||
else
|
else
|
||||||
throw std::logic_error ("inifite loop");
|
throw std::logic_error ("inifite loop");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue