1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* a few bugs in interpreter fixed

This commit is contained in:
mateuszb 2011-05-11 19:53:55 +00:00
parent 7c771e5c56
commit 95b16906aa
4 changed files with 36 additions and 18 deletions

View File

@ -378,13 +378,13 @@ void ERMInterpreter::scanForScripts()
FileInfo * finfo = new FileInfo;
finfo->filename = dir->path().string();
std::vector<ERM::TLine> buf = ep.parseFile();
std::vector<LineInfo> buf = ep.parseFile();
finfo->length = buf.size();
files.push_back(finfo);
for(int g=0; g<buf.size(); ++g)
{
scripts[LinePointer(finfo, g)] = buf[g];
scripts[LinePointer(finfo, g, buf[g].realLineNum)] = buf[g].tl;
}
}
}
@ -509,11 +509,11 @@ bool ERMInterpreter::isATrigger( const ERM::TLine & line )
break;
case 1: //erm
{
TERMline line = boost::get<TERMline>(line);
switch(line.which())
TERMline ermline = boost::get<TERMline>(line);
switch(ermline.which())
{
case 0: //tcmd
return isCMDATrigger( boost::get<ERM::Tcommand>(line) );
return isCMDATrigger( boost::get<ERM::Tcommand>(ermline) );
break;
default:
return false;
@ -550,7 +550,7 @@ bool ERMInterpreter::isCMDATrigger( const ERM::Tcommand & cmd )
ERM::TLine ERMInterpreter::retrieveLine( LinePointer linePtr ) const
{
return *scripts.find(linePtr);
return scripts.find(linePtr)->second;
}
/////////
@ -1062,7 +1062,7 @@ struct LVL1IexpDisemboweler : boost::static_visitor<IexpValStr>
{
if(dir == IexpDisemboweler::GET)
{
IexpValStr ret = IexpValStr(constant);
return IexpValStr(constant);
}
else
{
@ -1094,7 +1094,7 @@ IexpValStr ERMInterpreter::getIexp( const ERM::TIdentifierInternal & tid ) const
{
if(tid.which() == 0)
{
IexpValStr ievs = getIexp(boost::get<ERM::TIexp>(tid));
return getIexp(boost::get<ERM::TIexp>(tid));
}
else
throw EScriptExecError("Identifier must be a valid i-expression to perform this operation!");
@ -1138,12 +1138,14 @@ ERM::Ttrigger ERMInterpreter::retrieveTrigger( ERM::TLine line )
ERM::TERMline tl = boost::get<ERM::TERMline>(line);
if(tl.which() == 0)
{
ERM::Tcommand tcm = boost::get<ERM::Tcommand>(line);
ERM::Tcommand tcm = boost::get<ERM::Tcommand>(tl);
if(tcm.cmd.which() == 0)
{
return boost::get<ERM::Ttrigger>(tcm.cmd);
}
throw ELineProblem("Given line is not a trigger!");
}
throw ELineProblem("Given line is not a command!");
}
throw ELineProblem("Given line is not an ERM trigger!");
}
@ -1412,6 +1414,7 @@ double & VERMInterpreter::TriggerLocalVars::getEvar( int num )
int & VERMInterpreter::TriggerLocalVars::getYvar( int num )
{
num = -num; //we handle negative indices
if(num < 1 || num > YVAR_NUM)
throw EScriptExecError("Number of trigger local variable out of bounds");

View File

@ -220,10 +220,13 @@ namespace VERMInterpreter
const FileInfo * file; //non-owning
int lineNum;
int realLineNum;
LinePointer() : file(NULL)
{}
LinePointer(const FileInfo * finfo, int line) : file(finfo), lineNum(line)
LinePointer(const FileInfo * finfo, int line, int _realLineNum) : file(finfo), lineNum(line),
realLineNum(_realLineNum)
{}
//lexicographical order

View File

@ -177,10 +177,10 @@ ERMParser::ERMParser(std::string file)
:srcFile(file)
{}
std::vector<ERM::TLine> ERMParser::parseFile()
std::vector<LineInfo> ERMParser::parseFile()
{
CERMPreprocessor preproc(srcFile);
std::vector<ERM::TLine> ret;
std::vector<LineInfo> ret;
try
{
while(1)
@ -190,7 +190,10 @@ std::vector<ERM::TLine> ERMParser::parseFile()
break;
repairEncoding(command);
ret.push_back(parseLine(command));
LineInfo li;
li.realLineNum = preproc.getCurLineNo();
li.tl = parseLine(command, li.realLineNum);
ret.push_back(li);
}
}
catch (ParseErrorException & e)
@ -482,7 +485,7 @@ namespace ERM
};
};
ERM::TLine ERMParser::parseLine( const std::string & line )
ERM::TLine ERMParser::parseLine( const std::string & line, int realLineNo )
{
std::string::const_iterator beg = line.begin(),
end = line.end();
@ -493,7 +496,7 @@ ERM::TLine ERMParser::parseLine( const std::string & line )
bool r = qi::phrase_parse(beg, end, ERMgrammar, ascii::space, AST);
if(!r || beg != end)
{
tlog1 << "Parse error in file " << srcFile << " (line " << parsedLine << ") :\n" << line << std::endl;
tlog1 << "Parse error in file " << srcFile << " (line " << realLineNo << ") :\n" << line << std::endl;
tlog1 << "\tCannot parse: " << std::string(beg, end) << std::endl;
throw ParseErrorException();
}

View File

@ -28,6 +28,10 @@ class CERMPreprocessor
public:
CERMPreprocessor(const std::string &Fname);
std::string retreiveCommandLine();
int getCurLineNo() const
{
return lineNo;
}
};
//various classes that represent ERM/VERM AST
@ -231,20 +235,25 @@ namespace ERM
typedef boost::variant<TVExp, TERMline> TLine;
}
struct LineInfo
{
ERM::TLine tl;
int realLineNum;
};
class ERMParser
{
private:
std::string srcFile;
int parsedLine;
void repairEncoding(char * str, int len) const; //removes nonstandard ascii characters from string
void repairEncoding(std::string & str) const; //removes nonstandard ascii characters from string
enum ELineType{COMMAND_FULL, COMMENT, UNFINISHED, END_OF};
int countHatsBeforeSemicolon(const std::string & line) const;
ELineType classifyLine(const std::string & line, bool inString) const;
ERM::TLine parseLine(const std::string & line);
ERM::TLine parseLine(const std::string & line, int realLineNo);
public:
ERMParser(std::string file);
std::vector<ERM::TLine> parseFile();
std::vector<LineInfo> parseFile();
};