Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
3.6 kB · 127 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128#include "declarationparser.hpp"
#include <components/misc/strings/lower.hpp>
#include "context.hpp"#include "errorhandler.hpp"#include "extensions.hpp"#include "locals.hpp"#include "scanner.hpp"#include "skipparser.hpp"
Compiler::DeclarationParser::DeclarationParser(ErrorHandler& errorHandler, const Context& context, Locals& locals) : Parser(errorHandler, context) , mLocals(locals) , mState(State_Begin) , mType(0){}
bool Compiler::DeclarationParser::parseName(const std::string& name, const TokenLoc& loc, Scanner& scanner){ if (mState == State_Name) { std::string name2 = ::Misc::StringUtils::lowerCase(name);
char type = mLocals.getType(name2);
if (type != ' ') getErrorHandler().warning("Local variable re-declaration", loc); else mLocals.declare(mType, name2);
mState = State_End; return true; } else if (mState == State_End) { getErrorHandler().warning("Extra text after local variable declaration", loc); SkipParser skip(getErrorHandler(), getContext()); scanner.scan(skip); return false; }
return Parser::parseName(name, loc, scanner);}
bool Compiler::DeclarationParser::parseKeyword(int keyword, const TokenLoc& loc, Scanner& scanner){ if (mState == State_Begin) { switch (keyword) { case Scanner::K_short: mType = 's'; break; case Scanner::K_long: mType = 'l'; break; case Scanner::K_float: mType = 'f'; break; default: mType = 0; }
if (mType) { mState = State_Name; return true; } } else if (mState == State_Name) { // allow keywords to be used as local variable names. MW script compiler, you suck! if (const Extensions* extensions = getContext().getExtensions()) { std::string argumentType; bool hasExplicit = false; char returnType; if (extensions->isFunction(keyword, returnType, argumentType, hasExplicit)) getErrorHandler().warning("Local variable declaration shadows a function", loc); }
return parseName(loc.mLiteral, loc, scanner); } else if (mState == State_End) { getErrorHandler().warning("Extra text after local variable declaration", loc); SkipParser skip(getErrorHandler(), getContext()); scanner.scan(skip); return false; }
return Parser::parseKeyword(keyword, loc, scanner);}
bool Compiler::DeclarationParser::parseSpecial(int code, const TokenLoc& loc, Scanner& scanner){ if (mState == State_End) { if (code != Scanner::S_newline) { getErrorHandler().warning("Extra text after local variable declaration", loc); SkipParser skip(getErrorHandler(), getContext()); scanner.scan(skip); } return false; }
return Parser::parseSpecial(code, loc, scanner);}
bool Compiler::DeclarationParser::parseInt(int value, const TokenLoc& loc, Scanner& scanner){ if (mState == State_Name) { // Allow integers to be used as variable names getErrorHandler().warning("Integer is used as a local variable name", loc); return parseName(loc.mLiteral, loc, scanner); } return Parser::parseInt(value, loc, scanner);}
void Compiler::DeclarationParser::reset(){ mState = State_Begin;}