#ifndef _Ty_H_ #define _Ty_H_ /* Types */ #include "utils.h" #include "int2string.h" #include "userdata.h" #include #include class Ty; // External users should prefer t->indexed_type() to indexed_type(t). */ extern Ty *indexed_type(const Ty *t, bool strict); extern bool has_indexed_type(const Ty *t); class Ty { public: Ty() {} virtual ~Ty() {} Ty(const char *s, int n_ = 0) : userdata((void *) s), stringify(&chars2string), n(n_) {} Ty(string *s, int n_ = 0) : userdata((void *) s), stringify(&string2string), n(n_) {} Ty(string s, int n_ = 0) : userdata((void *) new string(s)), stringify(&string2string), n(n_) {} virtual const string *to_pstring() const { return (*stringify)(userdata); } const string &to_string() const { return *to_pstring(); } virtual void print(ostream &o) const { o << to_string(); } int arity() const { return n; } virtual const Ty *indexed_type(bool strict = true) const { return ::indexed_type(this, strict); } static Ty *setiTy; static Ty *psetiTy; static Ty *ppsetiTy; static Ty *ivsetiTy; static Ty *pivsetiTy; static Ty *rectTy(int n); static Ty *prectTy(int n); static Ty *doubleTy; static Ty *floatTy; static Ty *intTy; static Ty *pintTy; static Ty *ppintTy; static Ty *boolTy; private: void *userdata; const string * (*stringify)(void *userdata); protected: int n; }; class TyArray : public Ty { public: TyArray(Ty const *T, int arity) : base(T) { n = arity; } const string *to_pstring() const { return new string(base->to_string() + '[' + i2s(n) + ']'); } const Ty *indexed_type(bool) const { return base; } private: const Ty *base; }; class TyPtr : public Ty { public: TyPtr(Ty const *T) : base(T) {} const string *to_pstring() const { return new string(base->to_string() + " *"); } const Ty *indexed_type(bool) const { return base; } private: const Ty *base; }; class TyPoint : public Ty { public: TyPoint(int arity) : s("Point<" + i2s(arity) + ">") { n = arity; ; } const string *to_pstring() const { return &s; } const Ty *indexed_type(bool) const { return Ty::intTy; } private: const string s; }; extern Ty *RectDomain_Ty(int n); extern Ty *Domain_Ty(int n); static inline TyPoint *Point_Ty(int n) { return new TyPoint(n); } static inline TyPtr *pointer_to_Ty(Ty *t) { return new TyPtr(t); } static inline Ty *pointer_to_Ty(Ty *t, size_t n) { return n == 0 ? t : (--n, new TyPtr(pointer_to_Ty(t, n))); } #endif // _Ty_H_