/* * TokenConstraint.h * * Created on: Feb 11, 2010 * Author: petergoodman * Version: $Id$ */ #ifndef TOKENSTACKCONSTRAINT_H_ #define TOKENSTACKCONSTRAINT_H_ #include #include #include #include "Token.h" using namespace std; /** * This was fun. Handle checking of the stack. This is an example of me * having fun learning the C++ type system. */ namespace TS { typedef deque ts; /** * Exception type for constraint errors. Lets us figure out when a * constraint has failed. */ struct ConstraintError : public runtime_error { explicit ConstraintError(const string &s="") : runtime_error(s) { } virtual ~ConstraintError() throw() { } }; /* A constraint type that succeeds. */ struct True { True(ts &s, ts::size_type e=0) { (void) s; (void) e; }}; /* constraint type that fails */ struct False { False(ts &s, ts::size_type e=0) { (void) s; (void) e; throw ConstraintError(); }}; /* Make sure the stack is no smaller than a certain amount */ template struct MinSize { MinSize(ts &s, ts::size_type e=0) { (void) e; if(s.size() < n) { stringstream ss; ss << "Stack must have at least " << n << " elements."; throw ConstraintError(ss.str()); } } }; /* specialize to do nothing on zero */ template<> struct MinSize<0UL> { MinSize(ts &s, ts::size_type e=0) { (void) s; (void) e; }}; /* make sure the stack is not empty, i.e. min size = 1 */ struct NotEmpty : public MinSize<1UL> { NotEmpty(ts &s, ts::size_type e=0) : MinSize<1UL>(s, e) { } }; /* require two constraints to be met. */ template struct And { And(ts &s, ts::size_type e=0) { A(s, e); B(s, e+1); } }; /* special case for when not empty is a type parameter, we don't want to * increment e. */ template struct And { And(ts &s, ts::size_type e=0) { NotEmpty(s, e); B(s, e); } }; /* special case for min size, don't increment e. */ template struct And, B> { And(ts &s, ts::size_type e=0) { MinSize(s, e); B(s, e); } }; /* constraint on token type. */ template struct Type { Type(ts &s, ts::size_type e=0) { Token *tok(s[s.size() - e - 1]); if(tok->type != ty) { stringstream ss; ss << "Parameter " << e << " expected to be of type " << ty << " got " << tok << " instead."; throw ConstraintError(ss.str()); } } }; } #endif /* TOKENSTACKCONSTRAINT_H_ */