mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
* partially done support for VERM
* MSVC compilation fix (using boost::ref is an error)
This commit is contained in:
@@ -25,6 +25,8 @@
|
|||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
//#include <boost/thread.hpp>
|
//#include <boost/thread.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/ref.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "../lib/Connection.h"
|
#include "../lib/Connection.h"
|
||||||
#include "../lib/VCMIDirs.h"
|
#include "../lib/VCMIDirs.h"
|
||||||
@@ -220,7 +222,7 @@ CMenuScreen::CMenuScreen( EState which )
|
|||||||
bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[loadGame])), 532, 132, "ZMENULG.DEF", SDLK_l);
|
bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[loadGame])), 532, 132, "ZMENULG.DEF", SDLK_l);
|
||||||
buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[5].second, 0, 524, 251, "ZMENUHS.DEF", SDLK_h); // Highscore
|
buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[5].second, 0, 524, 251, "ZMENUHS.DEF", SDLK_h); // Highscore
|
||||||
buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[6].second, 0 /*cb*/, 557, 359, "ZMENUCR.DEF", SDLK_c); // Credits
|
buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[6].second, 0 /*cb*/, 557, 359, "ZMENUCR.DEF", SDLK_c); // Credits
|
||||||
boost::function<void()> confWindow = bind(CInfoWindow::showYesNoDialog, boost::ref(CGI->generaltexth->allTexts[69]), (const std::vector<SComponent*>*)0, do_quit, 0, false, 1);
|
boost::function<void()> confWindow = bind(CInfoWindow::showYesNoDialog, ref(CGI->generaltexth->allTexts[69]), (const std::vector<SComponent*>*)0, do_quit, 0, false, 1);
|
||||||
buttons[4] = new AdventureMapButton("", CGI->generaltexth->zelp[7].second, confWindow, 586, 468, "ZMENUQT.DEF", SDLK_ESCAPE); // Exit
|
buttons[4] = new AdventureMapButton("", CGI->generaltexth->zelp[7].second, confWindow, 586, 468, "ZMENUQT.DEF", SDLK_ESCAPE); // Exit
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -50,7 +50,7 @@ void ERMParser::parseFile()
|
|||||||
//check header
|
//check header
|
||||||
char header[5];
|
char header[5];
|
||||||
file.getline(header, ARRAY_COUNT(header));
|
file.getline(header, ARRAY_COUNT(header));
|
||||||
if(std::string(header) != "ZVSE")
|
if(std::string(header) != "ZVSE" && std::string(header) != "VERM")
|
||||||
{
|
{
|
||||||
tlog1 << "File " << srcFile << " has wrong header\n";
|
tlog1 << "File " << srcFile << " has wrong header\n";
|
||||||
return;
|
return;
|
||||||
@@ -280,9 +280,31 @@ namespace ERM
|
|||||||
std::string comment;
|
std::string comment;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::variant<Tcommand, std::string, qi::unused_type> Tline;
|
//vector expression
|
||||||
|
|
||||||
|
|
||||||
|
typedef boost::variant<Tcommand, std::string, qi::unused_type> TERMline;
|
||||||
|
|
||||||
|
struct TSymbol
|
||||||
|
{
|
||||||
|
boost::optional<std::string> symModifier; //'`', ',', ',@', '#''
|
||||||
|
std::string sym;
|
||||||
|
};
|
||||||
|
|
||||||
|
//for #'symbol expression
|
||||||
|
|
||||||
|
struct TVExp;
|
||||||
|
typedef boost::variant<boost::recursive_wrapper<TVExp>, TSymbol, char, double, int, Tcommand, TStringConstant > TVOption; //options in v-expression
|
||||||
|
//v-expression
|
||||||
|
struct TVExp
|
||||||
|
{
|
||||||
|
//char dummy;
|
||||||
|
std::vector<TVOption> children;
|
||||||
|
};
|
||||||
|
|
||||||
|
//script line
|
||||||
|
typedef boost::variant<TVExp, TERMline> TLine;
|
||||||
|
|
||||||
//console printer
|
//console printer
|
||||||
|
|
||||||
struct VarPrinterVisitor : boost::static_visitor<>
|
struct VarPrinterVisitor : boost::static_visitor<>
|
||||||
@@ -537,12 +559,78 @@ namespace ERM
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void printLineAST(const Tline & ast)
|
void printERM(const TERMline & ast)
|
||||||
{
|
{
|
||||||
tlog2 << "";
|
tlog2 << "";
|
||||||
|
|
||||||
boost::apply_visitor(LinePrinterVisitor(), ast);
|
boost::apply_visitor(LinePrinterVisitor(), ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printTVExp(const TVExp & exp);
|
||||||
|
|
||||||
|
struct VOptionPrinterVisitor : boost::static_visitor<>
|
||||||
|
{
|
||||||
|
void operator()(TVExp const& cmd) const
|
||||||
|
{
|
||||||
|
printTVExp(cmd);
|
||||||
|
}
|
||||||
|
void operator()(TSymbol const& cmd) const
|
||||||
|
{
|
||||||
|
if(cmd.symModifier.is_initialized())
|
||||||
|
{
|
||||||
|
tlog2 << cmd.symModifier.get();
|
||||||
|
}
|
||||||
|
tlog2 << cmd.sym;
|
||||||
|
}
|
||||||
|
void operator()(char const& cmd) const
|
||||||
|
{
|
||||||
|
tlog2 << "'" << cmd << "'";
|
||||||
|
}
|
||||||
|
void operator()(int const& cmd) const
|
||||||
|
{
|
||||||
|
tlog2 << cmd;
|
||||||
|
}
|
||||||
|
void operator()(double const& cmd) const
|
||||||
|
{
|
||||||
|
tlog2 << cmd;
|
||||||
|
}
|
||||||
|
void operator()(TERMline const& cmd) const
|
||||||
|
{
|
||||||
|
printERM(cmd);
|
||||||
|
}
|
||||||
|
void operator()(TStringConstant const& cmd) const
|
||||||
|
{
|
||||||
|
tlog2 << "^" << cmd.str << "^";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void printTVExp(const TVExp & exp)
|
||||||
|
{
|
||||||
|
tlog2 << "[ ";
|
||||||
|
BOOST_FOREACH(TVOption opt, exp.children)
|
||||||
|
{
|
||||||
|
boost::apply_visitor(VOptionPrinterVisitor(), opt);
|
||||||
|
tlog2 << " ";
|
||||||
|
}
|
||||||
|
tlog2 << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TLPrinterVisitor : boost::static_visitor<>
|
||||||
|
{
|
||||||
|
void operator()(TVExp const& cmd) const
|
||||||
|
{
|
||||||
|
printTVExp(cmd);
|
||||||
|
}
|
||||||
|
void operator()(TERMline const& cmd) const
|
||||||
|
{
|
||||||
|
printERM(cmd);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void printAST(const TLine & ast)
|
||||||
|
{
|
||||||
|
boost::apply_visitor(TLPrinterVisitor(), ast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FUSION_ADAPT_STRUCT(
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
@@ -670,12 +758,24 @@ BOOST_FUSION_ADAPT_STRUCT(
|
|||||||
(std::string, comment)
|
(std::string, comment)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
|
ERM::TVExp,
|
||||||
|
//(char, dummy)
|
||||||
|
(std::vector<ERM::TVOption>, children)
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
|
ERM::TSymbol,
|
||||||
|
(boost::optional<std::string>, symModifier)
|
||||||
|
(std::string, sym)
|
||||||
|
)
|
||||||
|
|
||||||
namespace ERM
|
namespace ERM
|
||||||
{
|
{
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
struct ERM_grammar : qi::grammar<Iterator, Tline(), ascii::space_type>
|
struct ERM_grammar : qi::grammar<Iterator, TLine(), ascii::space_type>
|
||||||
{
|
{
|
||||||
ERM_grammar() : ERM_grammar::base_type(rline, "ERM script line")
|
ERM_grammar() : ERM_grammar::base_type(vline, "VERM script line")
|
||||||
{
|
{
|
||||||
//do not build too complicated expressions, e.g. (a >> b) | c, qi has problems with them
|
//do not build too complicated expressions, e.g. (a >> b) | c, qi has problems with them
|
||||||
macroUsage %= qi::lexeme[qi::lit('$') >> *(qi::char_ - '$') >> qi::lit('$')];
|
macroUsage %= qi::lexeme[qi::lit('$') >> *(qi::char_ - '$') >> qi::lit('$')];
|
||||||
@@ -686,7 +786,7 @@ namespace ERM
|
|||||||
iexp %= varExp | qi::int_;
|
iexp %= varExp | qi::int_;
|
||||||
varp %=/* qi::lit("?") >> */(varExpNotMacro | qMacroUsage);
|
varp %=/* qi::lit("?") >> */(varExpNotMacro | qMacroUsage);
|
||||||
comment %= *qi::char_;
|
comment %= *qi::char_;
|
||||||
commentLine %= (~qi::char_('!') >> comment | (qi::char_('!') >> (~qi::char_("?!$#")) >> comment ));
|
commentLine %= (~qi::char_("![") >> comment | (qi::char_('!') >> (~qi::char_("?!$#")) >> comment ));
|
||||||
cmdName %= qi::lexeme[qi::repeat(2)[qi::char_]];
|
cmdName %= qi::lexeme[qi::repeat(2)[qi::char_]];
|
||||||
arithmeticOp %= iexp >> qi::char_ >> iexp;
|
arithmeticOp %= iexp >> qi::char_ >> iexp;
|
||||||
//identifier is usually a vector of i-expressions but VR receiver performs arithmetic operations on it
|
//identifier is usually a vector of i-expressions but VR receiver performs arithmetic operations on it
|
||||||
@@ -724,7 +824,15 @@ namespace ERM
|
|||||||
rline %=
|
rline %=
|
||||||
(
|
(
|
||||||
command | commentLine | spirit::eps
|
command | commentLine | spirit::eps
|
||||||
) > spirit::eoi;
|
);
|
||||||
|
|
||||||
|
vsym %= -(qi::string("`") | qi::string(",") | qi::string("#,") | qi::string(",@") | qi::string("#'")) >> +qi::char_("+*/$%&_=<>~a-zA-Z0-9-");
|
||||||
|
|
||||||
|
|
||||||
|
vopt %= vsym | (qi::lit("!") >> qi::char_ >> qi::lit("!")) | qi::double_ | qi::int_ | command /*| vexp*/ | string;
|
||||||
|
vexp %= qi::lit("[") >> *(vopt) >> qi::lit("]");
|
||||||
|
|
||||||
|
vline %= (vexp | rline ) > spirit::eoi;
|
||||||
|
|
||||||
//error handling
|
//error handling
|
||||||
|
|
||||||
@@ -741,11 +849,15 @@ namespace ERM
|
|||||||
receiver.name("receiver");
|
receiver.name("receiver");
|
||||||
postTrigger.name("post trigger");
|
postTrigger.name("post trigger");
|
||||||
command.name("command");
|
command.name("command");
|
||||||
rline.name("script line");
|
rline.name("ERM script line");
|
||||||
|
vsym.name("V symbol");
|
||||||
|
vopt.name("V option");
|
||||||
|
vexp.name("V expression");
|
||||||
|
vline.name("VERM line");
|
||||||
|
|
||||||
qi::on_error<qi::fail>
|
qi::on_error<qi::fail>
|
||||||
(
|
(
|
||||||
rline
|
vline
|
||||||
, std::cout //or phoenix::ref(std::count), is there any difference?
|
, std::cout //or phoenix::ref(std::count), is there any difference?
|
||||||
<< phoenix::val("Error! Expecting ")
|
<< phoenix::val("Error! Expecting ")
|
||||||
<< qi::_4 // what failed?
|
<< qi::_4 // what failed?
|
||||||
@@ -788,7 +900,11 @@ namespace ERM
|
|||||||
qi::rule<Iterator, Treceiver(), ascii::space_type> receiver;
|
qi::rule<Iterator, Treceiver(), ascii::space_type> receiver;
|
||||||
qi::rule<Iterator, TPostTrigger(), ascii::space_type> postTrigger;
|
qi::rule<Iterator, TPostTrigger(), ascii::space_type> postTrigger;
|
||||||
qi::rule<Iterator, Tcommand(), ascii::space_type> command;
|
qi::rule<Iterator, Tcommand(), ascii::space_type> command;
|
||||||
qi::rule<Iterator, Tline(), ascii::space_type> rline;
|
qi::rule<Iterator, TERMline(), ascii::space_type> rline;
|
||||||
|
qi::rule<Iterator, TSymbol(), ascii::space_type> vsym;
|
||||||
|
qi::rule<Iterator, TVOption(), ascii::space_type> vopt;
|
||||||
|
qi::rule<Iterator, TVExp(), ascii::space_type> vexp;
|
||||||
|
qi::rule<Iterator, TLine(), ascii::space_type> vline;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -798,7 +914,7 @@ void ERMParser::parseLine( const std::string & line )
|
|||||||
end = line.end();
|
end = line.end();
|
||||||
|
|
||||||
ERM::ERM_grammar<std::string::const_iterator> ERMgrammar;
|
ERM::ERM_grammar<std::string::const_iterator> ERMgrammar;
|
||||||
ERM::Tline AST;
|
ERM::TLine AST;
|
||||||
|
|
||||||
// bool r = qi::phrase_parse(beg, end, ERMgrammar, ascii::space, AST);
|
// bool r = qi::phrase_parse(beg, end, ERMgrammar, ascii::space, AST);
|
||||||
// if(!r || beg != end)
|
// if(!r || beg != end)
|
||||||
@@ -810,7 +926,7 @@ void ERMParser::parseLine( const std::string & line )
|
|||||||
// {
|
// {
|
||||||
// //parsing succeeded
|
// //parsing succeeded
|
||||||
// tlog2 << line << std::endl;
|
// tlog2 << line << std::endl;
|
||||||
// ERM::printLineAST(AST);
|
// ERM::printAST(AST);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -68,7 +68,8 @@ DLL_EXPORT void initDLL(CConsoleHandler *Console, std::ostream *Logfile)
|
|||||||
if(is_regular(dir->status()))
|
if(is_regular(dir->status()))
|
||||||
{
|
{
|
||||||
std::string name = dir->path().leaf();
|
std::string name = dir->path().leaf();
|
||||||
if( boost::algorithm::ends_with(name, ".erm"))
|
if( boost::algorithm::ends_with(name, ".erm") ||
|
||||||
|
boost::algorithm::ends_with(name, ".verm") )
|
||||||
{
|
{
|
||||||
|
|
||||||
ERMParser ep(dir->path().string());
|
ERMParser ep(dir->path().string());
|
||||||
|
Reference in New Issue
Block a user