1
0
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:
mateuszb 2011-05-29 18:16:49 +00:00
parent 47e4c8d6e6
commit 5786c26586
2 changed files with 220 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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;