Issue #181: Member variable access in expressions; error reporting fix for the previous commit

pull/21/head
Marc Zinnschlag 13 years ago
parent 6a89d76321
commit 6c5b21fa42

@ -5,6 +5,8 @@
#include "../mwworld/world.hpp"
#include "scriptmanager.hpp"
namespace MWScript
{
CompilerContext::CompilerContext (Type type)
@ -21,6 +23,18 @@ namespace MWScript
return MWBase::Environment::get().getWorld()->getGlobalVariableType (name);
}
char CompilerContext::getMemberType (const std::string& name, const std::string& id) const
{
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtr (id, false);
std::string script = MWWorld::Class::get (ptr).getScript (ptr);
if (script.empty())
return ' ';
return MWBase::Environment::get().getScriptManager()->getLocals (script).getType (name);
}
bool CompilerContext::isId (const std::string& name) const
{
return

@ -30,6 +30,9 @@ namespace MWScript
/// 'l: long, 's': short, 'f': float, ' ': does not exist.
virtual char getGlobalType (const std::string& name) const;
virtual char getMemberType (const std::string& name, const std::string& id) const;
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
virtual bool isId (const std::string& name) const;
///< Does \a name match an ID, that can be referenced?
};

@ -50,6 +50,7 @@ namespace MWScript
catch (const Compiler::SourceException&)
{
// error has already been reported via error handler
Success = false;
}
catch (const std::exception& error)
{
@ -146,6 +147,9 @@ namespace MWScript
{
if (!compile (name))
{
/// \todo Handle case of cyclic member variable access. Currently this could look up
/// the whole application in an endless recursion.
// failed -> ignore script from now on.
std::vector<Interpreter::Type_Code> empty;
mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));

@ -10,33 +10,35 @@ namespace Compiler
class Context
{
const Extensions *mExtensions;
public:
Context() : mExtensions (0) {}
virtual ~Context() {}
virtual bool canDeclareLocals() const = 0;
///< Is the compiler allowed to declare local variables?
void setExtensions (const Extensions *extensions = 0)
{
mExtensions = extensions;
}
const Extensions *getExtensions() const
{
return mExtensions;
}
virtual char getGlobalType (const std::string& name) const = 0;
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
virtual char getMemberType (const std::string& name, const std::string& id) const = 0;
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
virtual bool isId (const std::string& name) const = 0;
///< Does \a name match an ID, that can be referenced?
};
}
#endif

@ -195,10 +195,31 @@ namespace Compiler
return parseArguments (arguments, scanner, mCode);
}
bool ExprParser::handleMemberAccess (const std::string& name)
{
mMemberOp = false;
std::string name2 = toLower (name);
std::string id = toLower (mExplicit);
char type = getContext().getMemberType (name2, id);
if (type!=' ')
{
Generator::fetchMember (mCode, mLiterals, type, name2, id);
mNextOperand = false;
mExplicit.clear();
mOperands.push_back (type=='f' ? 'f' : 'l');
return true;
}
return false;
}
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
Literals& literals, bool argument)
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals),
mNextOperand (true), mFirst (true), mArgument (argument)
mNextOperand (true), mFirst (true), mArgument (argument), mRefOp (false), mMemberOp (false)
{}
bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
@ -251,7 +272,12 @@ namespace Compiler
Scanner& scanner)
{
if (!mExplicit.empty())
{
if (mMemberOp && handleMemberAccess (name))
return true;
return Parser::parseName (name, loc, scanner);
}
mFirst = false;
@ -281,7 +307,7 @@ namespace Compiler
return true;
}
if (mExplicit.empty() && getContext().isId (name))
if (mExplicit.empty() && getContext().isId (name2))
{
mExplicit = name;
return true;
@ -497,6 +523,12 @@ namespace Compiler
return true;
}
if (!mMemberOp && code==Scanner::S_member)
{
mMemberOp = true;
return true;
}
return Parser::parseSpecial (code, loc, scanner);
}
@ -609,6 +641,7 @@ namespace Compiler
mFirst = true;
mExplicit.clear();
mRefOp = false;
mMemberOp = false;
Parser::reset();
}

@ -26,6 +26,7 @@ namespace Compiler
bool mArgument;
std::string mExplicit;
bool mRefOp;
bool mMemberOp;
int getPriority (char op) const;
@ -53,6 +54,8 @@ namespace Compiler
int parseArguments (const std::string& arguments, Scanner& scanner);
bool handleMemberAccess (const std::string& name);
public:
ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,

Loading…
Cancel
Save