mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +00:00
added storage class for local variable declarations; added checks for variable re-declaration
This commit is contained in:
parent
21e0182ae2
commit
0cfeab622d
9 changed files with 139 additions and 9 deletions
|
@ -70,7 +70,8 @@ set(COMPILER components/compiler/errorhandler.cpp
|
||||||
components/compiler/fileparser.cpp components/compiler/scriptparser.cpp
|
components/compiler/fileparser.cpp components/compiler/scriptparser.cpp
|
||||||
components/compiler/lineparser.cpp components/compiler/skipparser.cpp
|
components/compiler/lineparser.cpp components/compiler/skipparser.cpp
|
||||||
components/compiler/parser.cpp components/compiler/scanner.cpp
|
components/compiler/parser.cpp components/compiler/scanner.cpp
|
||||||
components/compiler/streamerrorhandler.cpp)
|
components/compiler/streamerrorhandler.cpp
|
||||||
|
components/compiler/locals.cpp)
|
||||||
file(GLOB COMPILER_HEADER components/compiler/*.hpp)
|
file(GLOB COMPILER_HEADER components/compiler/*.hpp)
|
||||||
source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER})
|
source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER})
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
FileParser::FileParser (ErrorHandler& errorHandler, Context& context)
|
FileParser::FileParser (ErrorHandler& errorHandler, Context& context)
|
||||||
: Parser (errorHandler, context),
|
: Parser (errorHandler, context),
|
||||||
mScriptParser (errorHandler, context, true),
|
mScriptParser (errorHandler, context, mLocals, true),
|
||||||
mState (BeginState)
|
mState (BeginState)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ namespace Compiler
|
||||||
mState = BeginState;
|
mState = BeginState;
|
||||||
mName.clear();
|
mName.clear();
|
||||||
mScriptParser.reset();
|
mScriptParser.reset();
|
||||||
|
mLocals.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "parser.hpp"
|
#include "parser.hpp"
|
||||||
#include "scriptparser.hpp"
|
#include "scriptparser.hpp"
|
||||||
|
#include "locals.hpp"
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
@ -19,6 +20,7 @@ namespace Compiler
|
||||||
ScriptParser mScriptParser;
|
ScriptParser mScriptParser;
|
||||||
State mState;
|
State mState;
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
Locals mLocals;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,12 @@
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
#include "errorhandler.hpp"
|
#include "errorhandler.hpp"
|
||||||
#include "skipparser.hpp"
|
#include "skipparser.hpp"
|
||||||
|
#include "locals.hpp"
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
LineParser::LineParser (ErrorHandler& errorHandler, Context& context)
|
LineParser::LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals)
|
||||||
: Parser (errorHandler, context), mState (BeginState)
|
: Parser (errorHandler, context), mLocals (locals), mState (BeginState)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
@ -37,7 +38,20 @@ namespace Compiler
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char type = mLocals.getType (name);
|
||||||
|
|
||||||
|
if (type!=' ')
|
||||||
|
{
|
||||||
|
getErrorHandler().error ("can't re-declare local variable", loc);
|
||||||
|
SkipParser skip (getErrorHandler(), getContext());
|
||||||
|
scanner.scan (skip);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "declaring local variable: " << name << std::endl;
|
std::cout << "declaring local variable: " << name << std::endl;
|
||||||
|
mLocals.declare (mState==ShortState ? 's' : (mState==LongState ? 'l' : 'f'),
|
||||||
|
name);
|
||||||
|
|
||||||
mState = EndState;
|
mState = EndState;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
class Locals;
|
||||||
|
|
||||||
/// \brief Line parser, to be used in console scripts and as part of ScriptParser
|
/// \brief Line parser, to be used in console scripts and as part of ScriptParser
|
||||||
|
|
||||||
class LineParser : public Parser
|
class LineParser : public Parser
|
||||||
|
@ -16,11 +18,12 @@ namespace Compiler
|
||||||
EndState
|
EndState
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Locals& mLocals;
|
||||||
State mState;
|
State mState;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LineParser (ErrorHandler& errorHandler, Context& context);
|
LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals);
|
||||||
|
|
||||||
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
|
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
|
||||||
///< Handle an int token.
|
///< Handle an int token.
|
||||||
|
|
67
components/compiler/locals.cpp
Normal file
67
components/compiler/locals.cpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
#include "locals.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace Compiler
|
||||||
|
{
|
||||||
|
const std::vector<std::string>& Locals::get (char type) const
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 's': return mShorts;
|
||||||
|
case 'l': return mLongs;
|
||||||
|
case 'f': return mFloats;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::logic_error ("unknown variable type");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Locals::search (char type, const std::string& name) const
|
||||||
|
{
|
||||||
|
const std::vector<std::string>& collection = get (type);
|
||||||
|
|
||||||
|
return std::find (collection.begin(), collection.end(), name)!=collection.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string>& Locals::get (char type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 's': return mShorts;
|
||||||
|
case 'l': return mLongs;
|
||||||
|
case 'f': return mFloats;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::logic_error ("unknown variable type");
|
||||||
|
}
|
||||||
|
|
||||||
|
char Locals::getType (const std::string& name) const
|
||||||
|
{
|
||||||
|
if (search ('s', name))
|
||||||
|
return 's';
|
||||||
|
|
||||||
|
if (search ('l', name))
|
||||||
|
return 'l';
|
||||||
|
|
||||||
|
if (search ('f', name))
|
||||||
|
return 'f';
|
||||||
|
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
void Locals::declare (char type, const std::string& name)
|
||||||
|
{
|
||||||
|
get (type).push_back (name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Locals::clear()
|
||||||
|
{
|
||||||
|
get ('s').clear();
|
||||||
|
get ('l').clear();
|
||||||
|
get ('f').clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
36
components/compiler/locals.hpp
Normal file
36
components/compiler/locals.hpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef COMPILER_LOCALS_H_INCLUDED
|
||||||
|
#define COMPILER_LOCALS_H_INCLUDED
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Compiler
|
||||||
|
{
|
||||||
|
/// \brief Local variable declarations
|
||||||
|
|
||||||
|
class Locals
|
||||||
|
{
|
||||||
|
std::vector<std::string> mShorts;
|
||||||
|
std::vector<std::string> mLongs;
|
||||||
|
std::vector<std::string> mFloats;
|
||||||
|
|
||||||
|
const std::vector<std::string>& get (char type) const;
|
||||||
|
|
||||||
|
bool search (char type, const std::string& name) const;
|
||||||
|
|
||||||
|
std::vector<std::string>& get (char type);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
char getType (const std::string& name) const;
|
||||||
|
///< 's': short, 'l': long, 'f': float, ' ': does not exist.
|
||||||
|
|
||||||
|
void declare (char type, const std::string& name);
|
||||||
|
///< declares a variable.
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
///< remove all declarations.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,8 +5,10 @@
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
ScriptParser::ScriptParser (ErrorHandler& errorHandler, Context& context, bool end)
|
ScriptParser::ScriptParser (ErrorHandler& errorHandler, Context& context,
|
||||||
: Parser (errorHandler, context), mLineParser (errorHandler, context), mEnd (end)
|
Locals& locals, bool end)
|
||||||
|
: Parser (errorHandler, context), mLineParser (errorHandler, context, locals),
|
||||||
|
mLocals (locals), mEnd (end)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool ScriptParser::parseName (const std::string& name, const TokenLoc& loc,
|
bool ScriptParser::parseName (const std::string& name, const TokenLoc& loc,
|
||||||
|
|
|
@ -6,17 +6,21 @@
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
class Locals;
|
||||||
|
|
||||||
// Script parser, to be used in dialogue scripts and as part of FileParser
|
// Script parser, to be used in dialogue scripts and as part of FileParser
|
||||||
|
|
||||||
class ScriptParser : public Parser
|
class ScriptParser : public Parser
|
||||||
{
|
{
|
||||||
LineParser mLineParser;
|
LineParser mLineParser;
|
||||||
|
Locals& mLocals;
|
||||||
bool mEnd;
|
bool mEnd;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// \param end of script is marked by end keyword.
|
/// \param end of script is marked by end keyword.
|
||||||
ScriptParser (ErrorHandler& errorHandler, Context& context, bool end = false);
|
ScriptParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||||
|
bool end = false);
|
||||||
|
|
||||||
virtual bool parseName (const std::string& name, const TokenLoc& loc,
|
virtual bool parseName (const std::string& name, const TokenLoc& loc,
|
||||||
Scanner& scanner);
|
Scanner& scanner);
|
||||||
|
|
Loading…
Reference in a new issue