Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /** \file lispatom.h
  2.  *  implementation of the standard lisp elements: atom and sublist.
  3.  *
  4.  * class LispAtom. This class implements one atom, which is a
  5.  * reference to a string it represents, and a pointer to the next
  6.  * lisp atom if it is in a list.
  7.  * It also has a pointer to the annotation object.
  8.  * The local class LispPtr implements automatic garbage collection
  9.  * through reference counting.
  10.  *
  11.  * The class LispNumber inherits from LispAtom and holds a numeric atom
  12.  * in the string representation and in the numeric representation (BigNumber).
  13.  * The string representation is converted to BigNumber (using the current precision for floats) when a numeric
  14.  * operation is first requested on the atom. The BigNumber representation is
  15.  * converted to the string representation whenever the number needs to be printed i.e. LispAtom::String() method is requested.
  16.  * The string is held in the number (to avoid repeated conversions) and also cached in the string cache (this caching will eventually be abandoned).
  17.  * When LispNumber is constructed from BigNumber, no string representation is available.
  18.  * Conversion from string to BigNumber is done only if no BigNumber object is present.
  19.  */
  20.  
  21. #ifndef __lispatom_h__
  22. #define __lispatom_h__
  23.  
  24. #include "yacasbase.h"
  25. #include "lispobject.h"
  26. #include "lispstring.h"
  27. #include "numbers.h"  // RefPtr<BigNumber> needs definition of BigNumber
  28.  
  29. /// This should be used whenever constants 2, 10 mean binary and decimal.
  30. // maybe move somewhere else?
  31. #define BASE10 10
  32. #define BASE2 2
  33.  
  34. // Flags used for atom types. These are not strictly necessary, but
  35. // do speed up certain evaluations by avoiding a lot of overhead.
  36. #define KFlagIsNumeric 0x01  // Quoted (after executing the args for
  37.                           // a LispLambda, or for a LispSetQuoted)
  38.  
  39. class LispEnvironment;
  40.  
  41. class LispAtom : public ObjectHelper<LispAtom>
  42. {
  43. public:
  44.   static LispObject* New(LispEnvironment& aEnvironment, const LispChar * aString);
  45.   virtual ~LispAtom();
  46.   virtual LispString * String();
  47.   virtual LispObject* Copy() { return NEW LispAtom(*this); }
  48. private:
  49.   LispAtom(LispString * aString);
  50.   LispAtom& operator=(const LispAtom& aOther)
  51.   {
  52.     // copy constructor not written yet, hence the assert
  53.     LISPASSERT(0);
  54.     return *this;
  55.   }
  56. public:
  57.   LispAtom(const LispAtom& other);
  58. private:
  59.   LispString * iString;
  60. };
  61.  
  62. //------------------------------------------------------------------------------
  63. // LispSublist
  64.  
  65. class LispSubList : public ObjectHelper<LispSubList>
  66. {
  67. public:
  68.   static LispSubList* New(LispObject* aSubList);
  69.   virtual ~LispSubList();
  70.   virtual LispPtr* SubList() { return &iSubList; }
  71.   virtual LispObject* Copy() { return NEW LispSubList(*this); }
  72. private:
  73.   // Constructor is private -- use New() instead
  74.   LispSubList(LispObject* aSubList) : iSubList(aSubList) {}  // iSubList's constructor is messed up (it's a LispPtr, duh)
  75. public:
  76.   LispSubList(const LispSubList& other) : ASuper(other), iSubList(other.iSubList) {}
  77. private:
  78.   LispPtr iSubList;
  79. };
  80.  
  81.  
  82. //------------------------------------------------------------------------------
  83. // LispGenericClass
  84.  
  85. class LispGenericClass : public ObjectHelper<LispGenericClass>
  86. {
  87. public:
  88.   static LispGenericClass* New(GenericClass* aClass);
  89.   virtual ~LispGenericClass();
  90.   virtual GenericClass* Generic();
  91.   virtual LispObject* Copy() { return NEW LispGenericClass(*this); }
  92. private:
  93.   // Constructor is private -- use New() instead
  94.   LispGenericClass(GenericClass* aClass);
  95. public:
  96.   LispGenericClass(const LispGenericClass& other) : ASuper(other), iClass(other.iClass) { iClass->iReferenceCount++; }
  97. private:
  98.   LispGenericClass& operator=(const LispGenericClass& other)
  99.   {
  100.     // copy constructor not written yet, hence the assert
  101.     LISPASSERT(0);
  102.     return *this;
  103.   }
  104. private:
  105.     GenericClass* iClass;
  106. };
  107.  
  108. class LispHashTable;
  109. class LispNumber : public ObjectHelper<LispNumber>
  110. {
  111. public:
  112.     /// constructors:
  113.     /// construct from another LispNumber
  114.   LispNumber(BigNumber* aNumber, LispString * aString = NULL) : iNumber(aNumber), iString(aString) {}
  115.   LispNumber(const LispNumber& other) : ASuper(other), iNumber(other.iNumber), iString(other.iString) {}
  116.   /// construct from a decimal string representation (also create a number object) and use aBasePrecision decimal digits
  117.   LispNumber(LispString * aString, LispInt aBasePrecision) : iNumber(NULL), iString(aString) { Number(aBasePrecision); }
  118.  
  119.   virtual ~LispNumber() {}
  120.   virtual LispObject* Copy() { return NEW LispNumber(*this); }
  121.   /// return a string representation in decimal with maximum decimal precision allowed by the inherent accuracy of the number
  122.   virtual LispString * String();
  123.   /// give access to the BigNumber object; if necessary, will create a BigNumber object out of the stored string, at given precision (in decimal?)
  124.   virtual BigNumber* Number(LispInt aPrecision);
  125. private:
  126.   /// number object; NULL if not yet converted from string
  127.   RefPtr<BigNumber> iNumber;
  128.   /// string representation in decimal; NULL if not yet converted from BigNumber
  129.   RefPtr<LispString> iString;
  130. };
  131.  
  132.  
  133. #endif
  134.  
  135.  
  136.