diff --git a/src/libterm/term.hh b/src/libterm/term.hh index cf4651d10..34cf598dc 100644 --- a/src/libterm/term.hh +++ b/src/libterm/term.hh @@ -3,7 +3,7 @@ # define _LIBTERM_TERM_HH # include -# include +# include # include # include @@ -61,6 +61,12 @@ namespace term { } + inline + ATerm() + : ptr_(0) + { + } + protected: inline ATerm(const ATermImpl* ptr) @@ -94,6 +100,12 @@ namespace term return ptr_ < rhs.ptr_; } + inline + operator bool() + { + return ptr_; + } + public: inline const ATermImpl* @@ -103,16 +115,7 @@ namespace term } protected: - const ATermImpl* /*const*/ ptr_; - }; - - class ATermNil : public ATerm - { - public: - ATermNil() - : ATerm(0) - { - } + const ATermImpl* ptr_; }; @@ -157,7 +160,7 @@ namespace term public: inline - bool operator <(const this_type&) + bool operator <(const this_type&) const { return false; } @@ -388,7 +391,7 @@ namespace term # define TRM_LESS_GRAMMAR_NODE_OP(Name, Base, Attributes, BaseArgs) \ public: \ inline \ - bool operator <(const Name& arg_rhs) \ + bool operator <(const Name& arg_rhs) const \ { \ return TRM_APPLY(TRM_LESS_RHS_OR, Attributes) \ parent::operator < (arg_rhs); \ @@ -415,6 +418,11 @@ namespace term { \ } \ \ + A ## Name () \ + : parent() \ + { \ + } \ + \ protected: \ explicit A ## Name (const ATermImpl* ptr) \ : parent(ptr) \ @@ -432,13 +440,15 @@ namespace term A ## Name (const A ## Name& t) \ : parent(t) \ { \ + } \ + \ + A ## Name () \ + : parent() \ + { \ } \ \ const Name & \ operator() () const; \ - { \ - return *static_cast(ptr_); \ - } \ \ protected: \ explicit A ## Name (const ATermImpl* ptr) \ @@ -512,48 +522,45 @@ namespace term // definition of the ATermVisitor visit functions. # define TRM_VISITOR(Name, Base, Attributes, BaseArgs) \ ATerm \ - ATermVisitor::visit(const A ## Name) { \ - return ATermNil(); \ + ATermVisitor::visit(const A ## Name t) { \ + return t; \ } TRM_VISITOR(Term, TRM_NIL, TRM_NIL, TRM_NIL) TRM_GRAMMAR_NODES(TRM_VISITOR, TRM_VISITOR) # undef TRM_VISITOR - - template - class getVisitor : ATermVisitor + namespace impl { - public: - getVisitor(ATerm t) + template + class asVisitor : ATermVisitor { - t.accept(*this); - } + public: + asVisitor(ATerm t) + : res() + { + t.accept(*this); + } - ATerm visit(const T t) - { - res = std::pair(true, t); - return ATermNil(); - } + ATerm visit(const T t) + { + return res = t; + } - std::pair res; - }; + public: + T res; + }; + } + // This function will return a zero ATerm if the element does not have the + // expected type. template - std::pair - is_a(ATerm t) + T as(ATerm t) { - getVisitor v(t); + impl::asVisitor v(t); return v.res; } - template - T - as(ATerm t) - { - getVisitor v(t); - return v.res.second; - } } #endif diff --git a/src/libterm/test.cc b/src/libterm/test.cc index 9543bed7f..3b89d4184 100644 --- a/src/libterm/test.cc +++ b/src/libterm/test.cc @@ -1,5 +1,6 @@ #include +#include #define TRM_GRAMMAR_NODES(Interface, Final) \ Interface(Expr, Term, (0, ()), (0, ())) \ @@ -9,27 +10,46 @@ #include "term.hh" #undef TRM_GRAMMAR_NODES -struct Eval : public term::ATermVisitor +using namespace term; + +struct Eval : public ATermVisitor { - int run(const term::ATerm t) + int run(const ATerm t) { - return term::as(t.accept(*this))().value; + return as(t.accept(*this))().value; } - term::ATerm visit(const term::APlus p) + ATerm visit(const APlus p) { - return term::Int::make(run(p().lhs) + run(p().rhs)); + return Int::make(run(p().lhs) + run(p().rhs)); } }; +#define CHECK(Cond, Msg) \ + if (Cond) \ + { \ + good++; \ + std::cout << "Ok: " << Msg << std::endl; \ + } \ + else \ + { \ + std::cout << "Ko: " << Msg << std::endl; \ + } \ + tests++ + int main() { + unsigned good, tests; + using namespace term; AInt a = Int::make(1); AInt b = Int::make(2); AInt c = Int::make(1); - - // assert(a == c); Eval e; - return e.run(Plus::make(a, Plus::make(b, c))); + + CHECK(a == c, "Terms are shared."); + CHECK(!as(a), "Bad convertion returns a zero ATerm."); + CHECK(as(a), "Good convertion returns a non-zero ATerm."); + CHECK(e.run(Plus::make(a, Plus::make(b, c))) == 4, "Visitors are working."); + return tests - good; }