put ELAM into its own namespace
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sat, 13 Nov 2010 20:56:49 +0000 (20:56 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sat, 13 Nov 2010 20:56:49 +0000 (20:56 +0000)
start on parser

git-svn-id: https://silmor.de/svn/softmagic/elam/trunk@626 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

src/Doxyfile
src/dptr.h
src/elam.h
src/elamengine.cpp
src/elamengine.h
src/elamexpression.cpp [new file with mode: 0644]
src/elamexpression.h
src/elamintengine.cpp
src/elamintengine.h
src/elamvalue.cpp
src/elamvalue.h

index 8a9bff3..af2e34b 100644 (file)
@@ -137,7 +137,7 @@ SHORT_NAMES            = NO
 # comments will behave just like regular Qt-style comments
 # (thus requiring an explicit @brief command for a brief description.)
 
-JAVADOC_AUTOBRIEF      = NO
+JAVADOC_AUTOBRIEF      = YES
 
 # If the QT_AUTOBRIEF tag is set to YES then Doxygen will
 # interpret the first line (until the first dot) of a Qt-style
@@ -145,7 +145,7 @@ JAVADOC_AUTOBRIEF      = NO
 # will behave just like regular Qt-style comments (thus requiring
 # an explicit \brief command for a brief description.)
 
-QT_AUTOBRIEF           = NO
+QT_AUTOBRIEF           = YES
 
 # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
 # treat a multi-line C++ special comment block (i.e. a block of //! or ///
index 23a4d79..9b81c80 100644 (file)
@@ -6,58 +6,90 @@
 #ifndef DPTR_H
 #define DPTR_H
 
-/**Declares a smart d-pointer, to be used inside class declaration.
+/** \page dptr Automatic d-Pointers
+to be written
 
-It also declares the internal nested classes DPrivate and Private - Private is the actual d-pointer class, while DPrivate is a wrapper that automatically allocates and deallocates the d-pointer.
+\see dptr.h
+*/
+
+/** \file "dptr.h"
+Automatic d-Pointers Header File
+
+Please see \ref dptr "Automatic d-Pointers"
+for a tutorial.
+*/
+
+/** \brief Expands to the fully qualified name of the d-pointer class.
+\param Class the fully qualified name of the class the d-pointer was declared in.*/
+#define DPTR_CLASS_NAME(Class) Class::Private
+///Expands to the local name of d-pointer classes (Private).
+#define DPTR_NAME Private
+///Expands to the local name of the d-pointer wrapper class (DPrivate).
+#define DPTR_WRAPPER_NAME DPrivate
+
+/** \brief Declares a smart shared or non-shared d-pointer, to be used inside class declaration.
+
+It also declares the internal nested classes DPrivate and Private - Private is the actual d-pointer class, while DPrivate is a wrapper that automatically allocates, copies and deallocates the d-pointer.
+
+The wrapper DPointer class contains these methods:
+   - constructor, copy constructor for creating instances of Private
+    - used by automatic and explicit constructors of the containing class
+   - destructor for deallocation of Private
+    - used by the destructor of the containing class
+   - assignment operator to copy the content of Private
+    - used by the assignment operator of the containing class
+   - pointer operator to actually access the Private data
+
+You can use DEFINE_DPTR to define the necessary methods for a non-shared d-pointer or DEFINE_SHARED_DPTR if you want to share d-pointer data between instances of the containing class. It is recommended that non-shared d-pointer classes (Private) are derived from DPtr and the shared variants be derived from SharedDPtr.
+
+The d-pointer class Private is only forward declared, you have to fully declare and implement it in the code where you are using it, i.e. where you are implementing the containing class.
 
 \param dp name of the d-pointer*/
 #define DECLARE_DPTR(dp) \
+ private:\
  class Private; \
  class DPrivate{\
   public:DPrivate();DPrivate(const DPrivate&);~DPrivate();\
   DPrivate&operator=(const DPrivate&);\
-  Private*operator->()const{return d;}private:Private*d;\
+  Private*operator->()const{return d;}\
+  private:Private*d;\
  }; \
  DPrivate dp;
 
-/**Creates definitions for methods of the d-pointer wrapper, to be used in implementation where the actual d-pointer class is implemented.
+ /** \brief Alias for DECLARE_DPTR for convenience.
 
-\param Class the base class within which the d-pointer was declared*/
-#define DEFINE_DPTR(Class) \
- Class::DPrivate::DPrivate(){d=new Class::Private;};\
- Class::DPrivate::DPrivate(const Class::DPrivate&dp){d=new Class::Private(*(dp.d));};\
- Class::DPrivate::~DPrivate(){delete d;}\
- Class::DPrivate& Class::DPrivate::operator=(const Class::DPrivate&dp){*d=*(dp.d);return *this;}
+\param dp name of the d-pointer*/
+#define DECLARE_SHARED_DPTR(dp) DECLARE_DPTR(dp)
 
-/**Expands to the fully qualified name of the d-pointer class.
-\param Class the fully qualified name of the class the d-pointer was declared in.*/
-#define DPTR_CLASS_NAME(Class) Class::Private
-///Expands to the local name of d-pointer classes (Private).
-#define DPTR_NAME Private
+/** \brief Base class of non-shared d-pointers.
 
-/**Declares a smart shared d-pointer, to be used inside class declaration.
+Use in conjunction with DECLARE_DPTR and DEFINE_DPTR */
+class DPtr
+{
+       public:
+               ///instantiates a non-shared d-pointer
+               DPtr(){}
+               ///deletes a non-shared d-pointer
+               virtual ~DPtr(){}
+};
 
-It also declares the internal nested classes DPrivate and Private - Private is the actual d-pointer class, while DPrivate is a wrapper that automatically allocates and deallocates the d-pointer.
+/** \brief Creates definitions for methods of the non-shared d-pointer wrapper. 
 
-The d-pointer class must be derived from SharedDPtr in order to work with this macro.
+This variant is not shared between instances of the containing class.
 
-\param Class the base class within which the d-pointer was declared
-\param dp name of the d-pointer*/
-//public:\
-// Class& operator=(const Class&c){dp=c.dp;return *this;} 
-#define DECLARE_SHARED_DPTR(dp) \
-private:\
- class Private; \
- class DPrivate{public:\
-   DPrivate();DPrivate(const DPrivate&);~DPrivate();\
-   Private*operator->()const{return d;}\
-   DPrivate& operator=(const DPrivate&);\
-  private:\
-   Private*d;\
- }; \
- DPrivate dp;
+To be used in implementation where the actual d-pointer class is implemented.
+
+\param Class the base class within which the d-pointer was declared*/
+#define DEFINE_DPTR(Class) \
+ Class::DPrivate::DPrivate(){d=new Class::Private;}\
+ Class::DPrivate::DPrivate(const Class::DPrivate&dp){d=new Class::Private(*(dp.d));}\
+ Class::DPrivate::~DPrivate(){delete d;}\
+ Class::DPrivate& Class::DPrivate::operator=(const Class::DPrivate&dp)\
+ {*d=*(dp.d);return *this;}
 
-/**Base class of shared d-pointers. Use in conjunction with DECLARE_SHARED_DPTR and DEFINE_SHARED_DPTR */
+/** \brief Base class of shared d-pointers.
+
+Use in conjunction with DECLARE_SHARED_DPTR and DEFINE_SHARED_DPTR */
 class SharedDPtr
 {
        private:
@@ -73,14 +105,18 @@ class SharedDPtr
                virtual void detach(){cnt--;if(cnt==0)delete this;}
 };
 
-/**Defines the methods of the shared d-pointer wrapper, to be used in implementation where the actual d-pointer class is implemented.
+/** \brief Defines the methods of the shared d-pointer wrapper.
+
+This implements the shared version of the d-pointer wrapper.
+To be used in implementation where the actual d-pointer class is implemented.
 
 \param Class the base class within which the d-pointer was declared*/
 #define DEFINE_SHARED_DPTR(Class) \
  Class::DPrivate::DPrivate(){d=new Class::Private;}\
  Class::DPrivate::DPrivate(const DPrivate&dp){d=dp.d;d->attach();}\
  Class::DPrivate::~DPrivate(){d->detach();}\
- Class::DPrivate& Class::DPrivate::operator=(const DPrivate&dp){d->detach();d=dp.d;d->attach();return *this;}
+ Class::DPrivate& Class::DPrivate::operator=(const DPrivate&dp)\
+ {d->detach();d=dp.d;d->attach();return *this;}
 
 
 #endif
index f1f1887..8df3bdf 100644 (file)
@@ -7,7 +7,6 @@
 #define ELAM_LIB_H
 
 #include "elamengine.h"
-// #include "elamdefault.h"
-// #include "elamfunction.h"
+#include "elamintengine.h"
 
 #endif
index c7dde2e..1ec523c 100644 (file)
@@ -1,4 +1,4 @@
-// ELAM engine definition implementation
+//  engine definition implementation
 //
 // (c) Konrad Rosenbaum, 2010
 // protected under the GNU LGPL v3 or at your option any newer
 #include "elamengine.h"
 #include "elamvalue.h"
 
-class DPTR_CLASS_NAME(ELAMEngine)
+namespace ELAM {
+///////////////////////////////////////////////////////////////////////////////
+// Engine
+
+class DPTR_CLASS_NAME(Engine):public DPtr
 {
-       
+       public:
+               CharacterClassSettings cclass;
 };
+DEFINE_DPTR(Engine);
 
-DEFINE_DPTR(ELAMEngine);
-
-ELAMEngine::ELAMEngine(QObject* parent): QObject(parent)
+Engine::Engine(QObject* parent): QObject(parent)
 {
 
 }
 
-QVariant ELAMEngine::evaluate(QString ex)
+QVariant Engine::evaluate(QString ex)
 {
-       return evaluate(parseExpression(ex));
+       return evaluate(expression(ex));
 }
 
-QVariant ELAMEngine::evaluate(ELAMExpression ex)
+QVariant Engine::evaluate(Expression ex)
 {
+       Q_UNUSED(ex);
        //TODO: implement
        return QVariant();
 }
 
-ELAMExpression ELAMEngine::parseExpression(QString )
+Expression Engine::expression(QString s)
+{
+       return Expression(tokenize(s));
+}
+
+Expression Engine::expression(QList< Token > )
 {
        //TODO: implement parser
-       return ELAMExpression();
+       return Expression();
+}
+
+QList< Token > Engine::tokenize(QString ex)
+{
+       Token::Type ctype=Token::Invalid;
+       QString ctok;
+       QList<Token> ret;
+       int cline=1,ccol=0;
+       int sline=cline,scol=ccol;
+       for(int i=0;i<ex.size();i++){
+               if(ex[i]=='\n'){cline++;ccol=0;}
+               ccol++;
+               //if we have a type: check that we are still in it
+               Token::Type ntype=d->cclass.charType(ex[i],ctype);
+               //check for invalid stuff
+               if(ntype==Token::Invalid)
+                       return QList<Token>()<<Token(Position(sline,scol));
+               //check whether we are still inside the same token
+               if(ntype==ctype)
+                       ctok+=ex[i];
+               else{
+                       if(ctype!=Token::Invalid)
+                               ret<<Token(ctok,ctype,Position(sline,scol));
+                       ctype=ntype;
+                       ctok.clear();
+                       sline=cline;
+                       scol=ccol;
+               }
+       }
+       return ret;
+}
+
+CharacterClassSettings Engine::characterClasses()
+{
+       return d->cclass;
 }
 
+
+/////////////////////////////////////////////////////////////////
+// character classes
+
+class DPTR_CLASS_NAME(CharacterClassSettings):public SharedDPtr
+{
+       public:
+               DPTR_NAME(){
+                       operatorClass= "~!@#$%^&*-+=:<>?/";
+                       literalClass="0123456789\'\"";
+                       nameClass= QPair<QString,QString>( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_",  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
+                       whitespaceClass=" \t\r\n\v";
+                       parenthesesChars=QPair<QChar,QChar>('(',')');
+                       assignmentChars=QPair<QChar,QChar>(0,'=');
+                       commaChar=',';
+               }
+               QString operatorClass;
+               QString literalClass;
+               QPair<QString,QString> nameClass;
+               QString whitespaceClass;
+               QPair<QChar,QChar> parenthesesChars;
+               QPair<QChar,QChar> assignmentChars;
+               QChar commaChar;
+};
+DEFINE_SHARED_DPTR(CharacterClassSettings);
+
+QString CharacterClassSettings::operatorClass() const
+{
+       return d->operatorClass;
+}
+void CharacterClassSettings::setOperatorClass(QString c)
+{
+       d->operatorClass=c;
+}
+
+QPair<QString,QString> CharacterClassSettings::nameClass() const
+{
+       return d->nameClass;
+}
+void CharacterClassSettings::setNameClass(QString f,QString s)
+{
+       d->nameClass.first=f;
+       d->nameClass.second=s;
+}
+
+QString CharacterClassSettings::whitespaceClass() const
+{
+       return d->whitespaceClass;
+}
+void CharacterClassSettings::setWhitespaceClass(QString c)
+{
+       d->whitespaceClass=c;
+}
+
+QPair< QChar, QChar > CharacterClassSettings::assignmentChars() const
+{
+       return d->assignmentChars;
+}
+void CharacterClassSettings::setAssignmentChars(QChar f, QChar s)
+{
+       d->assignmentChars.first=f;
+       d->assignmentChars.second=s;
+}
+
+QChar CharacterClassSettings::commaChar() const
+{
+       return d->commaChar;
+}
+void CharacterClassSettings::setCommaChar(QChar c)
+{
+       d->commaChar=c;
+}
+
+QPair< QChar, QChar > CharacterClassSettings::parenthesesChars() const
+{
+       return d->parenthesesChars;
+}
+void CharacterClassSettings::setParentheses(QChar f, QChar s)
+{
+       d->parenthesesChars.first=f;
+       d->parenthesesChars.second=s;
+}
+
+QString CharacterClassSettings::literalStartClass() const
+{
+       return d->literalClass;
+}
+void CharacterClassSettings::setLiteralStartClass(QString c)
+{
+       d->literalClass=c;
+}
+
+static bool strContainedIn(QString n,QString h)
+{
+       for(int i=0;i<n.size();i++)
+               if(!h.contains(n[i]))
+                       return false;
+       return true;
+}
+
+static bool strOverlaps(QString s1,QString s2)
+{
+       for(int i=0;i<s1.size();i++)
+               if(s2.contains(s1[i]))
+                       return true;
+       return false;
+}
+
+bool CharacterClassSettings::isConsistent() const
+{
+       //check that check name class is internally consistent
+       if(!strContainedIn(d->nameClass.first,d->nameClass.second))
+               return false;
+       //check that major classes do not overlap
+       //literals: operators, whitespace, start of names (may partially overlap with names)
+       if(strOverlaps(d->literalClass,d->operatorClass+d->whitespaceClass+d->nameClass.first))
+               return false;
+       //operators: whitespace, literals, all of names
+       if(strOverlaps(d->operatorClass,d->literalClass+d->whitespaceClass+d->nameClass.second))
+               return false;
+       //start of names: literals, operators, whitespace
+       if(strOverlaps(d->nameClass.first,d->operatorClass+d->whitespaceClass+d->literalClass))
+               return false;
+       //all of names: operators, whitespace
+       if(strOverlaps(d->nameClass.second,d->operatorClass+d->whitespaceClass))
+               return false;
+       //check assigment chars are not in any class (except operators)
+       QString any=d->literalClass+d->whitespaceClass+d->nameClass.second+d->literalClass;
+       if(any.contains(d->assignmentChars.first) || any.contains(d->assignmentChars.second))
+               return false;
+       if(d->assignmentChars.first!=0 && !d->operatorClass.contains(d->assignmentChars.first))
+               return false;
+       if(d->assignmentChars.second!=0 && !d->operatorClass.contains(d->assignmentChars.second))
+               return false;
+       //check remaining special chars are not in any other class
+       any+=d->operatorClass;
+       if(any.contains(d->parenthesesChars.first) ||
+          any.contains(d->parenthesesChars.second) ||
+          any.contains(d->commaChar))
+               return false;
+       //all ok
+       return true;
+}
+
+
 /////////////////////////////////////////////////////////////////
 // Unary Operator
 
-class DPTR_CLASS_NAME(ELAMUnaryOperator):public SharedDPtr
+class DPTR_CLASS_NAME(UnaryOperator):public SharedDPtr
 {
        public:
-               QMap<int,ELAMUnaryOperatorCall>callmap;
+               QMap<int,UnaryOperatorCall>callmap;
 };
-DEFINE_SHARED_DPTR(ELAMUnaryOperator)
+DEFINE_SHARED_DPTR(UnaryOperator)
 
 
-ELAMUnaryOperator::ELAMUnaryOperator(const ELAMUnaryOperator& op)
+UnaryOperator::UnaryOperator(const UnaryOperator& op)
        :d(op.d)
 {
 }
 
-ELAMUnaryOperator::ELAMUnaryOperator()
+UnaryOperator::UnaryOperator()
 {
 }
 
-ELAMUnaryOperator::~ELAMUnaryOperator()
+UnaryOperator::~UnaryOperator()
 {
 }
 
 
-QVariant ELAMUnaryOperator::execute(const QVariant& op) const
+QVariant UnaryOperator::execute(const QVariant& op) const
 {
        if(d->callmap.size()==0)
-               return qVariantFromValue<ELAMException>(ELAMException(ELAMException::UnknownOperatorError));
+               return qVariantFromValue<Exception>(Exception(Exception::UnknownOperatorError));
        //search for direct match
        if(d->callmap.contains(op.type()))
                return d->callmap[op.type()](op);
        //search for fallback
-       int any=ELAMAnyType::metaTypeId();
+       int any=AnyType::metaTypeId();
        if(d->callmap.contains(any))
                return d->callmap[any](op);
-       return qVariantFromValue<ELAMException>(ELAMException(ELAMException::TypeMismatchError));
+       return qVariantFromValue<Exception>(Exception(Exception::TypeMismatchError));
 }
 
-QList< int > ELAMUnaryOperator::getTypeIds() const
+QList< int > UnaryOperator::getTypeIds() const
 {
        return d->callmap.keys();
 }
 
-QStringList ELAMUnaryOperator::getTypeNames() const
+QStringList UnaryOperator::getTypeNames() const
 {
        QStringList ret;
        QList<int>ti=d->callmap.keys();
@@ -88,21 +278,21 @@ QStringList ELAMUnaryOperator::getTypeNames() const
        return ret;
 }
 
-ELAMUnaryOperatorCall ELAMUnaryOperator::getCallback(QString type) const
+UnaryOperatorCall UnaryOperator::getCallback(QString type) const
 {
        return getCallback(QVariant::nameToType(type.toAscii().data()));
 }
 
-ELAMUnaryOperatorCall ELAMUnaryOperator::getCallback(int type) const
+UnaryOperatorCall UnaryOperator::getCallback(int type) const
 {
        if(d->callmap.contains(type))
                return d->callmap[type];
-       if(d->callmap.contains(ELAMAnyType::metaTypeId()))
-               return d->callmap[ELAMAnyType::metaTypeId()];
+       if(d->callmap.contains(AnyType::metaTypeId()))
+               return d->callmap[AnyType::metaTypeId()];
        return 0;
 }
 
-void ELAMUnaryOperator::setCallback(ELAMUnaryOperatorCall callback, int type)
+void UnaryOperator::setCallback(UnaryOperatorCall callback, int type)
 {
        if(type==QVariant::Invalid)return;
        if(callback==0){
@@ -112,12 +302,12 @@ void ELAMUnaryOperator::setCallback(ELAMUnaryOperatorCall callback, int type)
        d->callmap.insert(type,callback);
 }
 
-void ELAMUnaryOperator::setCallback(ELAMUnaryOperatorCall callback, QString type)
+void UnaryOperator::setCallback(UnaryOperatorCall callback, QString type)
 {
        setCallback(callback,QVariant::nameToType(type.toAscii().data()));
 }
 
-void ELAMUnaryOperator::removeCallback(ELAMUnaryOperatorCall cb)
+void UnaryOperator::removeCallback(UnaryOperatorCall cb)
 {
        if(cb==0)return;
        QList<int>k=d->callmap.keys(cb);
@@ -125,38 +315,42 @@ void ELAMUnaryOperator::removeCallback(ELAMUnaryOperatorCall cb)
                d->callmap.remove(k[i]);
 }
 
-void ELAMUnaryOperator::removeCallback(QString t)
+void UnaryOperator::removeCallback(QString t)
 {
        removeCallback(QVariant::nameToType(t.toAscii().data()));
 }
 
-void ELAMUnaryOperator::removeCallback(int t)
+void UnaryOperator::removeCallback(int t)
 {
        d->callmap.remove(t);
 }
 
 /////////////////////////////////////////////////////////////////
-// Unary Operator
+// Binary Operator
 
-class DPTR_CLASS_NAME(ELAMBinaryOperator):public SharedDPtr
+class DPTR_CLASS_NAME(BinaryOperator):public SharedDPtr
 {
        public:
-               QMap<QPair<int,int>,ELAMBinaryOperatorCall>callmap;
+               QMap<QPair<int,int>,BinaryOperatorCall>callmap;
 };
-DEFINE_SHARED_DPTR(ELAMBinaryOperator)
+DEFINE_SHARED_DPTR(BinaryOperator)
 
 
-ELAMBinaryOperator::ELAMBinaryOperator(const ELAMBinaryOperator& op)
+BinaryOperator::BinaryOperator(const BinaryOperator& op)
        :d(op.d)
 {
 }
 
-ELAMBinaryOperator::ELAMBinaryOperator()
+BinaryOperator::BinaryOperator()
 {
 
 }
 
-ELAMBinaryOperator::~ELAMBinaryOperator()
+BinaryOperator::~BinaryOperator()
 {
 
 }
+
+
+//end of namespace
+};
\ No newline at end of file
index e3a887f..872114f 100644 (file)
@@ -1,10 +1,10 @@
-//ELAM main header
+// main header
 //
 // (c) Konrad Rosenbaum, 2010
 // protected under the GNU LGPL v3 or at your option any newer
 
-#ifndef ELAM_ENGINE_H
-#define ELAM_ENGINE_H
+#ifndef _ENGINE_H
+#define _ENGINE_H
 
 #include <QStringList>
 #include <QObject>
 
 #include "dptr.h"
 
+namespace ELAM {
+
 /**pointer to a function wrapping an unary operator
 \param op the operand to be worked on
 \returns the result of the operation*/
-typedef QVariant (*ELAMUnaryOperatorCall)(const QVariant&op);
+typedef QVariant (*UnaryOperatorCall)(const QVariant&op);
 
-class ELAMUnaryOperator
+class UnaryOperator
 {
-       DECLARE_SHARED_DPTR(ELAMUnaryOperator,d);
+       DECLARE_SHARED_DPTR(d);
        public:
-               ELAMUnaryOperator(const ELAMUnaryOperator&);
-               ELAMUnaryOperator();
-               ~ELAMUnaryOperator();
+               UnaryOperator(const UnaryOperator&);
+               UnaryOperator();
+               ~UnaryOperator();
                
                /**sets a callback function for the operator and a specific typ
                \param callback the function to call, if it is null the type is deleted from this operators type list
                \param type the type of variable to work on, this must be a type registered with QVariant, if this type is already known to the operator its callback is replaced
                */
-               void setCallback(ELAMUnaryOperatorCall callback,QString type);
+               void setCallback(UnaryOperatorCall callback,QString type);
                /**sets a callback function for the operator and a specific typ
                \param callback the function to call, if it is null the type is deleted from this operators type list
                \param type the type of variable to work on, this must be a type registered with QVariant, if this type is already known to the operator its callback is replaced
                */
-               void setCallback(ELAMUnaryOperatorCall callback,int type);
+               void setCallback(UnaryOperatorCall callback,int type);
                /**returns the callback function attached to the type or NULL if there is none*/
-               ELAMUnaryOperatorCall getCallback(QString type)const;
+               UnaryOperatorCall getCallback(QString type)const;
                /**returns the callback function attached to the type or NULL if there is none*/
-               ELAMUnaryOperatorCall getCallback(int type)const;
+               UnaryOperatorCall getCallback(int type)const;
                
                /**removes all types attached to this callback from the operator*/
-               void removeCallback(ELAMUnaryOperatorCall);
+               void removeCallback(UnaryOperatorCall);
                ///removes the type from this operators list
                void removeCallback(QString);
                ///removes the type from this operators list
@@ -62,44 +64,82 @@ class ELAMUnaryOperator
 \param op1 the left operand
 \param op2 the right operand
 \returns the result of the operation*/
-typedef QVariant (*ELAMBinaryOperatorCall)(const QVariant&op1,const QVariant&op2);
+typedef QVariant (*BinaryOperatorCall)(const QVariant&op1,const QVariant&op2);
 
-class ELAMBinaryOperator
+class BinaryOperator
 {
-       DECLARE_SHARED_DPTR(ELAMBinaryOperator,d);
+       DECLARE_SHARED_DPTR(d);
        public:
-               ELAMBinaryOperator(const ELAMBinaryOperator&);
-               ELAMBinaryOperator();
-               ~ELAMBinaryOperator();
+               BinaryOperator(const BinaryOperator&);
+               BinaryOperator();
+               ~BinaryOperator();
 };
 
 /**pointer to a function wrapping a mathematical function
 \param args the list of arguments
 \returns the result of the function*/
-typedef QVariant (*ELAMFunction)(const QList<QVariant>&args);
+typedef QVariant (*Function)(const QList<QVariant>&args);
 
+class CharacterClassSettings
+{
+       DECLARE_SHARED_DPTR(d)
+       public:
+               QString operatorClass()const;
+               void setOperatorClass(QString);
+               
+               QPair<QString,QString> nameClass()const;
+               void setNameClass(QString startchars,QString allchars);
+               
+               QString whitespaceClass()const;
+               void setWhitespaceClass(QString);
+               
+               QString literalStartClass()const;
+               void setLiteralStartClass(QString);
+               
+               QPair<QChar,QChar> parenthesesChars()const;
+               void setParentheses(QChar,QChar);
+               
+               QPair<QChar,QChar> assignmentChars()const;
+               void setAssignmentChars(QChar,QChar);
+               
+               QChar commaChar()const;
+               void setCommaChar(QChar);
+               
+               bool isConsistent()const;
+               
+               Token::Type charType(QChar,Token::Type)const;
+};
 
-/**The calculation engine of ELAM.
+/**The calculation engine of .
 
 Instances of this class can be configured to represent a specific system of functions and operators.
 
 Methods of this class are used to evaluate expressions into final values.
 */
-class ELAMEngine:public QObject
+class Engine:public QObject
 {
        Q_OBJECT
        DECLARE_DPTR(d);
        public:
                ///instantiates an engine object
-               ELAMEngine(QObject*parent=0);
+               Engine(QObject*parent=0);
                
        public slots:
-               ///simply parses an expression string into an ELAM object
-               ELAMExpression parseExpression(QString);
+               ///simply parses an expression string into an  object
+               Expression expression(QString);
+               ///simply parses an expression string into an  object
+               Expression expression(QList<Token>);
+               ///simply parses an expression string into a list of tokens
+               QList<Token> tokenize(QString);
                ///parses and evaluates an expression string into a final value
                QVariant evaluate(QString);
                ///evaluates a parsed expression into a final value
-               QVariant evaluate(ELAMExpression);
+               QVariant evaluate(Expression);
+               ///gives access to the character classes settings
+               CharacterClassSettings characterClasses();
+};
+
+//end of namespace
 };
 
 #endif
diff --git a/src/elamexpression.cpp b/src/elamexpression.cpp
new file mode 100644 (file)
index 0000000..927683e
--- /dev/null
@@ -0,0 +1,40 @@
+#include "elamexpression.h"
+
+namespace ELAM {
+
+class DPTR_CLASS_NAME(Token):public DPtr
+{
+       public:
+               QString cont;
+               Type type;
+               QVariant val;
+               Position pos;
+};
+DEFINE_DPTR(Token)
+
+
+Token::Token(Position pos)
+{
+       d->pos=pos;
+}
+
+Token::Token(QString c,Token::Type t,Position pos)
+{
+       d->cont=c;
+       d->type=t;
+       d->pos=pos;
+}
+
+Token::Token(QString c,QVariant v,Position pos)
+{
+       d->cont=c;
+       d->val=v;
+       d->pos=pos;
+}
+
+QString Token::content()const{return d->cont;}
+Token::Type Token::type()const{return d->type;}
+QVariant Token::literalValue()const{return d->val;}
+Position Token::position()const{return d->pos;}
+
+};
\ No newline at end of file
index a552e9c..ff4812f 100644 (file)
@@ -7,26 +7,50 @@
 #define ELAM_EXPRESSION_H
 
 #include "elamvalue.h"
+#include "dptr.h"
 
-class ELAMToken
+namespace ELAM {
+
+class Token
 {
+       DECLARE_DPTR(d)
        public:
+               ///The type of token
                enum Type {
+                       ///invalid token
+                       Invalid,
+                       ///a name: function, variable, or constant
                        Name,
+                       ///an operator (unary or binary)
                        Operator,
+                       ///opening parenthese
                        ParOpen,
+                       ///closing parenthese
                        ParClose,
+                       ///a comma - separating expressions in function calls
                        Comma,
-                       Literal
+                       ///a literal value
+                       Literal,
+                       ///white space chars, this is actually not used for tokens, but for parsing
+                       Whitespace,
                };
-               QString content()const{return mcont;}
-               Type type()const{return mtype;}
-       private:
-               QString mcont;
-               Type mtype;
+               ///creates an empty/invalid token
+               Token(Position pos=Position(-1,-1));
+               ///creates a token from a parsed piece of string
+               Token(QString,Type,Position pos=Position(-1,-1));
+               ///creates a literal token
+               Token(QString,QVariant,Position pos=Position(-1,-1));
+               ///returns the string content of the token
+               QString content()const;
+               ///returns the type of token this is
+               Type type()const;
+               ///for literals: returns the value
+               QVariant literalValue()const;
+               ///returns the original position of the token
+               Position position()const;
 };
 
-class ELAMExpression
+class Expression
 {
        public:
                enum Type {
@@ -38,6 +62,11 @@ class ELAMExpression
                        UnaryOp,
                        BinaryOp,
                };
+               Expression(){}
+               Expression(const QList<Token>&){}
+};
+
+//end of namespace
 };
 
 #endif
index 5509dfe..cbed42e 100644 (file)
@@ -5,12 +5,12 @@
 
 #include "elamintengine.h"
 
-ELAMIntEngine::ELAMIntEngine()
+ELAM::IntEngine::IntEngine()
 {
        configureIntEngine(*this);
 }
 
-void ELAMIntEngine::configureIntEngine(ELAMEngine& eng)
+void ELAM::IntEngine::configureIntEngine(ELAM::Engine& eng)
 {
        //TODO: implement
 }
index d0c21b2..984d269 100644 (file)
@@ -8,12 +8,16 @@
 
 #include "elamengine.h"
 
-class ELAMIntEngine:public ELAMEngine
+namespace ELAM {
+
+class IntEngine:public Engine
 {
        public:
-               ELAMIntEngine();
+               IntEngine();
                
-               static void configureIntEngine(ELAMEngine&);
+               static void configureIntEngine(Engine&);
+};
+
 };
 
 #endif
index 8322ac2..e60429b 100644 (file)
@@ -1,40 +1,42 @@
-// ELAM value definition implementation
+//  value definition implementation
 //
 // (c) Konrad Rosenbaum, 2010
 // protected under the GNU LGPL v3 or at your option any newer
 
 #include "elamvalue.h"
 
-ELAMException::ELAMException()
+namespace ELAM {
+       
+Exception::Exception()
 {
-       mline=mcol=-1;
 }
-ELAMException::ELAMException(const ELAMException& e)
+Exception::Exception(const Exception& e)
 {
        operator=(e);
 }
-ELAMException::ELAMException(ErrorType tp,QString errText, int line, int column)
+Exception::Exception(ErrorType tp,QString errText, Position pos)
 {
        mtype=tp;
        merr=errText;
-       mline=line;
-       mcol=column;
+       mpos=pos;
 }
-static int ELAMException_metaid=qRegisterMetaType<ELAMException>();
-int ELAMException::metaTypeId()
+static int Exception_metaid=qRegisterMetaType<Exception>();
+int Exception::metaTypeId()
 {
-       return ELAMException_metaid;
+       return Exception_metaid;
 }
-ELAMException& ELAMException::operator=(const ELAMException& e)
+Exception& Exception::operator=(const Exception& e)
 {
        merr=e.merr;
-       mline=e.mline;
-       mcol=e.mcol;
+       mpos=e.mpos;
        return *this;
 }
 
-static int ELAMAnyType_metaid=qRegisterMetaType<ELAMAnyType>();
-int ELAMAnyType::metaTypeId()
+static int AnyType_metaid=qRegisterMetaType<AnyType>();
+int AnyType::metaTypeId()
 {
-       return ELAMAnyType_metaid;
+       return AnyType_metaid;
 }
+
+//end of namespace
+};
\ No newline at end of file
index a95cafe..384a73d 100644 (file)
@@ -9,9 +9,30 @@
 #include <QVariant>
 #include <QString>
 #include <QPair>
+#include <QPoint>
+
+namespace ELAM {
+
+class Position
+{
+       public:
+               Position(const QPair<int,int>&p){mline=p.first;mcol=p.second;}
+               Position(const QPoint &p){mline=p.y();mcol=p.x();}
+               Position(int line,int col){mline=line;mcol=col;}
+               Position(int col){mline=1;mcol=col;}
+               Position(){mline=mcol=-1;}
+               
+               int line()const{return mline;}
+               int column()const{return mcol;}
+               
+               operator QPair<int,int>()const{return QPair<int,int>(mline,mcol);}
+               operator QPoint()const{return QPoint(mcol,mline);}
+       private:
+               int mline,mcol;
+};
 
 /**Objects of this class represent an exception in the evaluation of an ELAM expression.*/
-class ELAMException
+class Exception
 {
        public:
                enum ErrorType{
@@ -22,33 +43,37 @@ class ELAMException
                        TypeMismatchError,
                };
                
-               ELAMException();
-               ELAMException(const ELAMException&);
-               ELAMException(ErrorType type,QString errorText=QString(),int line=-1,int column=-1);
+               Exception();
+               Exception(const Exception&);
+               Exception(ErrorType type,QString errorText=QString(),Position p=Position());
                
-               ELAMException& operator=(const ELAMException&);
+               Exception& operator=(const Exception&);
                
                QString errorText()const{return merr;}
-               int errorLine()const{return mline;}
-               int errorColumn()const{return mcol;}
-               QPair<int,int> errorPos()const{return QPair<int,int>(mline,mcol);}
+               int errorLine()const{return mpos.line();}
+               int errorColumn()const{return mpos.column();}
+               Position errorPos()const{return mpos;}
                
                static int metaTypeId();
                
        private:
                ErrorType mtype;
                QString merr;
-               int mline,mcol;
+               Position mpos;
 };
-Q_DECLARE_METATYPE(ELAMException);
 
 /**this type is not actually used, its ID is used as a fallback to tell operators, functions and engines that any supported type can be used*/
-class ELAMAnyType
+class AnyType
 {
        public:
                ///returns the meta type ID of the ANY type
                static int metaTypeId();
 };
-Q_DECLARE_METATYPE(ELAMAnyType);
+
+//end of namespace
+};
+
+Q_DECLARE_METATYPE(ELAM::Exception);
+Q_DECLARE_METATYPE(ELAM::AnyType);
 
 #endif