Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

sexpress.hpp

Go to the documentation of this file.
00001 // +-------------------------------------------------------------------------+
00002 // |               I__n__t__e__L__i__b           0.6.10 development          |
00003 // | Copyright (c) Andrey Vikt. Stolyarov <crocodil_AT_croco.net> 2000-2007. |
00004 // |                                                                         |
00005 // | This is free software. The library part is available under              |
00006 // |                               GNU LESSER GENERAL PUBLIC LICENSE v.2.1.  |
00007 // | GNU LGPL v2.1 is found in docs/gnu_gpl2.txt,  or at  http://www.gnu.org |
00008 // |     Please see also docs/readme.txt and visit http://www.intelib.org    |
00009 // |                                                                         |
00010 // | !!! THERE IS NO WARRANTY OF ANY KIND, NEITHER EXPRESSED NOR IMPLIED !!! |
00011 // +-------------------------------------------------------------------------+
00012 
00013 
00014 
00015 
00029 #ifndef INTELIB_SEXPRESS_HPP_SENTRY
00030 #define INTELIB_SEXPRESS_HPP_SENTRY
00031 
00032 #include "refcount.hpp"
00033 
00034 
00036 extern const char *the_intelib_title;
00037 
00039 extern const char *the_intelib_copyright;
00040 
00042 extern const int the_intelib_numberic_version;
00043 
00044 /* ------------------------------------------------------- */
00045 /* The main defaults                                       */
00046 
00047 #ifndef INTELIB_INTEGER_T 
00048 
00049 #define INTELIB_INTEGER_T int
00050 #endif 
00051  
00052 #ifndef INTELIB_FLOAT_T
00053 
00054 #define INTELIB_FLOAT_T float
00055 #endif 
00056 
00057 #ifndef INTELIB_SIMPLE_STRING_LIMIT
00058 
00059 #define INTELIB_SIMPLE_STRING_LIMIT sizeof(char*)
00060 #endif
00061  
00062 #ifndef INTELIB_TEXT_REPRESENTATIONS
00063 
00064 #define INTELIB_TEXT_REPRESENTATIONS 1
00065 #endif
00066 
00067 #if INTELIB_TEXT_REPRESENTATIONS == 1
00068 #  ifndef INTELIB_INTEGER_FORMAT
00069 
00070 #  define INTELIB_INTEGER_FORMAT "%d"
00071 #  endif
00072 #  ifndef INTELIB_FLOAT_FORMAT
00073 
00074 #  define INTELIB_FLOAT_FORMAT "%f"
00075 #  endif
00076 #endif
00077 
00078 #ifndef INTELIB_RUNTIME_CHECKS
00079 
00080 #define INTELIB_RUNTIME_CHECKS 1
00081 #endif
00082 
00083 #ifndef INTELIB_DEBUG_COUNTERS
00084 
00085 
00086 #define INTELIB_DEBUG_COUNTERS 0
00087 #endif
00088 
00090 typedef INTELIB_INTEGER_T intelib_integer_t;
00091 
00093 typedef INTELIB_FLOAT_T intelib_float_t;
00094 
00096 
00100 const unsigned int intelib_simple_string_limit 
00101                           = INTELIB_SIMPLE_STRING_LIMIT;
00102 
00103 /* ------------------------------------------------------- */
00104 
00106 
00113 class IntelibTypeId {
00115     const IntelibTypeId *prev;
00116     bool changeable;
00117 public:
00119 
00120     IntelibTypeId() 
00121         : changeable(false) { prev = 0; }
00123     IntelibTypeId(const IntelibTypeId *previous) 
00124         : changeable(previous->changeable) { prev = previous; }
00126     IntelibTypeId(const IntelibTypeId *previous, bool a_changeable) 
00127         : changeable(a_changeable) { prev = previous; }
00129     ~IntelibTypeId() {}
00130 
00132     const IntelibTypeId* Prev() const { return prev; } 
00133 
00135     bool IsSubtypeOf(const IntelibTypeId &op) const; 
00137     bool operator==(const IntelibTypeId &op) const
00138        { return &op == this; } 
00140     bool operator!=(const IntelibTypeId &op) const
00141        { return &op != this; } 
00142 
00144     bool IsChangeable() const { return changeable; }
00145 
00146 #if INTELIB_DEBUG_COUNTERS == 1
00147     mutable long object_counter; 
00148 #endif
00149 private:
00150     // disallow copying
00151     IntelibTypeId(const IntelibTypeId &) {} 
00152 };
00153 
00154 #if INTELIB_TEXT_REPRESENTATIONS == 1
00155 class SString; // we need it before it is defined, for text representations
00156 #endif
00157 
00159 
00162 class SExpression : public GarbageSafe {
00164     const IntelibTypeId *term_type_id;
00165 public:
00167 
00174     static IntelibTypeId TypeId;
00175 
00177 
00180     SExpression(const IntelibTypeId &the_type);
00181 
00182 protected:
00184 
00192     virtual ~SExpression();
00193 public:
00195     const IntelibTypeId& TermType() const { return *term_type_id; }
00196 
00198     bool IsChangeable() const { return term_type_id->IsChangeable(); }
00199 
00201 
00214     virtual SExpression* Clone() const { return 0; }
00215      
00216 
00217 #if INTELIB_TEXT_REPRESENTATIONS == 1
00218 
00219 
00223     virtual class SString TextRepresentation() const = 0;
00224 #endif
00225 
00227 
00235     virtual bool SpecificEql(const SExpression* /*other*/) const 
00236         { return false; }
00237 private:
00239     SExpression(const SExpression&) {}
00241     void operator = (const SExpression&) {}
00242 
00243 #if INTELIB_DEBUG_COUNTERS == 1
00244 public:
00245     static long object_counter; 
00246 #endif
00247 };
00248 
00250 
00255 class SExpressionInt : public SExpression {
00256     intelib_integer_t data;
00257 public:
00258     static IntelibTypeId TypeId;
00259     SExpressionInt() : SExpression(TypeId) { data = 0; }
00260     SExpressionInt(char d) : SExpression(TypeId) { data = d; }
00261     SExpressionInt(short int d) : SExpression(TypeId) { data = d; }
00262     SExpressionInt(int d) : SExpression(TypeId) { data = d; }
00263     SExpressionInt(long int d) : SExpression(TypeId) { data = d; }
00264     SExpressionInt(long long int d) : SExpression(TypeId) { data = d; }
00265     SExpressionInt(unsigned char d) : SExpression(TypeId) { data = d; }
00266     SExpressionInt(unsigned short int d) : SExpression(TypeId) { data = d; }
00267     SExpressionInt(unsigned int d) : SExpression(TypeId) { data = d; }
00268     SExpressionInt(unsigned long int d) : SExpression(TypeId) { data = d; }
00269     SExpressionInt(unsigned long long int d) 
00270         : SExpression(TypeId) { data = d; }
00271  
00272     intelib_integer_t GetValue() const { return data; }
00273 
00274 #if INTELIB_TEXT_REPRESENTATIONS == 1
00275 
00278     virtual SString TextRepresentation() const;
00279 #endif
00280 
00281 protected:
00282     virtual ~SExpressionInt() {}
00283     
00284     virtual bool SpecificEql(const SExpression* other) const;
00285 };
00286 
00288 
00292 class SExpressionFloat : public SExpression {
00293     intelib_float_t data;
00294 public:
00295     static IntelibTypeId TypeId;
00296     SExpressionFloat() : SExpression(TypeId) { data = 0; }
00297     SExpressionFloat(float d) : SExpression(TypeId) { data = d; }
00298     SExpressionFloat(double d) : SExpression(TypeId) { data = d; }
00299     SExpressionFloat(long double d) : SExpression(TypeId) { data = d; }
00300  
00301     intelib_float_t GetValue() const { return data; }
00302 
00303 #if INTELIB_TEXT_REPRESENTATIONS == 1
00304 
00307     virtual SString TextRepresentation() const;
00308 #endif
00309 
00310 protected:
00311     virtual ~SExpressionFloat() {}
00312     
00313     virtual bool SpecificEql(const SExpression* other) const;
00314 };
00315 
00317 
00322 class SExpressionChar : public SExpression {
00323     char s[2];
00324 public: 
00325     static IntelibTypeId TypeId;
00326 
00327     SExpressionChar(int c) : SExpression(TypeId) { s[0] = c; s[1] = 0; }
00328 
00329 protected:
00330     ~SExpressionChar() {}
00331     virtual bool SpecificEql(const SExpression* other) const;
00332 
00333 public:
00334     char GetValue() const { return s[0]; }
00335     const char *GetString() const { return s; }
00336 
00337 #if INTELIB_TEXT_REPRESENTATIONS == 1
00338 
00342     virtual SString TextRepresentation() const;
00343 #endif
00344 };
00345 
00346 
00348 
00353 class SExpressionString : public SExpression {
00355 
00359     bool is_indirect;
00360     union {
00361         char *p;
00362         char s[intelib_simple_string_limit];
00363     } str;
00365     void StringSetup(const char *s); 
00366 public: 
00367     static IntelibTypeId TypeId;
00368 
00369     SExpressionString() : SExpression(TypeId) 
00370              { is_indirect = 0; str.s[0] = 0; } // just empty string
00371     SExpressionString(const char *s); 
00373 
00375     SExpressionString(const char *s1, const char *s2);
00376 
00377 protected:
00379 
00380     SExpressionString(const IntelibTypeId &tid, const char *s);
00381     ~SExpressionString();    
00382 
00383 public:
00384     const char* GetValue() const
00385       { return is_indirect ? str.p : str.s; }
00386 
00387 #if INTELIB_TEXT_REPRESENTATIONS == 1
00388 
00392     virtual SString TextRepresentation() const;
00393 #endif
00394 
00395 protected:
00396     virtual bool SpecificEql(const SExpression* other) const;
00397 };
00398 
00400 
00407 class SExpressionClassicAtom : public SExpressionString {
00408 public:
00409     static IntelibTypeId TypeId;
00410     SExpressionClassicAtom(const char *s) : SExpressionString(TypeId, s) {}
00411     virtual SString TextRepresentation() const; 
00412       // Note we don't need to write specific SpecificEql function. 
00413       // It's version of SExpressionString will perfectly serve us.
00414 protected:
00415     ~SExpressionClassicAtom() {}
00416 };
00417 
00418 
00420 
00431 #if INTELIB_TEXT_REPRESENTATIONS == 1
00432 class SExpressionLabel : public SExpression {
00433     char *name;
00434 protected:
00435     SExpressionLabel(const IntelibTypeId &the_type, const char *a_name);
00436 public:
00437     static IntelibTypeId TypeId;
00438     SExpressionLabel(const char *a_name);
00439     virtual SString TextRepresentation() const;
00440     const char* GetName() const { return name; }
00441 protected:
00442     ~SExpressionLabel();
00443 };
00444 #else
00445 class SExpressionLabel : public SExpression {
00446 protected:
00447     SExpressionLabel(const IntelibTypeId &the_type, const char*)
00448         : SExpression(the_type) {}
00449     ~SExpressionLabel() {}
00450 public:
00451     static IntelibTypeId TypeId;
00452     SExpressionLabel(const char* /*a_name*/) : SExpression(TypeId) {}
00453     const char* GetName() const { return ""; }
00454 };
00455 #endif
00456 
00457 
00459 
00467 class SReference : public GenericReference<SExpression> {
00468 public:
00470 
00471     SReference() {}       
00472 
00474     SReference(const SExpression *tp) : GenericReference<SExpression>(tp) {} 
00475 
00477     SReference(const SReference &other) 
00478         : GenericReference<SExpression>
00479           (static_cast<const GenericReference<SExpression>&>(other)){}
00480     ~SReference() {}
00481    
00483 
00486     SReference(char c);
00487     SReference(signed char c);
00488     SReference(unsigned char c);
00489     SReference(signed short i);
00490     SReference(unsigned short i);
00491     SReference(signed int i);
00492     SReference(unsigned int i);
00493     SReference(signed long i);
00494     SReference(unsigned long i);
00495     SReference(signed long long i);
00496     SReference(unsigned long long i);
00497     SReference(float f);
00498     SReference(double f);
00499     SReference(long double f);
00500     SReference(const char *s);
00501     SReference(const unsigned char *s);
00503 
00504     SReference(const class SListConstructor &); 
00506     SReference(const SReference &car, const SReference &cdr);
00507 
00508     SReference& operator=(const SReference &other)
00509       { GenericReference<SExpression>::operator=(other); return *this; }
00510     void operator=(SExpression* newterm)
00511       { GenericReference<SExpression>::operator=(newterm); }
00512 
00513     SExpression* GetPtr() const 
00514       { return (SExpression*)GenericReference<SExpression>::GetPtr(); }
00515 
00517 
00520     SReference& AddAnotherItemToList(const SReference &right); 
00522 
00529     SReference& ChangeListEnd(const SReference &new_last); 
00531 
00534     SReference MakeCons(const SReference &right) const;
00535 
00537 
00541     SReference& operator,(const SReference &r) 
00542         { return AddAnotherItemToList(r); }
00544 
00548     SReference& operator||(const SReference &t) 
00549         { return ChangeListEnd(t); }
00551 
00552     SReference operator^(const SReference &t) const 
00553         { return MakeCons(t); }
00554 
00556     bool operator == (const SReference &other) const
00557       { return GetPtr() == other.GetPtr(); }
00559     bool operator != (const SReference &other) const 
00560       { return GetPtr() != other.GetPtr(); }
00562     bool operator == (const SExpression *other) const
00563       { return GetPtr() == other; }
00565     bool operator != (const SExpression *other) const
00566       { return GetPtr() != other; }
00567 
00568     bool IsEql(const SReference &other) const;
00569     bool IsEqual(const SReference &other) const;
00570 
00571     SReference& Car() const; 
00572     SReference& Cdr() const;
00573     SReference& CCar() const; 
00574     SReference& CCdr() const;
00575     intelib_float_t GetFloat() const;
00576     intelib_integer_t GetInt() const;
00577     const char* GetString() const;
00578     char GetSingleChar() const;
00579 
00580     template<class Tp> Tp* DynamicCastGetPtr() const;
00581     template<class Tp> Tp* SimpleCastGetPtr() const;
00582 
00583     SReference Clone() const;
00584     SReference CopyList() const;
00585     SReference CopyTree() const;
00586 
00587     bool IsEmptyList() const; 
00588 
00589 };
00590 
00591 
00593 class SLabel : public SReference {
00594 public:
00595     SLabel(const char *name) : SReference(new SExpressionLabel(name)) {}
00596 private: /* note all operations prohibited */
00597     SLabel(const SLabel &) {}
00598     void operator=(const SLabel &) {}
00599     void operator=(const SReference &) {}
00600     void operator=(const SExpression*) {}
00601 };
00602 
00604 
00606 class SExpressionCons : public SExpression {
00608     SReference car;
00610     SReference cdr;
00611 protected:
00612     SExpressionCons(const SReference &acar, const SReference &acdr,
00613                     const IntelibTypeId &tid)
00614            : SExpression(tid), car(acar), cdr(acdr) {}
00615 public:
00616     static IntelibTypeId TypeId;
00617 
00618     SExpressionCons(const SReference &acar, const SReference &acdr)
00619            : SExpression(TypeId), car(acar), cdr(acdr) {}
00620     ~SExpressionCons(){} 
00621 
00622     SReference& Car() { return car; }
00623     SReference& Cdr() { return cdr; }
00624     const SReference& Car() const { return car; }
00625     const SReference& Cdr() const { return cdr; }
00626 
00627     virtual SExpression* Clone() const; 
00628 
00629 #if INTELIB_TEXT_REPRESENTATIONS == 1
00630 
00643     SString CoreTextRepresentation(const char *delim, 
00644                                    const char *dotdelim,
00645                                    SString (*repfun)(const SReference &)=0) 
00646             const;
00650     virtual SString TextRepresentation() const;
00651 #endif
00652 };
00653 
00654 
00656 
00663 extern SReference *PTheEmptyList;
00664 
00665 
00667 
00675 class SListConstructor {
00676 public:
00677     SListConstructor() {}
00678     ~SListConstructor() {}
00679     
00680     SReference operator |(const SReference &t) const
00681         { return SReference(new SExpressionCons(t, *PTheEmptyList)); } 
00682     SReference operator ^(const SReference &other) const
00683         { return SReference(*PTheEmptyList, other); }
00684 };
00685 
00686 
00687 template<class Tp> Tp* SReference::DynamicCastGetPtr() const
00688 {
00689     if(GetPtr() && GetPtr()->TermType().IsSubtypeOf(Tp::TypeId)) 
00690         return (Tp*)GetPtr(); 
00691     else
00692         return 0;
00693 }
00694 
00695 template<class Tp> Tp* SReference::SimpleCastGetPtr() const
00696 {
00697     if(GetPtr() && &(GetPtr()->TermType()) == &(Tp::TypeId)) 
00698         return (Tp*)GetPtr(); 
00699     else
00700         return 0;
00701 }
00702 
00703 
00704 
00705 #endif

Generated on Tue Dec 18 00:39:45 2007 for InteLib by  doxygen 1.4.1