1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-15 23:12:44 +01:00

- Fix some preprocessing issues.

- Add a simple test to show how the user can to manipulate Terms.
This commit is contained in:
Nicolas Pierron 2010-02-15 20:41:44 +00:00
parent adc5231106
commit 02a4ea0617
2 changed files with 177 additions and 98 deletions

View file

@ -4,26 +4,54 @@
# include <set> # include <set>
# include <boost/preprocessor/seq/seq.hpp> # include <boost/preprocessor/tuple.hpp>
# include <boost/preprocessor/control/iif.hpp> # include <boost/preprocessor/seq.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/array.hpp>
# include "visitor_fwd.hh"
# define TRM_GRAMMAR_NODE_BINOP(Final, Name) \
Final( \
Name, Expr, \
(2, (TRM_TYPE_TERM(Expr, lhs), TRM_TYPE_TERM(Expr, rhs))), \
(0,()) \
)
# define TRM_GRAMMAR_NODE_SINGLETON(Final, Name) \
Final(Name, Expr, (0,()), (0,()))
namespace term namespace term
{ {
/* class ATerm;
class ATermNil;
# define TRM_INTERFACE_DECLARE(Name, Base, Attributes, BaseArgs) \
template <typename T> \
class Name;
# define TRM_FINAL_DECLARE(Name, Base, Attributes, BaseArgs) \
class Name;
TRM_GRAMMAR_NODES(TRM_INTERFACE_DECLARE, TRM_FINAL_DECLARE)
# undef TRM_FINAL_DECLARE
# undef TRM_INTERFACE_DECLARE
class ATermVisitor class ATermVisitor
{ {
virtual void visit(const ATerm e) = 0; virtual ATerm visit(const ATerm e) {
virtual void visit(const Function& e) = 0; return ATermNil;
}; }
# define TRM_VISITOR(Name, Base, Attributes, BaseArgs) \
virtual ATerm visit(const Name e) { \
return ATermNil; \
}
TRM_GRAMMAR_NODES(TRM_VISITOR, TRM_VISITOR)
# undef TRM_VISITOR
class ATermConstVisitor
{
virtual void visit(const ATerm e) const = 0;
virtual void visit(const Function& e) const = 0;
}; };
*/
// Performance issue: Abstract classes should be copied where fully // Performance issue: Abstract classes should be copied where fully
@ -44,7 +72,7 @@ namespace term
} }
public: public:
virtual void accept(ATermVisitor& v) const = 0; virtual ATerm accept(ATermVisitor& v) const = 0;
}; };
@ -67,7 +95,7 @@ namespace term
public: public:
inline inline
void accept(ATermVisitor& v) ATerm accept(ATermVisitor& v)
{ {
return ptr_->accept(v); return ptr_->accept(v);
} }
@ -95,6 +123,15 @@ namespace term
const void* ptr_; const void* ptr_;
}; };
class ATermNul : public ATerm
{
public:
ATermNil()
: ATerm(0)
{
}
};
template <typename T> template <typename T>
struct Term : public ATermImpl struct Term : public ATermImpl
@ -134,34 +171,60 @@ namespace term
# define TRM_NIL # define TRM_NIL
# define TRM_NIL_1(_) # define TRM_NIL_ARGS(...)
# define TRM_NIL_2(_, _)
# define TRM_IF_EMPTY_SEQ(Seq, True, False) \
BOOST_PP_IF(BOOST_PP_SEQ_SIZE(Seq), False, True)
# define TRM_MAP_HELPER(R, Macro, Seq) (Macro(Elt)) # define TRM_ARRAY_DATA(Array) BOOST_PP_ARRAY_DATA(Array)
# define TRM_ARRAY_SIZE(Array) BOOST_PP_ARRAY_SIZE(Array)
# define TRM_EVAL_0(Macro1, Macro2, Array, Default) Default
/*
define TRM_EVAL_1(Macro1, Macro2, Array, Default) \
Macro1(Macro2, BOOST_PP_TUPLE_TO_SEQ(TRM_ARRAY_SIZE(Array), TRM_ARRAY_DATA(Array)))
*/
# define TRM_EVAL_2 TRM_EVAL_1
# define TRM_EVAL_3 TRM_EVAL_1
# define TRM_EVAL_4 TRM_EVAL_1
# define TRM_EVAL_II(eval) eval
# define TRM_EVAL_I(n, tuple) TRM_EVAL_ ## n
# define TRM_EVAL(Macro1, Macro2, Array, Default) \
TRM_EVAL_II(TRM_EVAL_I Array (Macro1, Macro2, Array, Default))
# define TRM_MAP_HELPER(R, Macro, Elt) (Macro(Elt))
# define TRM_MAP_(Macro, Seq) \ # define TRM_MAP_(Macro, Seq) \
BOOST_PP_SEQ_FOR_EACH(TRM_MAP_HELPER, Macro, Seq) BOOST_PP_SEQ_FOR_EACH(TRM_MAP_HELPER, Macro, Seq)
# define TRM_MAP(Macro, Seq) \ # define TRM_MAP_SEQ(Macro, Seq) \
TRM_IF_EMPTY_SEQ(Seq, TRM_NIL_2, TRM_MAP_)(Macro, Seq) TRM_MAP_(Macro, Seq)
# define TRM_MAP_SEQ_TO_ARRAY(Macro, Seq) \
BOOST_PP_SEQ_TO_ARRAY(TRM_MAP_SEQ(Macro, Seq))
# define TRM_MAP_ARRAY(Macro, Array) \
TRM_EVAL(TRM_MAP_SEQ_TO_ARRAY, Macro, Array, (0, ()))
# define TRM_MAP(Macro, Array) \
TRM_EVAL(TRM_MAP_SEQ, Macro, Array, TRM_NIL)
# define TRM_APPLY_HELPER(R, Macro, Seq) Macro(Elt) # define TRM_APPLY_HELPER(R, Macro, Elt) Macro(Elt)
# define TRM_APPLY_(Macro, Seq) \ # define TRM_APPLY_(Macro, Seq) \
BOOST_PP_SEQ_FOR_EACH(TRM_MAP_HELPER, Macro, Seq) BOOST_PP_SEQ_FOR_EACH(TRM_MAP_HELPER, Macro, Seq)
# define TRM_APPLY(Macro, Seq) \ # define TRM_APPLY_SEQ(Macro, Seq) \
TRM_IF_EMPTY_SEQ(Seq, TRM_NIL_2, TRM_APPLY_)(Macro, Seq) TRM_APPLY_(Macro, Seq)
# define TRM_APPLY(Macro, Array) \
TRM_EVAL(TRM_APPLY_, Macro, Array, TRM_NIL)
# define TRM_HEAD(Seq) BOOST_PP_SEQ_HEAD(Seq) # define TRM_HEAD(Seq) BOOST_PP_SEQ_HEAD(Seq)
# define TRM_TAIL(Seq) BOOST_PP_SEQ_TAIL(Seq) # define TRM_TAIL(Seq) BOOST_PP_SEQ_TAIL(Seq)
# define TRM_SEPARATE_COMMA_HELPER(Elt) , Elt # define TRM_SEPARATE_COMMA_HELPER(Elt) , Elt
# define TRM_SEPARATE_COMMA_(Seq) \ # define TRM_SEPARATE_COMMA_(_, Seq) \
TRM_HEAD(Seq) TRM_APPLY(TRM_SEPARATE_COMMA_HELPER, TRM_TAIL(Seq)) TRM_HEAD(Seq) TRM_APPLY_SEQ(TRM_SEPARATE_COMMA_HELPER, TRM_TAIL(Seq))
# define TRM_SEPARATE_COMMA(Seq) \ # define TRM_SEPARATE_COMMA_SEQ(Seq) \
TRM_IF_EMPTY_SEQ(Seq, TRM_NIL_1, TRM_SEPARATE_COMMA_)(Seq) TRM_SEPARATE_COMMA_(dummy, Seq)
# define TRM_SEPARATE_COMMA(Array) \
TRM_EVAL(TRM_SEPARATE_COMMA_, dummy, Array, TRM_NIL)
# define TRM_TYPE_REF(Type, Name) (const Type&, Type &, Name)
# define TRM_TYPE_COPY(Type, Name) (const Type, Type &, Name) # define TRM_TYPE_REF(Type, Name) const Type&, Type &, Name
# define TRM_TYPE_COPY(Type, Name) const Type, Type &, Name
# define TRM_TYPE_TERM(Type, Name) TRM_TYPE_COPY(A ## Type, Name) # define TRM_TYPE_TERM(Type, Name) TRM_TYPE_COPY(A ## Type, Name)
# define TRM_CONST_ABSTRACT_COPY_DECL(Copy, Ref, Name) Copy Name; # define TRM_CONST_ABSTRACT_COPY_DECL(Copy, Ref, Name) Copy Name;
@ -183,10 +246,16 @@ namespace term
// with the expected arguments. // with the expected arguments.
# define TRM_GRAMMAR_NODE_CTR(Name, Base, Attributes, BaseArgs) \ # define TRM_GRAMMAR_NODE_CTR(Name, Base, Attributes, BaseArgs) \
private: \ private: \
Name ( TRM_SEPARATE_COMMA(TRM_MAP(TRM_CONST_ABSTRACT_COPY_ARG, \ Name ( TRM_SEPARATE_COMMA( \
Attributes BaseArgs)) ) \ TRM_MAP_ARRAY(TRM_CONST_ABSTRACT_COPY_ARG, Attributes) \
: TRM_SEPARATE_COMMA(TRM_MAP(TRM_INIT_ATTRIBUTES, Attributes)) , \ ) ) \
parent( TRM_SEPARATE_COMMA(TRM_MAP(TRM_ARGUMENTS, BaseArgs)) ) \ : TRM_SEPARATE_COMMA_SEQ( \
TRM_MAP(TRM_INIT_ATTRIBUTES, Attributes) \
( parent(TRM_SEPARATE_COMMA( \
TRM_MAP_ARRAY(TRM_ARGUMENTS, BaseArgs) \
)) \
) \
) \
{ \ { \
} }
@ -200,9 +269,17 @@ namespace term
public: \ public: \
static inline \ static inline \
term \ term \
make ## Name(const APattern a1, const AExpr a2, const APos a3) \ make ## Name( \
TRM_SEPARATE_COMMA( \
TRM_MAP_ARRAY(TRM_CONST_ABSTRACT_COPY_ARG, Attributes) \
) \
) \
{ \ { \
return term(get_identity(this_type(a1, a2, a3))); \ return term(get_identity(this_type( \
TRM_SEPARATE_COMMA( \
TRM_MAP_ARRAY(TRM_ARGUMENTS, Attributes) \
) \
))); \
} }
@ -215,9 +292,10 @@ namespace term
static inline \ static inline \
bool \ bool \
match ## Name( \ match ## Name( \
const ATerm t, \ TRM_SEPARATE_COMMA_SEQ( \
TRM_SEPARATE_COMMA(TRM_MAP(TRM_ABSTRACT_REF_ARG, \ ( const ATerm t ) \
Attributes BaseArgs)) \ TRM_MAP(TRM_ABSTRACT_REF_ARG, Attributes) \
) \
) \ ) \
{ \ { \
this_type* ptr; \ this_type* ptr; \
@ -225,8 +303,10 @@ namespace term
{ \ { \
TRM_MAP(TRM_COPY_IN_ARG, Attributes); \ TRM_MAP(TRM_COPY_IN_ARG, Attributes); \
return parent::match ## Base ( \ return parent::match ## Base ( \
t, \ TRM_SEPARATE_COMMA_SEQ( \
TRM_SEPARATE_COMMA(TRM_MAP(TRM_ARGUMENTS, BaseArgs)) \ ( t ) \
TRM_MAP(TRM_ARGUMENTS, BaseArgs) \
) \
); \ ); \
} \ } \
return false; \ return false; \
@ -256,7 +336,6 @@ namespace term
// implementation of the term. This class is a wrapper over a pointer which // implementation of the term. This class is a wrapper over a pointer which
// should derivate from the ATerm class. // should derivate from the ATerm class.
# define TRM_ABSTRACT_GRAMMAR_NODE(Name, Base, Attributes, BaseArgs, NoTemplate) \ # define TRM_ABSTRACT_GRAMMAR_NODE(Name, Base, Attributes, BaseArgs, NoTemplate) \
class Name; \
class A ## Name : public A ## Base \ class A ## Name : public A ## Base \
{ \ { \
typedef A ## Base parent; \ typedef A ## Base parent; \
@ -309,9 +388,9 @@ namespace term
TRM_GRAMMAR_NODE_MATCH_METHOD(Name, Base, Attributes, BaseArgs) \ TRM_GRAMMAR_NODE_MATCH_METHOD(Name, Base, Attributes, BaseArgs) \
\ \
public: \ public: \
void accept(ATermVisitor& v) const \ ATerm accept(ATermVisitor& v) const \
{ \ { \
v.visit(*this); \ return v.visit(*this); \
} \ } \
\ \
TRM_LESS_GRAMMAR_NODE_OP(Name, Base, Attributes, BaseArgs) \ TRM_LESS_GRAMMAR_NODE_OP(Name, Base, Attributes, BaseArgs) \
@ -322,59 +401,18 @@ namespace term
using Name::match ## Name; using Name::match ## Name;
# define TRM_GRAMMAR_NODE_BINOP(Final, Name) \ # define TRM_INTERFACE(Name, Base, Attributes, BaseArgs) \
Final(Name, Expr, (TRM_TYPE_TERM(Expr, lhs) \ TRM_ABSTRACT_GRAMMAR_NODE(Name, Base, Attributes, BaseArgs, TRM_NIL_ARGS) \
TRM_TYPE_TERM(Expr, rhs)), TRM_NIL) TRM_INTERFACE_GRAMMAR_NODE(Name, Base, Attributes, BaseArgs)
# define TRM_GRAMMAR_NODE_SINGLETON(Final, Name) \ # define TRM_FINAL(Name, Base, Attributes, BaseArgs) \
Final(Name, Expr, TRM_NIL, TRM_NIL) TRM_ABSTRACT_GRAMMAR_NODE(Name, Base, Attributes, BaseArgs, TRM_ADD_FRIEND) \
TRM_FINAL_GRAMMAR_NODE(Name, Base, Attributes, BaseArgs)
TRM_GRAMMAR_NODES(TRM_INTERFACE, TRM_FINAL)
// Test case. This should be moved inside the libexpr or generated in # undef TRM_FINAL
// another manner. # undef TRM_INTERFACE
# define TRM_GAMMAR_NODES(Interface, Final)
Interface(Loc, Term, TRM_NIL, TRM_NIL)
Interface(Pattern, Term, TRM_NIL, TRM_NIL)
Interface(Expr, Term, TRM_NIL, TRM_NIL)
Final(Pos, Loc, (TRM_TYPE_REF(std::string, file)
TRM_TYPE_COPY(int, line)
TRM_TYPE_COPY(int, column)), TRM_NIL)
Final(NoPos, Loc, TRM_NIL, TRM_NIL)
Final(String, Expr, (TRM_TYPE_REF(std::string, value)), TRM_NIL)
Final(Var, Expr, (TRM_TYPE_REF(std::string, name)), TRM_NIL)
Final(Path, Expr, (TRM_TYPE_REF(std::string, filename)), TRM_NIL)
Final(Int, Expr, (TRM_TYPE_COPY(int, value)), TRM_NIL)
Final(Function, Expr, (TRM_TYPE_TERM(Pattern, pattern)
TRM_TYPE_TERM(Expr, body)
TRM_TYPE_TERM(Pos, position)), TRM_NIL)
Final(Assert, Expr, (TRM_TYPE_TERM(Expr, cond)
TRM_TYPE_TERM(Expr, body)
TRM_TYPE_TERM(Pos, position)), TRM_NIL)
Final(With, Expr, (TRM_TYPE_TERM(Expr, set)
TRM_TYPE_TERM(Expr, body)
TRM_TYPE_TERM(Pos, position)), TRM_NIL)
Final(If, Expr, (TRM_TYPE_TERM(Expr, cond)
TRM_TYPE_TERM(Expr, thenPart)
TRM_TYPE_TERM(Expr, elsePart)), TRM_NIL)
Final(OpNot, Expr, (TRM_TYPE_TERM(Expr, cond)), TRM_NIL)
TRM_GRAMMAR_NODE_BINOP(Final, OpEq)
TRM_GRAMMAR_NODE_BINOP(Final, OpNEq)
TRM_GRAMMAR_NODE_BINOP(Final, OpAnd)
TRM_GRAMMAR_NODE_BINOP(Final, OpOr)
TRM_GRAMMAR_NODE_BINOP(Final, OpImpl)
TRM_GRAMMAR_NODE_BINOP(Final, OpUpdate)
TRM_GRAMMAR_NODE_BINOP(Final, SubPath)
TRM_GRAMMAR_NODE_BINOP(Final, OpHasAttr)
TRM_GRAMMAR_NODE_BINOP(Final, OpPlus)
TRM_GRAMMAR_NODE_BINOP(Final, OpConcat)
Final(Call, Expr, (TRM_TYPE_TERM(Expr, function)
TRM_TYPE_TERM(Expr, argument)), TRM_NIL)
Final(Select, Expr, (TRM_TYPE_TERM(Expr, set)
TRM_TYPE_TERM(Var, var)), TRM_NIL)
Final(BlackHole, Expr, TRM_NIL, TRM_NIL)
Final(Undefined, Expr, TRM_NIL, TRM_NIL)
Final(Removed, Expr, TRM_NIL, TRM_NIL)
/* /*
class AExpr : public ATerm class AExpr : public ATerm
@ -510,7 +548,6 @@ namespace term
*/ */
/*
template <typename T> template <typename T>
class getVisitor : ATermNoOpVisitor class getVisitor : ATermNoOpVisitor
{ {
@ -520,9 +557,10 @@ namespace term
t.accept(*this); t.accept(*this);
} }
visit(const T& t) ATerm visit(const T& t)
{ {
res = std::pair(true, &t); res = std::pair(true, &t);
return ATermNul();
} }
std::pair<bool, T*> res; std::pair<bool, T*> res;
@ -535,7 +573,14 @@ namespace term
getVisitor v(t); getVisitor v(t);
return v.res; return v.res;
} }
*/
template <typename T>
T
as(Aterm t)
{
getVisitor v(t);
return v.res;
}
} }
#endif #endif

34
src/libterm/test.cc Normal file
View file

@ -0,0 +1,34 @@
#include <vector>
#define TRM_GRAMMAR_NODES(Interface, Final) \
Interface(Expr, Term, (0, ()), (0, ())) \
TRM_GRAMMAR_NODE_BINOP(Final, Plus) \
Final(Int, Expr, (1, (TRM_TYPE_COPY(int, value))), (0, ()))
#include "term.hh"
#undef TRM_GRAMMAR_NODES
class Eval : public term::ATermVisitor
{
int run(const ATerm t)
{
return term::as<AInt>(t.accept(*this))().value;
}
ATerm visit(const APlus p)
{
return makeInt(run(p().lhs) + run(p().rhs));
}
};
int main()
{
AInt a = makeInt(1);
AInt b = makeInt(2);
AInt c = makeInt(1);
assert(a == c);
Eval e();
return e.run(makePlus(a, makePlus(b, c)));
}