added storage class for local variable declarations; added checks for variable re-declaration

pull/7/head
Marc Zinnschlag 15 years ago
parent 21e0182ae2
commit 0cfeab622d

@ -70,7 +70,8 @@ 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/streamerrorhandler.cpp
components/compiler/locals.cpp)
file(GLOB COMPILER_HEADER components/compiler/*.hpp)
source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER})

@ -9,7 +9,7 @@ namespace Compiler
{
FileParser::FileParser (ErrorHandler& errorHandler, Context& context)
: Parser (errorHandler, context),
mScriptParser (errorHandler, context, true),
mScriptParser (errorHandler, context, mLocals, true),
mState (BeginState)
{}
@ -88,6 +88,7 @@ namespace Compiler
mState = BeginState;
mName.clear();
mScriptParser.reset();
mLocals.clear();
}
}

@ -3,6 +3,7 @@
#include "parser.hpp"
#include "scriptparser.hpp"
#include "locals.hpp"
namespace Compiler
{
@ -19,6 +20,7 @@ namespace Compiler
ScriptParser mScriptParser;
State mState;
std::string mName;
Locals mLocals;
public:

@ -7,11 +7,12 @@
#include "context.hpp"
#include "errorhandler.hpp"
#include "skipparser.hpp"
#include "locals.hpp"
namespace Compiler
{
LineParser::LineParser (ErrorHandler& errorHandler, Context& context)
: Parser (errorHandler, context), mState (BeginState)
LineParser::LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals)
: Parser (errorHandler, context), mLocals (locals), mState (BeginState)
{}
bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
@ -37,7 +38,20 @@ namespace Compiler
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;
mLocals.declare (mState==ShortState ? 's' : (mState==LongState ? 'l' : 'f'),
name);
mState = EndState;
return true;
}

@ -5,6 +5,8 @@
namespace Compiler
{
class Locals;
/// \brief Line parser, to be used in console scripts and as part of ScriptParser
class LineParser : public Parser
@ -15,12 +17,13 @@ namespace Compiler
ShortState, LongState, FloatState,
EndState
};
Locals& mLocals;
State mState;
public:
LineParser (ErrorHandler& errorHandler, Context& context);
LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals);
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
///< Handle an int token.

@ -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();
}
}

@ -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
{
ScriptParser::ScriptParser (ErrorHandler& errorHandler, Context& context, bool end)
: Parser (errorHandler, context), mLineParser (errorHandler, context), mEnd (end)
ScriptParser::ScriptParser (ErrorHandler& errorHandler, Context& context,
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,

@ -6,17 +6,21 @@
namespace Compiler
{
class Locals;
// Script parser, to be used in dialogue scripts and as part of FileParser
class ScriptParser : public Parser
{
LineParser mLineParser;
Locals& mLocals;
bool mEnd;
public:
/// \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,
Scanner& scanner);

Loading…
Cancel
Save