mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
reimplemented expression parsing as a separate parser (still only handling non-negative integers)
This commit is contained in:
parent
10cb9d3dab
commit
bceb7ebcbd
7 changed files with 184 additions and 34 deletions
|
@ -66,18 +66,11 @@ set(MISC_HEADER components/misc/fileops.hpp components/misc/slice_array.hpp
|
|||
components/misc/stringops.hpp)
|
||||
source_group(misc FILES ${MISC} ${MISC_HEADER})
|
||||
|
||||
set(COMPILER components/compiler/errorhandler.cpp
|
||||
components/compiler/fileparser.cpp components/compiler/scriptparser.cpp
|
||||
components/compiler/lineparser.cpp components/compiler/skipparser.cpp
|
||||
components/compiler/parser.cpp components/compiler/scanner.cpp
|
||||
components/compiler/streamerrorhandler.cpp
|
||||
components/compiler/locals.cpp components/compiler/literals.cpp
|
||||
components/compiler/output.cpp components/compiler/generator.cpp)
|
||||
file(GLOB COMPILER components/compiler/*.cpp)
|
||||
file(GLOB COMPILER_HEADER components/compiler/*.hpp)
|
||||
source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER})
|
||||
|
||||
set(INTERPRETER components/interpreter/runtime.cpp components/interpreter/interpreter.cpp
|
||||
components/interpreter/installopcodes.cpp)
|
||||
file(GLOB INTERPRETER components/interpreter/*.cpp)
|
||||
file(GLOB INTERPRETER_HEADER components/interpreter/*.hpp)
|
||||
source_group(interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER})
|
||||
|
||||
|
|
65
components/compiler/exprparser.cpp
Normal file
65
components/compiler/exprparser.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
|
||||
#include "exprparser.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "generator.hpp"
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
Literals& literals)
|
||||
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals)
|
||||
{}
|
||||
|
||||
bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
||||
{
|
||||
Operand operand;
|
||||
operand.mType = 'l';
|
||||
operand.mInteger = value;
|
||||
|
||||
mOperands.push_back (operand);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExprParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner)
|
||||
{
|
||||
return Parser::parseFloat (value, loc, scanner);
|
||||
}
|
||||
|
||||
bool ExprParser::parseName (const std::string& name, const TokenLoc& loc,
|
||||
Scanner& scanner)
|
||||
{
|
||||
return Parser::parseName (name, loc, scanner);
|
||||
}
|
||||
|
||||
bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner)
|
||||
{
|
||||
return Parser::parseKeyword (keyword, loc, scanner);
|
||||
}
|
||||
|
||||
bool ExprParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner)
|
||||
{
|
||||
return Parser::parseSpecial (code, loc, scanner);
|
||||
}
|
||||
|
||||
void ExprParser::reset()
|
||||
{
|
||||
mOperands.clear();
|
||||
}
|
||||
|
||||
char ExprParser::write (std::vector<Interpreter::Type_Code>& code)
|
||||
{
|
||||
if (mOperands.empty())
|
||||
throw std::logic_error ("empty expression");
|
||||
|
||||
Operand operand = mOperands[mOperands.size()-1];
|
||||
mOperands.clear();
|
||||
|
||||
Generator::pushInt (code, mLiterals, operand.mInteger);
|
||||
|
||||
return operand.mType;
|
||||
}
|
||||
}
|
||||
|
67
components/compiler/exprparser.hpp
Normal file
67
components/compiler/exprparser.hpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef COMPILER_EXPRPARSER_H_INCLUDED
|
||||
#define COMPILER_EXPRPARSER_H_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <components/interpreter/types.hpp>
|
||||
|
||||
#include "parser.hpp"
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
class Locals;
|
||||
class Literals;
|
||||
|
||||
class ExprParser : public Parser
|
||||
{
|
||||
struct Operand
|
||||
{
|
||||
char mType;
|
||||
int mInteger;
|
||||
float mFloat;
|
||||
};
|
||||
|
||||
Locals& mLocals;
|
||||
Literals& mLiterals;
|
||||
std::vector<Operand> mOperands;
|
||||
|
||||
public:
|
||||
|
||||
ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
Literals& literals);
|
||||
///< constructor
|
||||
|
||||
char getType() const;
|
||||
///< Return type of parsed expression ('l' integer, 'f' float)
|
||||
|
||||
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
|
||||
///< Handle an int token.
|
||||
/// \return fetch another token?
|
||||
|
||||
virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner);
|
||||
///< Handle a float token.
|
||||
/// \return fetch another token?
|
||||
|
||||
virtual bool parseName (const std::string& name, const TokenLoc& loc,
|
||||
Scanner& scanner);
|
||||
///< Handle a name token.
|
||||
/// \return fetch another token?
|
||||
|
||||
virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner);
|
||||
///< Handle a keyword token.
|
||||
/// \return fetch another token?
|
||||
|
||||
virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner);
|
||||
///< Handle a special character token.
|
||||
/// \return fetch another token?
|
||||
|
||||
void reset();
|
||||
///< Reset parser to clean state.
|
||||
|
||||
char write (std::vector<Interpreter::Type_Code>& code);
|
||||
///< Generate code for parsed expression.
|
||||
/// \return Type ('l': integer, 'f': float)
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2,6 +2,8 @@
|
|||
#include "generator.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include "literals.hpp"
|
||||
|
||||
|
@ -63,6 +65,11 @@ namespace
|
|||
code.push_back (segment5 (3));
|
||||
}
|
||||
|
||||
void opFloatToInt (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
assert (0); // not implemented
|
||||
}
|
||||
|
||||
void opStoreLocalShort (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (0));
|
||||
|
@ -83,20 +90,36 @@ namespace Compiler
|
|||
{
|
||||
namespace Generator
|
||||
{
|
||||
void assignIntToLocal (CodeContainer& code, Literals& literals, char localType,
|
||||
int localIndex, int value)
|
||||
void pushInt (CodeContainer& code, Literals& literals, int value)
|
||||
{
|
||||
int index = literals.addInteger (value);
|
||||
|
||||
opPushInt (code, localIndex);
|
||||
int index = literals.addInteger (value);
|
||||
opPushInt (code, index);
|
||||
opFetchIntLiteral (code);
|
||||
opFetchIntLiteral (code);
|
||||
}
|
||||
|
||||
void assignToLocal (CodeContainer& code, char localType,
|
||||
int localIndex, const CodeContainer& value, char valueType)
|
||||
{
|
||||
opPushInt (code, localIndex);
|
||||
|
||||
std::copy (value.begin(), value.end(), std::back_inserter (code));
|
||||
|
||||
if (localType!=valueType)
|
||||
{
|
||||
if (localType=='f' && valueType=='l')
|
||||
{
|
||||
opIntToFloat (code);
|
||||
}
|
||||
else if ((localType=='l' || localType=='s') && valueType=='f')
|
||||
{
|
||||
opFloatToInt (code);
|
||||
}
|
||||
}
|
||||
|
||||
switch (localType)
|
||||
{
|
||||
case 'f':
|
||||
|
||||
opIntToFloat (code);
|
||||
opStoreLocalFloat (code);
|
||||
break;
|
||||
|
||||
|
@ -113,7 +136,7 @@ namespace Compiler
|
|||
default:
|
||||
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@ namespace Compiler
|
|||
namespace Generator
|
||||
{
|
||||
typedef std::vector<Interpreter::Type_Code> CodeContainer;
|
||||
|
||||
void assignIntToLocal (CodeContainer& code, Literals& literals, char localType,
|
||||
int localIndex, int value);
|
||||
|
||||
void pushInt (CodeContainer& code, Literals& literals, int value);
|
||||
|
||||
void assignToLocal (CodeContainer& code, char localType,
|
||||
int localIndex, const CodeContainer& value, char valueType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,22 +13,11 @@ namespace Compiler
|
|||
LineParser::LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
Literals& literals, std::vector<Interpreter::Type_Code>& code)
|
||||
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals), mCode (code),
|
||||
mState (BeginState)
|
||||
mState (BeginState), mExprParser (errorHandler, context, locals, literals)
|
||||
{}
|
||||
|
||||
bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
||||
{
|
||||
if (mState==SetLocalToState)
|
||||
{
|
||||
Generator::assignIntToLocal (mCode, mLiterals, mLocals.getType (mName),
|
||||
mLocals.getIndex (mName), value);
|
||||
|
||||
mState = EndState;
|
||||
mName.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
return Parser::parseInt (value, loc, scanner);
|
||||
}
|
||||
|
||||
|
@ -104,7 +93,16 @@ namespace Compiler
|
|||
}
|
||||
else if (mState==SetLocalVarState && keyword==Scanner::K_to)
|
||||
{
|
||||
mState = SetLocalToState;
|
||||
mExprParser.reset();
|
||||
scanner.scan (mExprParser);
|
||||
|
||||
std::vector<Interpreter::Type_Code> code;
|
||||
char type = mExprParser.write (code);
|
||||
|
||||
Generator::assignToLocal (mCode, mLocals.getType (mName),
|
||||
mLocals.getIndex (mName), code, type);
|
||||
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <components/interpreter/types.hpp>
|
||||
|
||||
#include "parser.hpp"
|
||||
#include "exprparser.hpp"
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
|
@ -29,6 +30,7 @@ namespace Compiler
|
|||
std::vector<Interpreter::Type_Code>& mCode;
|
||||
State mState;
|
||||
std::string mName;
|
||||
ExprParser mExprParser;
|
||||
|
||||
public:
|
||||
|
||||
|
|
Loading…
Reference in a new issue