lundi 22 décembre 2014

Runtime handling of constant / terminal types in C++ AST

I'm trying to find a good way of implementing unary and binary operators within an abstract syntax tree hierarchy that uses std::shared_ptr wrappers.


I'm using a templated "Constant" class to wrap the supported native types - float, std::string, etc.


I also have a "Variable" class that is used to store a variable symbol and lookup the associated Constant at runtime.


I would like to implement the Binary operator class to evaluate it's lhs and rhs components at runtime and then apply an operator and return a Constant<> of the appropriate return type. Since I have a variable type, the return type of a binary operation isn't necessarily known at compile time and I therefore need to deduce lhs and rhs underlying Constant types at runtime. So, for example, an addition operator would sum two Constant inputs or concatenate two Constant inputs.


Can anyone recommend a good way of implementing this functionality such that the BinaryOp's lhs and rhs component types do not need to be known at compile time?


I've looked at decltype, functors and branching with dynamic_cast<>, but haven't reached a good solution.


Here's the basic form of my AST hierarchy:


Any suggestions, links, etc would be greatly appreciated!



class Ast {
public:

typedef std::shared_ptr<Ast> Ref;

Ast() {}
virtual ~Ast() {}

virtual Ast::Ref evaluate() = 0;
};

class Variable : public Ast {
public:

std::string ident;

Variable() {}
Variable(const std::string& i) : ident(ident) {}
};

template <typename ValueType>
class Constant : public Ast {
public:

ValueType value;

Constant() {}
Constant(const ValueType& v) : value(v) {}
};

class BinaryOp : public Ast {
public:

Ast::Ref lhs;
Ast::Ref rhs;

BinaryOp() {}
BinaryOp(Ast::Ref l, Ast::Ref r) : lhs(l), rhs(r) {}
};

Aucun commentaire:

Enregistrer un commentaire