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 <boost/thread.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <cstdlib>
|
||||
#include "../lib/Connection.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);
|
||||
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
|
||||
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
|
||||
}
|
||||
break;
|
||||
|
@@ -50,7 +50,7 @@ void ERMParser::parseFile()
|
||||
//check header
|
||||
char header[5];
|
||||
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";
|
||||
return;
|
||||
@@ -280,9 +280,31 @@ namespace ERM
|
||||
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
|
||||
|
||||
struct VarPrinterVisitor : boost::static_visitor<>
|
||||
@@ -537,12 +559,78 @@ namespace ERM
|
||||
}
|
||||
};
|
||||
|
||||
void printLineAST(const Tline & ast)
|
||||
void printERM(const TERMline & ast)
|
||||
{
|
||||
tlog2 << "";
|
||||
|
||||
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(
|
||||
@@ -670,12 +758,24 @@ BOOST_FUSION_ADAPT_STRUCT(
|
||||
(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
|
||||
{
|
||||
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
|
||||
macroUsage %= qi::lexeme[qi::lit('$') >> *(qi::char_ - '$') >> qi::lit('$')];
|
||||
@@ -686,7 +786,7 @@ namespace ERM
|
||||
iexp %= varExp | qi::int_;
|
||||
varp %=/* qi::lit("?") >> */(varExpNotMacro | qMacroUsage);
|
||||
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_]];
|
||||
arithmeticOp %= iexp >> qi::char_ >> iexp;
|
||||
//identifier is usually a vector of i-expressions but VR receiver performs arithmetic operations on it
|
||||
@@ -724,7 +824,15 @@ namespace ERM
|
||||
rline %=
|
||||
(
|
||||
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
|
||||
|
||||
@@ -741,11 +849,15 @@ namespace ERM
|
||||
receiver.name("receiver");
|
||||
postTrigger.name("post trigger");
|
||||
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>
|
||||
(
|
||||
rline
|
||||
vline
|
||||
, std::cout //or phoenix::ref(std::count), is there any difference?
|
||||
<< phoenix::val("Error! Expecting ")
|
||||
<< qi::_4 // what failed?
|
||||
@@ -788,7 +900,11 @@ namespace ERM
|
||||
qi::rule<Iterator, Treceiver(), ascii::space_type> receiver;
|
||||
qi::rule<Iterator, TPostTrigger(), ascii::space_type> postTrigger;
|
||||
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();
|
||||
|
||||
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);
|
||||
// if(!r || beg != end)
|
||||
@@ -810,7 +926,7 @@ void ERMParser::parseLine( const std::string & line )
|
||||
// {
|
||||
// //parsing succeeded
|
||||
// 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()))
|
||||
{
|
||||
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());
|
||||
|
Reference in New Issue
Block a user