From: konrad Date: Fri, 12 Nov 2010 08:52:16 +0000 (+0000) Subject: removed ELAMValue class (replaced by plain QVariant) X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=c5b03e819f66baa0bd546c0a2403d87d34577b19;p=web%2Fkonrad%2Ftaurus.git removed ELAMValue class (replaced by plain QVariant) better draft of engine interface git-svn-id: https://silmor.de/svn/softmagic/elam/trunk@623 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- diff --git a/src/elam.pro b/src/elam.pro index f0224c1..69c113f 100644 --- a/src/elam.pro +++ b/src/elam.pro @@ -15,7 +15,8 @@ HEADERS += \ elamvalue.h SOURCES += \ - elamvalue.cpp + elamvalue.cpp \ + elamengine.cpp INCLUDEPATH += . DEPENDPATH += . diff --git a/src/elamengine.cpp b/src/elamengine.cpp new file mode 100644 index 0000000..09dac3c --- /dev/null +++ b/src/elamengine.cpp @@ -0,0 +1,145 @@ +// ELAM 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" + +ELAMEngine::ELAMEngine(QObject* parent): QObject(parent) +{ + +} + +QVariant ELAMEngine::evaluate(QString ex) +{ + return evaluate(parseExpression(ex)); +} + +QVariant ELAMEngine::evaluate(ELAMExpression ex) +{ + //TODO: implement + return QVariant(); +} + +ELAMExpression ELAMEngine::parseExpression(QString ) +{ + //TODO: implement parser + return ELAMExpression(); +} + +///////////////////////////////////////////////////////////////// +// Unary Operator + +class ELAMUnaryOperator::Private +{ + public: + //memory management + int ctr; + Private(){ctr=1;} + void detach(){ctr--;if(ctr<=0)delete this;} + void attach(){ctr++;} + //callback mapping + QMapcallmap; +}; + +ELAMUnaryOperator::ELAMUnaryOperator(const ELAMUnaryOperator& op) +{ + d=0; + operator=(op); +} + +ELAMUnaryOperator::ELAMUnaryOperator() +{ + d=new Private(); +} + +ELAMUnaryOperator::~ELAMUnaryOperator() +{ + if(d)d->detach(); + d=0; +} + + +ELAMUnaryOperator& ELAMUnaryOperator::operator=(const ELAMUnaryOperator& op) +{ + if(d)d->detach(); + d=op.d; + if(d)d->attach(); + return *this; +} + +QVariant ELAMUnaryOperator::execute(const QVariant& op) const +{ + if(d->callmap.size()==0) + return qVariantFromValue(ELAMException(ELAMException::UnknownOperatorError)); + //search for direct match + if(d->callmap.contains(op.type())) + return d->callmap[op.type()](op); + //search for fallback + int any=ELAMAnyType::metaTypeId(); + if(d->callmap.contains(any)) + return d->callmap[any](op); + return qVariantFromValue(ELAMException(ELAMException::TypeMismatchError)); +} + +QList< int > ELAMUnaryOperator::getTypeIds() const +{ + return d->callmap.keys(); +} + +QStringList ELAMUnaryOperator::getTypeNames() const +{ + QStringList ret; + QListti=d->callmap.keys(); + for(int i=0;icallmap.contains(type)) + return d->callmap[type]; + if(d->callmap.contains(ELAMAnyType::metaTypeId())) + return d->callmap[ELAMAnyType::metaTypeId()]; + return 0; +} + +void ELAMUnaryOperator::setCallback(ELAMUnaryOperatorCall callback, int type) +{ + if(type==QVariant::Invalid)return; + if(callback==0){ + d->callmap.remove(type); + return; + } + d->callmap.insert(type,callback); +} + +void ELAMUnaryOperator::setCallback(ELAMUnaryOperatorCall callback, QString type) +{ + setCallback(callback,QVariant::nameToType(type.toAscii().data())); +} + +void ELAMUnaryOperator::removeCallback(ELAMUnaryOperatorCall cb) +{ + if(cb==0)return; + QListk=d->callmap.keys(cb); + for(int i=0;icallmap.remove(k[i]); +} + +void ELAMUnaryOperator::removeCallback(QString t) +{ + removeCallback(QVariant::nameToType(t.toAscii().data())); +} + +void ELAMUnaryOperator::removeCallback(int t) +{ + d->callmap.remove(t); +} diff --git a/src/elamengine.h b/src/elamengine.h index 75be1cd..3bc054c 100644 --- a/src/elamengine.h +++ b/src/elamengine.h @@ -6,20 +6,94 @@ #ifndef ELAM_ENGINE_H #define ELAM_ENGINE_H -#include +#include #include +#include #include "elamexpression.h" +/**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); + +class ELAMUnaryOperator +{ + public: + ELAMUnaryOperator(const ELAMUnaryOperator&); + ELAMUnaryOperator(); + ~ELAMUnaryOperator(); + + ELAMUnaryOperator& operator=(const ELAMUnaryOperator&); + + /**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); + /**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); + /**returns the callback function attached to the type or NULL if there is none*/ + ELAMUnaryOperatorCall getCallback(QString type)const; + /**returns the callback function attached to the type or NULL if there is none*/ + ELAMUnaryOperatorCall getCallback(int type)const; + + /**removes all types attached to this callback from the operator*/ + void removeCallback(ELAMUnaryOperatorCall); + ///removes the type from this operators list + void removeCallback(QString); + ///removes the type from this operators list + void removeCallback(int); + + ///returns all type names that have a valid callback in this operator + QStringList getTypeNames()const; + ///returns all type IDs that have a valid callback in this operator + QList getTypeIds()const; + + ///calls the callback function associated with the type of the argument, throws an exception if there is no callback + QVariant execute(const QVariant&)const; + private: + class Private; + Private *d; +}; + +/**pointer to a function wrapping a binary operator +\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); + +/**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&args); + + +/**The calculation engine of ELAM. + +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 { Q_OBJECT public: + ///instantiates an engine object ELAMEngine(QObject*parent=0); + public slots: + ///simply parses an expression string into an ELAM object ELAMExpression parseExpression(QString); - ELAMValue evaluate(QString); - ELAMValue evaluate(ELAMExpression); + ///parses and evaluates an expression string into a final value + QVariant evaluate(QString); + ///evaluates a parsed expression into a final value + QVariant evaluate(ELAMExpression); + + private: class Private; Private *d; diff --git a/src/elamvalue.cpp b/src/elamvalue.cpp index 5d4b9bb..8322ac2 100644 --- a/src/elamvalue.cpp +++ b/src/elamvalue.cpp @@ -5,91 +5,36 @@ #include "elamvalue.h" -ELAMValue::ELAMValue() +ELAMException::ELAMException() { - m_exc=false; - m_exline=m_excol=-1; + mline=mcol=-1; } - -ELAMValue::ELAMValue(long long l) -{ - m_exc=false; - m_exline=m_excol=-1; - m_val=l; -} - -ELAMValue::ELAMValue(double d) -{ - m_exc=false; - m_exline=m_excol=-1; - m_val=d; -} - -ELAMValue::ELAMValue(QString s) +ELAMException::ELAMException(const ELAMException& e) { - m_exc=false; - m_exline=m_excol=-1; - m_val=s; + operator=(e); } - -ELAMValue::ELAMValue(QVariant v) +ELAMException::ELAMException(ErrorType tp,QString errText, int line, int column) { - m_exc=false; - m_exline=m_excol=-1; - //TODO: registered type? - m_val=v; + mtype=tp; + merr=errText; + mline=line; + mcol=column; } - -ELAMValue& ELAMValue::operator=(const ELAMValue&e) +static int ELAMException_metaid=qRegisterMetaType(); +int ELAMException::metaTypeId() { - m_exc=e.m_exc; - m_exstr=e.m_exstr; - m_exline=e.m_exline; - m_excol=e.m_excol; - m_val=e.m_val; - return *this; + return ELAMException_metaid; } - -ELAMValue& ELAMValue::operator=(long long v) +ELAMException& ELAMException::operator=(const ELAMException& e) { - m_exc=false;m_excol=m_exline=-1;m_exstr=QString(); - m_val=v; + merr=e.merr; + mline=e.mline; + mcol=e.mcol; return *this; } -ELAMValue& ELAMValue::operator=(int v) -{ - m_exc=false;m_excol=m_exline=-1;m_exstr=QString(); - m_val=v; - return *this; -} - -ELAMValue& ELAMValue::operator=(const QString&v) -{ - m_exc=false;m_excol=m_exline=-1;m_exstr=QString(); - m_val=v; - return *this; -} - -ELAMValue& ELAMValue::operator=(const QVariant&v) -{ - m_exc=false;m_excol=m_exline=-1;m_exstr=QString(); - m_val=v; - return *this; -} - - -void ELAMValue::setException(QString s,int l,int c) -{ - m_exc=true; - m_exline=l;m_excol=c; - m_exstr=s; -} - -QPair ELAMValue::exceptionPos()const +static int ELAMAnyType_metaid=qRegisterMetaType(); +int ELAMAnyType::metaTypeId() { - if(m_exc) - return QPair(m_exline,m_excol); - else - return QPair(-1,-1); + return ELAMAnyType_metaid; } diff --git a/src/elamvalue.h b/src/elamvalue.h index f30f7c9..a95cafe 100644 --- a/src/elamvalue.h +++ b/src/elamvalue.h @@ -10,37 +10,45 @@ #include #include -class ELAMValue +/**Objects of this class represent an exception in the evaluation of an ELAM expression.*/ +class ELAMException { public: - ELAMValue(); - ELAMValue(long long); - ELAMValue(double); - ELAMValue(QString); - ELAMValue(QVariant); - ELAMValue& operator=(const ELAMValue&); - ELAMValue& operator=(long long); - ELAMValue& operator=(int); - ELAMValue& operator=(const QString&); - ELAMValue& operator=(const QVariant&); + enum ErrorType{ + NoError=0, + ParserError, + UnknownOperatorError, + UnknownFunctionError, + TypeMismatchError, + }; - bool isNull()const{return m_val.isNull();} + ELAMException(); + ELAMException(const ELAMException&); + ELAMException(ErrorType type,QString errorText=QString(),int line=-1,int column=-1); - void setException(QString,int,int); + ELAMException& operator=(const ELAMException&); - bool hasException()const{return m_exc;} - QString exceptionString()const{return m_exc?m_exstr:QString();} - QPair exceptionPos()const; + QString errorText()const{return merr;} + int errorLine()const{return mline;} + int errorColumn()const{return mcol;} + QPair errorPos()const{return QPair(mline,mcol);} - QVariant toVariant()const{return m_val;} - long long toInt()const{return m_val.toInt();} - QString toString()const{return m_val.toString();} + static int metaTypeId(); private: - QVariant m_val; - bool m_exc; - QString m_exstr; - int m_exline,m_excol; + ErrorType mtype; + QString merr; + int mline,mcol; }; +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 +{ + public: + ///returns the meta type ID of the ANY type + static int metaTypeId(); +}; +Q_DECLARE_METATYPE(ELAMAnyType); #endif