mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
* building verm tree without modifiers
This commit is contained in:
parent
47e4c8d6e6
commit
5786c26586
@ -2304,3 +2304,145 @@ const CGObjectInstance * ERMInterpreter::getObjFrom( int3 pos )
|
||||
throw EScriptExecError("Attempt to obtain access to nonexistent object!");
|
||||
return objs.back();
|
||||
}
|
||||
|
||||
namespace VERMInterpreter
|
||||
{
|
||||
VOption convertToVOption(const ERM::TVOption & tvo)
|
||||
{
|
||||
return boost::apply_visitor(OptionConverterVisitor(), tvo);
|
||||
}
|
||||
|
||||
VNode::VNode( const ERM::TVExp & exp )
|
||||
{
|
||||
for(int i=0; i<exp.children.size(); ++i)
|
||||
{
|
||||
children.elements.push_back(convertToVOption(exp.children[i]));
|
||||
}
|
||||
processModifierList(exp.modifier);
|
||||
}
|
||||
|
||||
VNode::VNode( const VOption & first, const VOptionList & rest ) /*merges given arguments into [a, rest] */
|
||||
{
|
||||
setVnode(first, rest);
|
||||
}
|
||||
|
||||
VNode::VNode( const VOptionList & cdren ) : children(cdren)
|
||||
{}
|
||||
|
||||
VNode::VNode( const ERM::TSymbol & sym )
|
||||
{
|
||||
children.car() = OptionConverterVisitor()(sym);
|
||||
processModifierList(sym.symModifier);
|
||||
}
|
||||
|
||||
void VNode::setVnode( const VOption & first, const VOptionList & rest )
|
||||
{
|
||||
children.car() = first;
|
||||
children.cdr() = rest;
|
||||
}
|
||||
|
||||
void VNode::processModifierList( const std::vector<TVModifier> & modifierList )
|
||||
{
|
||||
for(int g=0; g<modifierList.size(); ++g)
|
||||
{
|
||||
children.cdr() = VNode(children);
|
||||
if(modifierList[g] == "`")
|
||||
{
|
||||
children.car() = VSymbol("backquote");
|
||||
}
|
||||
else if(modifierList[g] == ",!")
|
||||
{
|
||||
children.car() = VSymbol("comma-unlist");
|
||||
}
|
||||
else if(modifierList[g] == ",")
|
||||
{
|
||||
children.car() = VSymbol("comma");
|
||||
}
|
||||
else if(modifierList[g] == "#'")
|
||||
{
|
||||
children.car() = VSymbol("get-func");
|
||||
}
|
||||
else if(modifierList[g] == "'")
|
||||
{
|
||||
children.car() = VSymbol("quote");
|
||||
}
|
||||
else
|
||||
throw EInterpreterError("Incorrect value of modifier!");
|
||||
}
|
||||
}
|
||||
|
||||
VermTreeIterator & VermTreeIterator::operator=( const VOption & opt )
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case CAR:
|
||||
if(parent.elements.size() == 0)
|
||||
parent.elements.push_back(opt);
|
||||
else
|
||||
parent.elements[0] = opt;
|
||||
break;
|
||||
case CDR:
|
||||
parent.elements.resize(2);
|
||||
parent.elements[1] = opt;
|
||||
break;
|
||||
default://should never happen
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
VermTreeIterator & VermTreeIterator::operator=( const std::vector<VOption> & opt )
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case CAR:
|
||||
//TODO: implement me
|
||||
break;
|
||||
case CDR:
|
||||
parent.elements.resize(1);
|
||||
parent.elements.insert(parent.elements.begin()+1, opt.begin(), opt.end());
|
||||
break;
|
||||
default://should never happen
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
VermTreeIterator & VermTreeIterator::operator=( const VOptionList & opt )
|
||||
{
|
||||
return *this = opt.elements;
|
||||
}
|
||||
|
||||
|
||||
VOption OptionConverterVisitor::operator()( ERM::TVExp const& cmd ) const
|
||||
{
|
||||
return VNode(cmd);
|
||||
}
|
||||
VOption OptionConverterVisitor::operator()( ERM::TSymbol const& cmd ) const
|
||||
{
|
||||
if(cmd.symModifier.size() == 0)
|
||||
return VSymbol(cmd.sym);
|
||||
else
|
||||
return VNode(cmd);
|
||||
}
|
||||
VOption OptionConverterVisitor::operator()( char const& cmd ) const
|
||||
{
|
||||
return TLiteral(cmd);
|
||||
}
|
||||
VOption OptionConverterVisitor::operator()( double const& cmd ) const
|
||||
{
|
||||
return TLiteral(cmd);
|
||||
}
|
||||
VOption OptionConverterVisitor::operator()(int const& cmd) const
|
||||
{
|
||||
return TLiteral(cmd);
|
||||
}
|
||||
VOption OptionConverterVisitor::operator()(ERM::Tcommand const& cmd) const
|
||||
{
|
||||
return cmd;
|
||||
}
|
||||
VOption OptionConverterVisitor::operator()( ERM::TStringConstant const& cmd ) const
|
||||
{
|
||||
return TLiteral(cmd.str);
|
||||
}
|
||||
|
||||
}
|
@ -295,6 +295,84 @@ namespace VERMInterpreter
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//verm goodies
|
||||
struct VSymbol
|
||||
{
|
||||
std::string text;
|
||||
VSymbol(const std::string & txt) : text(txt)
|
||||
{}
|
||||
};
|
||||
typedef boost::variant<char, double, int, std::string> TLiteral;
|
||||
|
||||
struct VNIL
|
||||
{};
|
||||
|
||||
struct VNode;
|
||||
struct VOptionList;
|
||||
|
||||
typedef boost::variant<VNIL, boost::recursive_wrapper<VNode>, VSymbol, TLiteral, ERM::Tcommand> VOption; //options in v-expression, VNIl should be the default
|
||||
|
||||
|
||||
struct VermTreeIterator
|
||||
{
|
||||
private:
|
||||
friend struct VOptionList;
|
||||
VOptionList & parent;
|
||||
enum Estate {CAR, CDR} state;
|
||||
public:
|
||||
VermTreeIterator(VOptionList & _parent) : parent(_parent)
|
||||
{}
|
||||
|
||||
VermTreeIterator & operator=(const VOption & opt);
|
||||
VermTreeIterator & operator=(const std::vector<VOption> & opt);
|
||||
VermTreeIterator & operator=(const VOptionList & opt);
|
||||
};
|
||||
|
||||
struct VOptionList
|
||||
{
|
||||
std::vector<VOption> elements;
|
||||
VermTreeIterator car()
|
||||
{
|
||||
VermTreeIterator ret(*this);
|
||||
ret.state = VermTreeIterator::CAR;
|
||||
return ret;
|
||||
}
|
||||
VermTreeIterator cdr()
|
||||
{
|
||||
VermTreeIterator ret(*this);
|
||||
ret.state = VermTreeIterator::CDR;
|
||||
return ret;
|
||||
}
|
||||
bool isNil() const
|
||||
{
|
||||
return elements.size() == 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct OptionConverterVisitor : boost::static_visitor<VOption>
|
||||
{
|
||||
VOption operator()(ERM::TVExp const& cmd) const;
|
||||
VOption operator()(ERM::TSymbol const& cmd) const;
|
||||
VOption operator()(char const& cmd) const;
|
||||
VOption operator()(double const& cmd) const;
|
||||
VOption operator()(int const& cmd) const;
|
||||
VOption operator()(ERM::Tcommand const& cmd) const;
|
||||
VOption operator()(ERM::TStringConstant const& cmd) const;
|
||||
};
|
||||
|
||||
struct VNode
|
||||
{
|
||||
private:
|
||||
void processModifierList(const std::vector<TVModifier> & modifierList);
|
||||
public:
|
||||
VOptionList children;
|
||||
VNode( const ERM::TVExp & exp);
|
||||
VNode( const VOptionList & cdren );
|
||||
VNode( const ERM::TSymbol & sym ); //only in case sym has modifiers!
|
||||
VNode( const VOption & first, const VOptionList & rest); //merges given arguments into [a, rest];
|
||||
void setVnode( const VOption & first, const VOptionList & rest);
|
||||
};
|
||||
}
|
||||
|
||||
class ERMInterpreter;
|
||||
|
Loading…
Reference in New Issue
Block a user