00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00151 IntelibTypeId(const IntelibTypeId &) {}
00152 };
00153
00154 #if INTELIB_TEXT_REPRESENTATIONS == 1
00155 class SString;
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* ) 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; }
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
00413
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* ) : 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:
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