From: hama Date: Sun, 24 Aug 2014 21:38:17 +0000 (+0200) Subject: dayly work X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=04702bf5745db82b31df6c1c198434ba678d0a07;p=reqt dayly work --- diff --git a/rplcore/rplstring.cpp b/rplcore/rplstring.cpp index 635658c..a8bd039 100644 --- a/rplcore/rplstring.cpp +++ b/rplcore/rplstring.cpp @@ -421,4 +421,119 @@ char RplString::findCsvSeparator(FILE* fp, char* buffer, size_t bufferSize){ return rc; } +/** + * @brief Determines the length and vlaue of an integer. + * + * @param text the number as text + * @param radix the base of the number system: 8 (octal), 10 or 16 + * @param pValue OUT: the value of the integer. May be NULL + * + * @return <=0: no integer found + * otherwise: the length of the integer + */ +int RplString::lengthOfUInt64(const char* text, int radix, quint64* pValue) +{ + qint64 value = 0; + int length = 0; + int cc; + if (radix == 10){ + while ( (cc = text[length]) >= '0' && cc <= '9'){ + value = value * 10 + cc - '0'; + length++; + } + } else if (radix == 16){ + while (true){ + if ( (cc = text[length]) >= '0' && cc <= '9') + value = value * 16 + cc - '0'; + else if (cc >= 'A' && cc <= 'F') + value = value * 16 + cc - 'A' + 10; + else if (cc >= 'a' && cc <= 'f') + value = value * 16 + cc - 'a' + 10; + else + break; + length++; + } + } else if (radix == 8){ + while (true){ + if ( (cc = text[length]) >= '0' && cc <= '7') + value = value * 8 + cc - '0'; + else + break; + length++; + } + } else { + throw RplException("RplString::lengthOfInt(): wrong radix: %d", radix); + } + if (pValue != NULL) + *pValue = value; + return length; +} + +/** + * @brief Determines the length and value of a floting point number. + * + * @param text the number as text + * @param pValue OUT: the value of the integer. May be NULL + * + * @return <=0: no real number found + * otherwise: the length of the floating point number + */ +int RplString::lengthOfReal(const char* text, qreal* pValue) +{ + qreal value = 0.0; + int cc; + int length = 0; + while (true){ + if ( (cc = text[length]) >= '0' && cc <= '9') + value = value * 10 + (cc - '0'); + else + break; + length++; + } + // found: a digit has been found (in front of or behind the '.' + bool found = length > 0; + if (text[length] == '.'){ + length++; + } + if (isdigit(text[length])){ + found = true; + qreal divisor = 1; + qreal precision = 0; + while ( (cc = text[length]) >= '0' && cc <= '9'){ + divisor *= 10; + precision = precision*10 + cc - '0'; + length++; + } + value += precision / divisor; + } else if (! found){ + length = 0; + } + if (found && toupper(text[length]) == 'E'){ + int savePoint = length; + length++; + bool negative = false; + if ( (cc = text[length]) == '+') + length++; + else if (cc == '-'){ + length++; + negative = true; + } + if (! isdigit(text[length])) + length = savePoint; + else{ + int exponent = 0; + while (isdigit(text[length])){ + exponent = exponent * 10 + text[length] - '0'; + length++; + } + if (negative) + value /= qPow(10, exponent); + else + value *= qPow(10, exponent); + } + } + if (pValue) + *pValue = value; + return found ? length : 0; +} diff --git a/rplcore/rplstring.hpp b/rplcore/rplstring.hpp index ab12169..ee8924c 100644 --- a/rplcore/rplstring.hpp +++ b/rplcore/rplstring.hpp @@ -29,7 +29,8 @@ public: static QByteArray toNumber(int value, const char* format = "%d"); static int lengthOfNumber(const char* text, bool skipTrailingSpaces = false); static char findCsvSeparator(FILE* fp, char* buffer, size_t bufferSize); - + static int lengthOfUInt64(const char* text, int radix, quint64* pValue); + static int lengthOfReal(const char* text, qreal* pValue); }; #endif // RPLSTRING_HPP diff --git a/rplexpr/rplasclasses.cpp b/rplexpr/rplasclasses.cpp index aab5963..11f21d6 100644 --- a/rplexpr/rplasclasses.cpp +++ b/rplexpr/rplasclasses.cpp @@ -75,7 +75,7 @@ RplSymbolSpace::RplSymbolSpace(RplASTree& tree) : * @param parent the parent of the symbol space */ RplSymbolSpace::RplSymbolSpace(RplSymbolSpace::SymbolSpaceType type, - const QString& name, + const QByteArray& name, RplSymbolSpace* parent) : m_type(type), m_name(name), @@ -136,7 +136,7 @@ void RplSymbolSpace::finishScope(int endOfScope, RplASScope& scope) for (; ix < last; ix++){ RplASVarDefinition* var = m_listOfVars[ix]; var->setEndOfScope(endOfScope); - const QString& name = var->name(); + const QByteArray& name = var->name(); if (m_variables.contains(name)) m_variables.remove(name); } @@ -150,7 +150,7 @@ void RplSymbolSpace::finishScope(int endOfScope, RplASScope& scope) * @return NULL: not found
* otherwise: the variable */ -RplASVarDefinition* RplSymbolSpace::findVariable(const QString& name) const +RplASVarDefinition* RplSymbolSpace::findVariable(const QByteArray& name) const { RplASVarDefinition* rc = NULL; if (m_variables.contains(name)) @@ -167,7 +167,7 @@ RplASVarDefinition* RplSymbolSpace::findVariable(const QString& name) const * @return NULL: not found
* otherwise: the class */ -RplASClass* RplSymbolSpace::findClass(const QString& name) const +RplASClass* RplSymbolSpace::findClass(const QByteArray& name) const { RplASClass* rc = NULL; if (m_classes.contains(name)) @@ -184,7 +184,7 @@ RplASClass* RplSymbolSpace::findClass(const QString& name) const * @return NULL: method not found * otherwise: the method description */ -RplASMethod* RplSymbolSpace::findMethod(const QString& name) const +RplASMethod* RplSymbolSpace::findMethod(const QByteArray& name) const { RplASMethod* rc = NULL; if (m_methods.contains(name)) @@ -203,10 +203,10 @@ void RplSymbolSpace::dump(RplWriter& writer, int indent, const char* header) { if (header != NULL) writer.writeLine(header); - writer.formatIndented(indent, "= %s (%s) parent: %s", m_name.toUtf8().constData(), + writer.formatIndented(indent, "= %s (%s) parent: %s", m_name.constData(), spaceTypeName(m_type), - m_parent == NULL ? "" : m_parent->name().toUtf8().constData()); - QList sorted; + m_parent == NULL ? "" : m_parent->name().constData()); + QList sorted; if (m_classes.size() > 0){ writer.writeIndented(indent, "== Classes:"); sorted.reserve(m_classes.size()); @@ -214,8 +214,8 @@ void RplSymbolSpace::dump(RplWriter& writer, int indent, const char* header) for (it = m_classes.begin(); it != m_classes.end(); it++){ sorted.append(it.key()); } - qSort(sorted.begin(), sorted.end(), qLess()); - QList::iterator it2; + qSort(sorted.begin(), sorted.end(), qLess()); + QList::iterator it2; for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ RplASClass* clazz = m_classes[*it2]; clazz->dump(writer, indent); @@ -229,8 +229,8 @@ void RplSymbolSpace::dump(RplWriter& writer, int indent, const char* header) for (it3 = m_methods.begin(); it3 != m_methods.end(); it3++){ sorted.append(it3.key()); } - qSort(sorted.begin(), sorted.end(), qLess()); - QList::iterator it4; + qSort(sorted.begin(), sorted.end(), qLess()); + QList::iterator it4; for (it4 = sorted.begin(); it4 != sorted.end(); it4++){ RplASMethod* method = m_methods[*it4]; do { @@ -242,7 +242,7 @@ void RplSymbolSpace::dump(RplWriter& writer, int indent, const char* header) if (m_listOfVars.size() > 0){ writer.writeIndented(indent, "== Variables:"); - QList::iterator it6; + QList::iterator it6; for (int ix = 0; ix < m_listOfVars.size(); ix++){ RplASVarDefinition* var = m_listOfVars[ix]; var->dump(writer, indent); @@ -368,7 +368,7 @@ void RplSymbolSpace::setBody(RplASItem* body) RplASItem* RplSymbolSpace::addVariable(RplASVarDefinition* variable, int& varNo) { RplASItem* rc = NULL; - const QString& name = variable->name(); + const QByteArray& name = variable->name(); if (m_variables.contains(name)) rc = m_variables[name]; else if (m_methods.contains(name)) @@ -391,7 +391,7 @@ RplASItem* RplSymbolSpace::addVariable(RplASVarDefinition* variable, int& varNo) RplASItem* RplSymbolSpace::addMethod(RplASMethod* method) { RplASItem* rc = NULL; - const QString& name = method->name(); + const QByteArray& name = method->name(); if (m_variables.contains(name)) rc = m_variables[name]; else if (! m_methods.contains(name)){ @@ -422,7 +422,7 @@ RplASItem* RplSymbolSpace::addMethod(RplASMethod* method) RplASUserClass* RplSymbolSpace::addClass(RplASUserClass* clazz) { RplASUserClass* rc = NULL; - const QString& name = clazz->name(); + const QByteArray& name = clazz->name(); if (m_classes.contains(name)){ rc = dynamic_cast(m_classes[name]); } else { @@ -436,7 +436,7 @@ RplASUserClass* RplSymbolSpace::addClass(RplASUserClass* clazz) * * @return the name */ -const QString& RplSymbolSpace::name() const +const QByteArray& RplSymbolSpace::name() const { return m_name; } @@ -499,7 +499,7 @@ bool RplASBoolean::boolValueOf(void*) const * @param maxLength not used * @return a string describing the object */ -QString RplASBoolean::toString(void* object, int) const +QByteArray RplASBoolean::toString(void* object, int) const { return ((RplASVariant*) object)->asBool() ? "True" : "False"; } @@ -518,7 +518,7 @@ RplASFloat::RplASFloat(RplASTree& tree) : { } -RplASFloat::RplASFloat(const QString& name, RplASTree& tree) : +RplASFloat::RplASFloat(const QByteArray& name, RplASTree& tree) : RplASClass(name, tree) { m_superClass = RplASFloat::m_instance; @@ -567,11 +567,12 @@ bool RplASFloat::boolValueOf(void*) const * @param maxLength not used * @return a string describing the object */ -QString RplASFloat::toString(void* object, int) const +QByteArray RplASFloat::toString(void* object, int) const { - QString rc; - rc.sprintf("%f", ((RplASVariant *) object)->asFloat()); - return rc; + char buffer[256]; + + qsnprintf(buffer, sizeof buffer, "%f", ((RplASVariant *) object)->asFloat()); + return buffer; } /** @class RplASInteger rplastree.hpp "rplexpr/rplastree.hpp" @@ -608,11 +609,12 @@ bool RplASInteger::boolValueOf(void*) const * @param maxLength the maximum length of the result * @return a string describing the object */ -QString RplASInteger::toString(void* object, int maxLength) const +QByteArray RplASInteger::toString(void* object, int maxLength) const { - QString rc; - rc.sprintf("%.*d", maxLength, ((RplASVariant *) object)->asInt()); - return rc; + char buffer[64]; + qsnprintf(buffer, sizeof buffer, "%.*d", maxLength, + ((RplASVariant *) object)->asInt()); + return buffer; } @@ -637,7 +639,7 @@ RplASString::RplASString(RplASTree& tree) : */ void* RplASString::newValueInstance(void* source) const { - QString* rc = source == NULL ? new QString() : new QString(*(QString*) source); + QByteArray* rc = source == NULL ? new QByteArray() : new QByteArray(*(QByteArray*) source); return (void*) rc; } @@ -650,7 +652,7 @@ void* RplASString::newValueInstance(void* source) const */ void RplASString::destroyValueInstance(void* object) const { - delete (QString*) object; + delete (QByteArray*) object; } /** @@ -658,7 +660,7 @@ void RplASString::destroyValueInstance(void* object) const * * This method should never be called. * - * @param object the object to test (a QString* instance) + * @param object the object to test (a QByteArray* instance) * @return false: the string is empty * true: otherwise */ @@ -666,7 +668,7 @@ bool RplASString::boolValueOf(void* object) const { bool rc = false; if (object != NULL){ - QString* string = static_cast(object); + QByteArray* string = static_cast(object); if (string == NULL) throw RplException("RplASString.boolValueOf(): not a string"); rc = ! string->isEmpty(); @@ -681,10 +683,10 @@ bool RplASString::boolValueOf(void* object) const * @param maxLength the maximum length of the result * @return a string describing the object */ -QString RplASString::toString(void* object, int maxLength) const +QByteArray RplASString::toString(void* object, int maxLength) const { - QString rc; - QString* string = reinterpret_cast (object); + QByteArray rc; + QByteArray* string = reinterpret_cast (object); int length = string->size(); if (length + 2 > maxLength) length = maxLength - 2; @@ -775,9 +777,9 @@ bool RplASList::boolValueOf(void* object) const * @param maxLength unused * @return a string describing the object */ -QString RplASList::toString(void* object, int maxLength) const +QByteArray RplASList::toString(void* object, int maxLength) const { - QString rc; + QByteArray rc; rc.reserve(maxLength); rc += "["; RplASListOfVariants* list = reinterpret_cast(object); @@ -788,7 +790,7 @@ QString RplASList::toString(void* object, int maxLength) const first = false; else rc += ","; - QString part = (*it)->toString(maxLength - rc.size() - 5); + QByteArray part = (*it)->toString(maxLength - rc.size() - 5); if (maxLength - rc.size() - 5 - part.size() <= 0){ rc += "..."; break; @@ -831,7 +833,7 @@ void* RplASMap::newValueInstance(void* source) const RplASMapOfVariants::iterator it; for (it = source2->begin(); it != source2->end(); it++){ // deleting in destroyValue(): - const QString& key = it.key(); + const QByteArray& key = it.key(); RplASVariant* value = new RplASVariant(*it.value()); (*rc)[key] = value; } @@ -876,9 +878,9 @@ bool RplASMap::boolValueOf(void* object) const * @param maxLength maximal length of the result * @return a string describing the object */ -QString RplASMap::toString(void* object, int maxLength) const +QByteArray RplASMap::toString(void* object, int maxLength) const { - QString rc; + QByteArray rc; rc.reserve(maxLength); rc += "["; RplASMapOfVariants* map = reinterpret_cast(object); @@ -897,7 +899,7 @@ QString RplASMap::toString(void* object, int maxLength) const rc += it.key(); rc += "':"; } - QString part = it.value()->toString(maxLength - rc.size() - 5); + QByteArray part = it.value()->toString(maxLength - rc.size() - 5); if (maxLength - rc.size() - 5 - part.size() <= 0){ rc += "..."; break; @@ -919,7 +921,7 @@ QString RplASMap::toString(void* object, int maxLength) const /** * @brief Constructor. */ -RplVariable::RplVariable(const QString& name) : +RplVariable::RplVariable(const QByteArray& name) : m_name(name), m_namespace(NULL), m_value(), @@ -936,12 +938,10 @@ RplVariable::RplVariable(const QString& name) : */ void RplVariable::dump(RplWriter& writer, int indent) { - QByteArray name1 = m_type == NULL ? "NoneType" : m_type->name().toUtf8(); - QByteArray name2 = m_name.toUtf8(); - QByteArray val = m_value.toString().toUtf8(); + const char* name1 = m_type == NULL ? "NoneType" : m_type->name().constData(); + QByteArray val = m_value.toString(); writer.formatIndented(indent, "%s %s: value: %s", - name1.constData(), - name2.constData(), val.constData()); + name1, m_name.constData(), val.constData()); } /** * @brief Returns the data type of the variable. @@ -966,7 +966,7 @@ void RplVariable::setType(RplASClass* type) * * @return the name */ -const QString& RplVariable::name() const +const QByteArray& RplVariable::name() const { return m_name; } @@ -1021,9 +1021,9 @@ bool RplASVoid::boolValueOf(void*) const * @param maxLength ignored * @return the empty string */ -QString RplASVoid::toString(void*, int) const +QByteArray RplASVoid::toString(void*, int) const { - return QString(""); + return QByteArray(""); } /** @class RplASFormula rplastree.hpp "rplexpr/rplastree.hpp" @@ -1082,13 +1082,13 @@ bool RplASFormula::boolValueOf(void*) const * @param maxLength ignored * @return the empty string */ -QString RplASFormula::toString(void* object, int) const +QByteArray RplASFormula::toString(void* object, int) const { RplASExprStatement* expr = static_cast(object); - QString rc; - rc.sprintf("", expr->id()); - return rc; + char buffer[64]; + qsnprintf(buffer, sizeof buffer, "", expr->id()); + return buffer; } /** @class RplASUserClass rplastree.hpp "rplexpr/rplastree.hpp" @@ -1104,7 +1104,7 @@ QString RplASFormula::toString(void* object, int) const * @param position the position of the class definition * @param tree the abstract syntax tree */ -RplASUserClass::RplASUserClass(const QString& name, +RplASUserClass::RplASUserClass(const QByteArray& name, const RplSourcePosition* position, RplASTree& tree) : RplASClass(name, tree), @@ -1150,7 +1150,7 @@ bool RplASUserClass::boolValueOf(void* object) const * @param maxLength maximum length of the string * @return */ -QString RplASUserClass::toString(void*, int) const +QByteArray RplASUserClass::toString(void*, int) const { return m_name; } diff --git a/rplexpr/rplasclasses.hpp b/rplexpr/rplasclasses.hpp index 72c2038..fbb5df2 100644 --- a/rplexpr/rplasclasses.hpp +++ b/rplexpr/rplasclasses.hpp @@ -13,16 +13,16 @@ class RplSymbolSpace; class RplVariable { public: - RplVariable(const QString& name); + RplVariable(const QByteArray& name); public: void dump(RplWriter& writer, int indent); RplASClass* type() const; void setType(RplASClass* type); - const QString& name() const; + const QByteArray& name() const; protected: - QString m_name; + QByteArray m_name; // NULL for "simple" variables (int, float, bool) RplSymbolSpace* m_namespace; RplASVariant m_value; @@ -50,24 +50,24 @@ public: }; public: - typedef QMap VariableMap; - typedef QMap ClassMap; - typedef QMap MethodMap; + typedef QMap VariableMap; + typedef QMap ClassMap; + typedef QMap MethodMap; typedef QList VariableList; private: RplSymbolSpace(RplASTree& tree); public: - RplSymbolSpace(SymbolSpaceType type, const QString& name, + RplSymbolSpace(SymbolSpaceType type, const QByteArray& name, RplSymbolSpace* parent); virtual ~RplSymbolSpace(); public: void startScope(RplASScope& scope); void finishScope(int endOfScope, RplASScope& scope); - RplASVarDefinition* findVariable(const QString& name) const; - RplASClass* findClass(const QString& name) const; - RplASMethod* findMethod(const QString& name) const; + RplASVarDefinition* findVariable(const QByteArray& name) const; + RplASClass* findClass(const QByteArray& name) const; + RplASMethod* findMethod(const QByteArray& name) const; void dump(RplWriter& writer, int indent, const char* header = NULL); - const QString& name() const; + const QByteArray& name() const; RplASItem* body() const; void setBody(RplASItem* body); RplASItem* addVariable(RplASVarDefinition* variable, int& varNo); @@ -80,7 +80,7 @@ public: static RplSymbolSpace* createGlobal(RplASTree& tree); private: SymbolSpaceType m_type; - QString m_name; + QByteArray m_name; VariableMap m_variables; ClassMap m_classes; MethodMap m_methods; @@ -97,7 +97,7 @@ public: void* newValueInstance(void* source = NULL) const; void destroyValueInstance(void* object) const; virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; public: static RplASBoolean* m_instance; }; @@ -105,12 +105,12 @@ public: class RplASFloat : public RplASClass { public: RplASFloat(RplASTree& tree); - RplASFloat(const QString& name, RplASTree& tree); + RplASFloat(const QByteArray& name, RplASTree& tree); public: void* newValueInstance(void* source = NULL) const; void destroyValueInstance(void* object) const; virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; public: static RplASFloat* m_instance; }; @@ -120,7 +120,7 @@ public: RplASInteger(RplASTree& tree); public: virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; public: static RplASInteger* m_instance; }; @@ -132,7 +132,7 @@ public: void* newValueInstance(void* source = NULL) const; void destroyValueInstance(void* object) const; virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; public: static RplASString* m_instance; }; @@ -144,7 +144,7 @@ public: void* newValueInstance(void* source = NULL) const; void destroyValueInstance(void* object) const; virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; public: static RplASList* m_instance; }; @@ -156,7 +156,7 @@ public: void* newValueInstance(void* source = NULL) const; void destroyValueInstance(void* object) const; virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; public: static RplASMap* m_instance; }; @@ -168,7 +168,7 @@ public: void* newValueInstance(void* source = NULL) const; void destroyValueInstance(void* object) const; virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; public: static RplASVoid* m_instance; }; @@ -180,20 +180,20 @@ public: void* newValueInstance(void* source = NULL) const; void destroyValueInstance(void* object) const; virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; public: static RplASFormula* m_instance; }; class RplASUserClass : public RplASClass { public: - RplASUserClass(const QString& name, const RplSourcePosition* position, + RplASUserClass(const QByteArray& name, const RplSourcePosition* position, RplASTree& tree); public: void* newValueInstance(void* source = NULL) const; void destroyValueInstance(void* object) const; virtual bool boolValueOf(void* object) const; - virtual QString toString(void *object, int maxLength = 80) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; const RplSourcePosition* position() const; private: diff --git a/rplexpr/rplastree.cpp b/rplexpr/rplastree.cpp index df05d16..3db6a3e 100644 --- a/rplexpr/rplastree.cpp +++ b/rplexpr/rplastree.cpp @@ -26,6 +26,18 @@ enum { LOC_UNOP_3, LOC_UNOP_4, // 10005 LOC_BINOP_1, + LOC_BINOP_CALC_1, + LOC_BINOP_CALC_2, + LOC_BINOP_CALC_3, + LOC_BINOP_CALC_4, + LOC_BINOP_CALC_5, + LOC_BINOP_CALC_6, + LOC_BINOP_CALC_7, + LOC_BINOP_CALC_8, + LOC_BINOP_CALC_9, + LOC_BINOP_CALC_10, + LOC_BINOP_CALC_11, + LOC_BINOP_CALC_12, LOC_COUNT }; @@ -47,19 +59,19 @@ unsigned int RplASItem::m_nextId = 1; */ void dumpMap(RplWriter& writer, RplASMapOfVariants& map, bool withEndOfLine) { - QList sorted; + QList sorted; sorted.reserve(map.size()); RplASMapOfVariants::iterator it; for (it = map.begin(); it != map.end(); it++){ sorted.append(it.key()); } - qSort(sorted.begin(), sorted.end(), qLess()); - QList::iterator it2; + qSort(sorted.begin(), sorted.end(), qLess()); + QList::iterator it2; bool first = true; for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ RplASVariant* value = map[*it2]; - writer.format("%c'%s':%s", first ? '{' : ',', (*it2).toUtf8().constData(), - value->toString().toUtf8().constData()); + writer.format("%c'%s':%s", first ? '{' : ',', (*it2).constData(), + value->toString().constData()); first = false; } if (first) @@ -179,6 +191,10 @@ RplASVariant&RplASVariant::operator=(const RplASVariant& source) */ void RplASVariant::copyValue(const RplASVariant& source) { + destroyValue(); + m_variantType = source.m_variantType; + m_class = source.m_class; + switch(source.m_variantType) { case VT_BOOL: @@ -194,7 +210,9 @@ void RplASVariant::copyValue(const RplASVariant& source) break; default: m_value.m_object = m_class->newValueInstance(source.m_value.m_object); + break; } + m_flags = source.m_flags; } /** @@ -236,6 +254,9 @@ const char*RplASVariant::nameOfType() const { const char* rc = "?"; switch(m_variantType){ + case VT_UNDEF: + rc = ""; + break; case VT_FLOAT: rc = "Float"; break; @@ -333,14 +354,14 @@ void* RplASVariant::asObject(const RplASClass** clazz) const * @return the value as string * @throw RplException the instance is not a string value */ -const QString* RplASVariant::asString() const +const QByteArray* RplASVariant::asString() const { const RplASClass* clazz; - const QString* rc = static_cast(asObject(&clazz)); + const QByteArray* rc = static_cast(asObject(&clazz)); if (clazz != RplASString::m_instance){ - const QString& name = clazz->name(); + const QByteArray& name = clazz->name(); throw RplException("RplASVariant::asString: not a string: %s", - name.toUtf8().constData()); + name.constData()); } return rc; } @@ -389,10 +410,10 @@ void RplASVariant::setBool(bool value) * * @param string the string value. */ -void RplASVariant::setString(const QString& string) +void RplASVariant::setString(const QByteArray& string) { // deletion in RplASVariant::destroyValue(): - setObject(new QString(string), RplASString::m_instance); + setObject(new QByteArray(string), RplASString::m_instance); } /** @@ -401,19 +422,22 @@ void RplASVariant::setString(const QString& string) * @param maxLength the maximum length of the result * @return the value as string */ -QString RplASVariant::toString(int maxLength) const +QByteArray RplASVariant::toString(int maxLength) const { - QString rc; + QByteArray rc; + char buffer[256]; switch(m_variantType) { case VT_BOOL: rc = m_value.m_bool ? "True" : "False"; break; case VT_FLOAT: - rc.sprintf("%f", m_value.m_float); + qsnprintf(buffer, sizeof buffer, "%f", m_value.m_float); + rc = buffer; break; case VT_INTEGER: - rc.sprintf("%d", m_value.m_int); + qsnprintf(buffer, sizeof buffer, "%lld", m_value.m_int); + rc = buffer; break; case VT_OBJECT: rc = m_class->toString(m_value.m_object, maxLength); @@ -712,7 +736,7 @@ void RplASConstant::dump(RplWriter& writer, int indent) { char buffer[256]; writer.formatIndented(indent, "const id: %d value: %s %s", m_id, - m_value.toString().toUtf8().constData(), + m_value.toString().constData(), positionStr(buffer, sizeof buffer)); } @@ -781,8 +805,8 @@ void RplASListConstant::dump(RplWriter& writer, int indent) writer.formatIndented(indent, "listConst id: %d %s", m_id, positionStr(buffer, sizeof buffer)); - QString sValue = m_value.toString(8092); - writer.writeIndented(indent + 1, sValue.toUtf8().constData()); + QByteArray sValue = m_value.toString(8092); + writer.writeIndented(indent + 1, sValue.constData()); } /** @@ -880,7 +904,7 @@ RplASMapOfVariants* RplASMapConstant::map() * @param attributes the attributes of the variable */ RplASNamedValue::RplASNamedValue(RplASClass* dataType,RplSymbolSpace* space, - const QString& name, int attributes) : + const QByteArray& name, int attributes) : RplASNode1(AST_NAMED_VALUE), m_name(name), m_attributes(attributes), @@ -895,7 +919,7 @@ RplASNamedValue::RplASNamedValue(RplASClass* dataType,RplSymbolSpace* space, * * @return the name */ -const QString& RplASNamedValue::name() const +const QByteArray& RplASNamedValue::name() const { return m_name; } @@ -929,7 +953,7 @@ void RplASNamedValue::dump(RplWriter& writer, int indent) { char buffer[256]; writer.formatIndented(indent, "namedValue %s id: %d attr: 0x%x %s", - m_name.toUtf8().constData(), m_id, m_attributes, + m_name.constData(), m_id, m_attributes, positionStr(buffer, sizeof buffer)); } /** @@ -1040,7 +1064,7 @@ RplASVarDefinition::RplASVarDefinition() : void RplASVarDefinition::dump(RplWriter& writer, int indent) { RplASNamedValue* namedValue = dynamic_cast(m_child2); - QByteArray name = namedValue->name().toUtf8(); + QByteArray name = namedValue->name(); char endOfScope[32]; endOfScope[0] = '\0'; if (m_endOfScope > 0) @@ -1048,7 +1072,7 @@ void RplASVarDefinition::dump(RplWriter& writer, int indent) char buffer[256]; writer.formatIndented(indent, "varDef %s %s id: %d namedValue: %d value: %d succ: %d %s%s", namedValue == NULL || namedValue->dataType() == NULL - ? "?" : namedValue->dataType()->name().toUtf8().constData(), + ? "?" : namedValue->dataType()->name().constData(), name.constData(), m_id, m_child2 == NULL ? 0 : m_child2->id(), m_child3 == NULL ? 0 : m_child3->id(), @@ -1065,10 +1089,10 @@ void RplASVarDefinition::dump(RplWriter& writer, int indent) * * @return the name */ -const QString& RplASVarDefinition::name() const +const QByteArray& RplASVarDefinition::name() const { RplASNamedValue* namedValue = dynamic_cast(m_child2); - const QString& rc = namedValue->name(); + const QByteArray& rc = namedValue->name(); return rc; } @@ -2033,7 +2057,7 @@ void RplASRepeat::dump(RplWriter& writer, int indent) /** * @brief Constructor. */ -RplASClass::RplASClass(const QString& name, RplASTree& tree) : +RplASClass::RplASClass(const QByteArray& name, RplASTree& tree) : m_name(name), m_symbols(NULL), m_superClass(NULL), @@ -2057,7 +2081,7 @@ RplASClass::~RplASClass() * * @return the class name */ -const QString& RplASClass::name() const +const QByteArray& RplASClass::name() const { return m_name; } @@ -2070,9 +2094,9 @@ const QString& RplASClass::name() const */ void RplASClass::dump(RplWriter& writer, int indent) { - writer.formatIndented(indent, "class %s super: %s", m_name.toUtf8().constData(), + writer.formatIndented(indent, "class %s super: %s", m_name.constData(), m_superClass == NULL - ? "" : m_superClass->name().toUtf8().constData()); + ? "" : m_superClass->name().constData()); m_symbols->dump(writer, indent); } @@ -2173,7 +2197,7 @@ bool RplASTree::startModule(RplSourceUnitName name) * @return NULL: not found
* otherwise: the symbol space of the module */ -RplSymbolSpace* RplASTree::findmodule(const QString& name) +RplSymbolSpace* RplASTree::findmodule(const QByteArray& name) { RplSymbolSpace* rc = m_modules.contains(name) ? m_modules[name] : NULL; return rc; @@ -2202,12 +2226,12 @@ void RplASTree::finishModule(RplSourceUnitName name) * @param type the symbol space type * @return the new symbol space */ -RplSymbolSpace* RplASTree::startClassOrMethod(const QString& name, +RplSymbolSpace* RplASTree::startClassOrMethod(const QByteArray& name, RplSymbolSpace::SymbolSpaceType type) { // the stack m_modules is never empty because of "global" and modules. RplSymbolSpace* parent = m_symbolSpaces[m_symbolSpaces.size() - 1]; - QString fullName = parent->name() + "." + name; + QByteArray fullName = parent->name() + "." + name; // freed in ~RplASTree() RplSymbolSpace* space = new RplSymbolSpace(type, fullName, parent); m_symbolSpaceHeap[fullName] = space; @@ -2221,12 +2245,12 @@ RplSymbolSpace* RplASTree::startClassOrMethod(const QString& name, * * @param name the name of the class (short form) */ -void RplASTree::finishClassOrMethod(const QString& name) +void RplASTree::finishClassOrMethod(const QByteArray& name) { RplSymbolSpace* top = m_symbolSpaces.at(m_symbolSpaces.size() - 1); if (! top->name().endsWith("." + name)) throw RplException("RplASTree::finishModule(): class is not top: %s", - name.toUtf8().constData()); + name.constData()); else { m_symbolSpaces.removeLast(); // "global" is the bottom always! @@ -2281,14 +2305,14 @@ void RplASTree::dump(const char* filename, int flags, const char* header) m_global->dump(writer, 0, "=== Globals:"); } if (flags & DMP_MODULES){ - QList sorted; + QList sorted; sorted.reserve(m_modules.size()); SymbolSpaceMap::iterator it; for (it = m_modules.begin(); it != m_modules.end(); it++){ sorted.append(it.key()); } - qSort(sorted.begin(), sorted.end(), qLess()); - QList::iterator it2; + qSort(sorted.begin(), sorted.end(), qLess()); + QList::iterator it2; for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ RplSymbolSpace* space = m_modules[*it2]; space->dump(writer, 0); @@ -2313,7 +2337,7 @@ void RplASTree::dump(const char* filename, int flags, const char* header) * otherwise: the parent (variable, field ...) */ -RplASMethodCall::RplASMethodCall(const QString& name, RplASItem* parent) : +RplASMethodCall::RplASMethodCall(const QByteArray& name, RplASItem* parent) : RplASNode3(AST_METHOD_CALL), RplASStatement(), m_name(name), @@ -2334,7 +2358,7 @@ void RplASMethodCall::dump(RplWriter& writer, int indent) { char buffer[256]; writer.formatIndented(indent, "call %s Id: %d args: %d parent: %d succ: %d %s", - m_name.toUtf8().constData(), m_id, + m_name.constData(), m_id, m_child2 == NULL ? 0 : m_child2->id(), m_child3 == NULL ? 0 : m_child3->id(), m_child == NULL ? 0 : m_child->id(), @@ -2387,6 +2411,9 @@ RplASArgument* RplASMethodCall::arg1() const /** @class RplASBinaryOp rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements binary operator for the Abstract Syntax Tree. + * + * m_child: left operand
+ * m_child2: right operand */ /** * @brief Constructor. @@ -2407,22 +2434,171 @@ void RplASBinaryOp::calc(RplVMThread& thread) if (isAssignment()) assign(thread); else{ - switch(m_operator){ - case BOP_PLUS: - case BOP_MINUS: - case BOP_TIMES: - case BOP_DIV: - case BOP_MOD: - case BOP_POWER: - case BOP_LOG_OR: - case BOP_LOG_AND: - case BOP_LOG_XOR: - case BOP_BIT_OR: - case BOP_BIT_AND: - case BOP_BIT_XOR: - break; - default: - break; + RplASCalculable* op1 = dynamic_cast(m_child); + RplASCalculable* op2 = dynamic_cast(m_child2); + if (op1 == NULL || op2 == NULL) + error(thread.logger(), LOC_BINOP_CALC_1, "operand is null: %d / %d", + m_child == NULL ? 0 : m_child->id(), + m_child2 == NULL ? 0 : m_child2->id()); + else{ + op1->calc(thread); + op2->calc(thread); + RplASVariant& val1 = thread.top2OfValues(); + RplASVariant& val2 = thread.topOfValues(); + switch(m_operator){ + case BOP_PLUS: + switch(val1.variantType()){ + case RplASVariant::VT_FLOAT: + val1.setFloat(val1.asFloat() + val2.asFloat()); + break; + case RplASVariant::VT_INTEGER: + val1.setInt(val1.asInt() + val2.asInt()); + break; + case RplASVariant::VT_OBJECT: + //if (val1.getClass() == RplASString::m_instance) + default: + error(thread.logger(), LOC_BINOP_CALC_2, "invalid type for '+': %s", + val1.nameOfType()); + break; + } + break; + case BOP_MINUS: + switch(val1.variantType()){ + case RplASVariant::VT_FLOAT: + val1.setFloat(val1.asFloat() - val2.asFloat()); + break; + case RplASVariant::VT_INTEGER: + val1.setInt(val1.asInt() - val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_3, "invalid type for '-': %s", + val1.nameOfType()); + break; + } + break; + case BOP_TIMES: + switch(val1.variantType()){ + case RplASVariant::VT_FLOAT: + val1.setFloat(val1.asFloat() * val2.asFloat()); + break; + case RplASVariant::VT_INTEGER: + val1.setInt(val1.asInt() * val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_4, "invalid type for '*': %s", + val1.nameOfType()); + break; + } + break; + case BOP_DIV: + switch(val1.variantType()){ + case RplASVariant::VT_FLOAT: + val1.setFloat(val1.asFloat() / val2.asFloat()); + break; + case RplASVariant::VT_INTEGER: + val1.setInt(val1.asInt() / val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_5, "invalid type for '/': %s", + val1.nameOfType()); + break; + } + break; + case BOP_MOD: + switch(val1.variantType()){ + case RplASVariant::VT_FLOAT: + val1.setFloat(fmod(val1.asFloat(), val2.asFloat())); + break; + case RplASVariant::VT_INTEGER: + val1.setInt(val1.asInt() % val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_6, "invalid type for '%': %s", + val1.nameOfType()); + break; + } + break; + case BOP_POWER: + switch(val1.variantType()){ + case RplASVariant::VT_FLOAT: + val1.setFloat(fmod(val1.asFloat(), val2.asFloat())); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_7, "invalid type for '**': %s", + val1.nameOfType()); + break; + } + break; + case BOP_LOG_OR: + switch(val1.variantType()){ + case RplASVariant::VT_BOOL: + val1.setBool(val1.asBool() || val2.asBool()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_8, "invalid type for '||': %s", + val1.nameOfType()); + break; + } + break; + case BOP_LOG_AND: + switch(val1.variantType()){ + case RplASVariant::VT_BOOL: + val1.setBool(val1.asBool() && val2.asBool()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_9, "invalid type for '&&': %s", + val1.nameOfType()); + break; + } + break; + case BOP_LOG_XOR: + switch(val1.variantType()){ + case RplASVariant::VT_BOOL: + val1.setBool(val1.asBool() != val2.asBool()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_9, "invalid type for '^^': %s", + val1.nameOfType()); + break; + } + break; + case BOP_BIT_OR: + switch(val1.variantType()){ + case RplASVariant::VT_INTEGER: + val1.setInt(val1.asInt() | val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_10, "invalid type for '|': %s", + val1.nameOfType()); + break; + } + break; + case BOP_BIT_AND: + switch(val1.variantType()){ + case RplASVariant::VT_INTEGER: + val1.setInt(val1.asInt() & val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_11, "invalid type for '&': %s", + val1.nameOfType()); + break; + } + break; + case BOP_BIT_XOR: + switch(val1.variantType()){ + case RplASVariant::VT_INTEGER: + val1.setInt(val1.asInt() ^ val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_12, "invalid type for '^': %s", + val1.nameOfType()); + break; + } + break; + default: + break; + } + thread.popValue(); } } } @@ -2479,7 +2655,7 @@ void RplASBinaryOp::assign(RplVMThread& thread) RplASVariant& rValue = thread.lValue(m_child); RplASCalculable* expr = dynamic_cast(m_child2); if (expr == NULL) - error(thread.logger(), LOC_BINOP_1, "not a calulable: id: %d", + error(thread.logger(), LOC_BINOP_1, "not a calculable: id: %d", m_child2 == NULL ? 0 : m_child2->id()); else { RplASVariant& value = thread.popValue(); @@ -2487,9 +2663,9 @@ void RplASBinaryOp::assign(RplVMThread& thread) case BOP_ASSIGN: break; case BOP_PLUS_ASSIGN: - switch(value.variantType()){ + //switch(value.variantType()){ - } + //} break; case BOP_MINUS_ASSIGN: case BOP_TIMES_ASSIGN: @@ -2651,7 +2827,7 @@ const char* RplASBinaryOp::nameOfOp(RplASBinaryOp::BinOperator op) * @param name the method name * @param tree the abstract syntax tree */ -RplASMethod::RplASMethod(const QString& name, RplASTree& tree) : +RplASMethod::RplASMethod(const QByteArray& name, RplASTree& tree) : RplASNode2(AST_METHOD), m_name(name), m_resultType(NULL), @@ -2674,11 +2850,11 @@ void RplASMethod::dump(RplWriter& writer, int indent) char buffer[256]; writer.indent(indent); writer.format("Method %s %s(", - m_resultType == NULL ? "" : m_resultType->name().toUtf8().constData(), - m_name.toUtf8().constData()); + m_resultType == NULL ? "" : m_resultType->name().constData(), + m_name.constData()); RplSymbolSpace* parent = m_symbols->parent(); writer.formatLine(") id: %d parent: %s args: %d body: %d %s", m_id, - parent == NULL ? "" : parent->name().toUtf8().constData(), + parent == NULL ? "" : parent->name().constData(), m_child2 == NULL ? 0 : m_child2->id(), m_child->id(), positionStr(buffer, sizeof buffer)); @@ -2709,7 +2885,7 @@ void RplASMethod::setSymbols() * @return the name */ -const QString& RplASMethod::name() const +const QByteArray& RplASMethod::name() const { return m_name; } @@ -2818,7 +2994,7 @@ void RplASArgument::dump(RplWriter& writer, int indent) * * @param name name of the field */ -RplASField::RplASField(const QString& name) : +RplASField::RplASField(const QByteArray& name) : RplASNode1(AST_FIELD), m_name(name) { @@ -2834,7 +3010,7 @@ void RplASField::dump(RplWriter& writer, int indent) { char buffer[256]; writer.formatIndented(indent, "field %s id: %d parent: %d succ: %s", - m_name.toUtf8().constData(), m_id, + m_name.constData(), m_id, m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); m_child->dump(writer, indent + 1); diff --git a/rplexpr/rplastree.hpp b/rplexpr/rplastree.hpp index 24d54ea..96492a5 100644 --- a/rplexpr/rplastree.hpp +++ b/rplexpr/rplastree.hpp @@ -84,13 +84,13 @@ public: int asInt() const; bool asBool() const; void* asObject(const RplASClass** clazz) const; - const QString* asString() const; + const QByteArray* asString() const; void setFloat(qreal number); void setInt(int integer); void setBool(bool value); void setObject(void* object, const RplASClass* clazz); - void setString(const QString& string); - QString toString(int maxLength = 80) const; + void setString(const QByteArray& string); + QByteArray toString(int maxLength = 80) const; VariantType variantType() const; const char* nameOfType() const; const RplASClass* getClass() const; @@ -264,7 +264,7 @@ protected: }; typedef QList RplASListOfVariants; -typedef QMap RplASMapOfVariants; +typedef QMap RplASMapOfVariants; class RplASListConstant : public RplASNode1, public RplASCalculable { @@ -315,9 +315,9 @@ public: public: RplASNamedValue(RplASClass* dataType, RplSymbolSpace* space, - const QString& name, int attributes); + const QByteArray& name, int attributes); public: - const QString& name() const; + const QByteArray& name() const; void setSymbolSpace(RplSymbolSpace* space, int variableNo); virtual void calc(RplVMThread& thread); void dump(RplWriter& writer, int indent); @@ -327,7 +327,7 @@ public: int variableNo() const; void setVariableNo(int variableNo); protected: - QString m_name; + QByteArray m_name; int m_attributes; RplASClass* m_dataType; RplSymbolSpace* m_symbolSpace; @@ -357,7 +357,7 @@ public: public: virtual void execute(RplVMThread& thread); void dump(RplWriter& writer, int indent); - const QString& name() const; + const QByteArray& name() const; RplASClass* datatype() const; int endOfScope() const; void setEndOfScope(int endOfScope); @@ -533,7 +533,7 @@ class RplASMethod; class RplASMethodCall : public RplASNode3, public RplASStatement { public: - RplASMethodCall(const QString& name, RplASItem* parent); + RplASMethodCall(const QByteArray& name, RplASItem* parent); public: void dump(RplWriter& writer, int indent); virtual void execute(RplVMThread& thread); @@ -544,7 +544,7 @@ public: RplASArgument*arg1() const; private: - QString m_name; + QByteArray m_name; RplASMethod* m_method; }; @@ -554,18 +554,18 @@ public: RplParameter(); virtual ~RplParameter(); private: - QString m_name; + QByteArray m_name; RplASNamedValue* m_default; }; class RplASField : public RplASNode1 { public: - RplASField(const QString& name); + RplASField(const QByteArray& name); public: void dump(RplWriter& writer, int indent); private: - QString m_name; + QByteArray m_name; }; @@ -574,19 +574,19 @@ class RplSymbolSpace; class RplASMethod : public RplASNode2 { public: - RplASMethod(const QString& name, RplASTree& tree); + RplASMethod(const QByteArray& name, RplASTree& tree); public: void execute(RplVMThread& thread); void dump(RplWriter& writer, int indent); RplSymbolSpace* symbols() const; void setSymbols(); - const QString& name() const; + const QByteArray& name() const; bool equalSignature(RplASMethod& other) const; RplASMethod* sibling() const; void setSibling(RplASMethod* sibling); private: - QString m_name; + QByteArray m_name; RplASClass* m_resultType; RplSymbolSpace* m_symbols; // chain over all overloaded methods (same name, other signature): @@ -596,9 +596,9 @@ private: class RplASClass { public: - typedef QMap MethodMap; + typedef QMap MethodMap; public: - RplASClass(const QString& name, RplASTree& m_tree); + RplASClass(const QByteArray& name, RplASTree& m_tree); virtual ~RplASClass(); public: /** @@ -633,13 +633,13 @@ public: * @param maxLength the maximum length of the result (string) * @return a string describing the object */ - virtual QString toString(void *object, int maxLength = 80) const = 0; + virtual QByteArray toString(void *object, int maxLength = 80) const = 0; public: - const QString& name() const; + const QByteArray& name() const; virtual void dump(RplWriter& writer, int indent); void setSymbols(); protected: - QString m_name; + QByteArray m_name; RplSymbolSpace* m_symbols; const RplASClass* m_superClass; RplASTree& m_tree; @@ -659,7 +659,7 @@ public: DMP_ALL = DMP_GLOBALS | DMP_MODULES | DMP_SPACE_STACK | DMP_SPACE_HEAP, DMP_NO_GLOBALS = DMP_MODULES | DMP_SPACE_STACK | DMP_SPACE_HEAP }; - typedef QMap SymbolSpaceMap; + typedef QMap SymbolSpaceMap; typedef QList SymbolSpaceStack; public: RplASTree(); @@ -667,16 +667,16 @@ public: public: bool startModule(RplSourceUnitName name); void finishModule(RplSourceUnitName name); - RplSymbolSpace* startClassOrMethod(const QString& name, + RplSymbolSpace* startClassOrMethod(const QByteArray& name, RplSymbolSpace::SymbolSpaceType type); - void finishClassOrMethod(const QString& name); + void finishClassOrMethod(const QByteArray& name); SymbolSpaceStack& symbolSpaces(); RplSymbolSpace* currentSpace() const; - RplASClass* findClass(const QString& name); + RplASClass* findClass(const QByteArray& name); void clear(); void dump(const char* filename, int flags = DMP_ALL, const char* header = NULL); - RplSymbolSpace*findmodule(const QString& name); + RplSymbolSpace*findmodule(const QByteArray& name); RplSourcePosition* copyPosition(); RplByteStorage& store(); diff --git a/rplexpr/rpllexer.cpp b/rplexpr/rpllexer.cpp index f573ab5..1366cf8 100644 --- a/rplexpr/rpllexer.cpp +++ b/rplexpr/rpllexer.cpp @@ -98,7 +98,7 @@ RplToken& RplToken::operator =(const RplToken& source) * @brief Returns the string representation of the instance * @return a string representing the instance */ -const QString& RplToken::toString() +const QByteArray& RplToken::toString() { return m_string; } @@ -146,7 +146,7 @@ qreal RplToken::asReal() const * * @return the value of the token as floating point value */ -const QString& RplToken::rawString() const +const QByteArray& RplToken::rawString() const { return m_printableString; } @@ -235,8 +235,8 @@ void RplToken::clear() */ bool RplToken::isCapitalizedId() const { - bool rc = m_tokenType == TOKEN_ID && m_string.at(0).isUpper() - && (m_string.length() == 1 || m_string.at(1).isLower()); + bool rc = m_tokenType == TOKEN_ID && isupper(m_string.at(0)) + && (m_string.length() == 1 || islower(m_string.at(1))); return rc; } @@ -262,7 +262,7 @@ QByteArray RplToken::asUtf8() const break; case TOKEN_STRING: qsnprintf(buffer, sizeof buffer, "'%.*s'", int(sizeof buffer) - 1, - m_printableString.toUtf8().constData()); + m_printableString.constData()); break; case TOKEN_NUMBER: qsnprintf(buffer, sizeof buffer, "%lld", m_value.m_integer); @@ -276,7 +276,7 @@ QByteArray RplToken::asUtf8() const break; case TOKEN_ID: qsnprintf(buffer, sizeof buffer, "'%.*s'", int(sizeof buffer) - 1, - m_string.toUtf8().constData()); + m_string.constData()); break; case TOKEN_COMMENT_REST_OF_LINE: case TOKEN_COMMENT_START: @@ -361,14 +361,13 @@ static void itemsToVector(const char* items, RplLexer::StringList& vector, int id = 0; for (it = list.begin(); it < list.end(); it++){ QByteArray& item2 = *it; - QString item(item2); + QByteArray item(item2); id++; - item += QChar(' '); - item += QChar(id); - vector.push_back(item); + item.append(' ').append(id % 256).append(id / 256); + vector.append(item); unsigned char cc = item2.at(0); if (cc < 128) - charInfo[cc] |= firstCharFlag; + charInfo[cc] |= firstCharFlag; if(item2.size() > 1){ cc = item2.at(1); if (cc < 128) @@ -387,7 +386,7 @@ static void itemsToVector(const char* items, RplLexer::StringList& vector, } } } - qSort(vector.begin(), vector.end(), qLess()); + qSort(vector.begin(), vector.end(), qLess()); } static void charClassToCharInfo(const char* charClass, int flag, @@ -534,7 +533,7 @@ void RplLexer::prepareOperators(const char* operators, // the entries of m_operators end with ' ' and id: if (m_operators.at(ix).size() == 1 + 2 && m_operators.at(ix).at(0) != m_operators.at(ix+1).at(0)){ - int cc = (char) m_operators[ix].at(0).unicode(); + int cc = (char) m_operators[ix].at(0); m_charInfo[cc] |= CC_OP_1_ONLY; } @@ -619,19 +618,18 @@ int RplLexer::findInVector(int tokenLength, const StringList& vector) int half = (ubound + lbound) / 2; int compareRc = 0; int ix = 0; - const QString& current = vector[half]; - // vector items end with ' ' and id: - int currentLength = current.size() - 2; + const QByteArray& current = vector[half]; + // vector items end with ' ' and id (2 byte): + int currentLength = current.size() - 3; while(ix < tokenLength && compareRc == 0){ if (ix >= currentLength) // current is shorter: compareRc = 1; else - compareRc = m_input.at(ix).unicode() - - (int) current.at(ix).unicode(); + compareRc = m_input.at(ix) - (int) current.at(ix); ix++; } - if (compareRc == 0 && current.at(ix).unicode() != ' ') + if (compareRc == 0 && current.at(ix) != ' ') // token.size() < current.size(): compareRc = -1; if (compareRc < 0) @@ -639,7 +637,7 @@ int RplLexer::findInVector(int tokenLength, const StringList& vector) else if (compareRc > 0) lbound = half + 1; else { - id = current[currentLength + 1].unicode(); + id = current[currentLength + 1] + current[currentLength + 2] * 256; break; } } @@ -691,11 +689,11 @@ RplToken* RplLexer::findTokenWithId(RplTokenType tokenType, int flag2, int inputLength = m_input.size(); int cc; if (inputLength > 1){ - cc = m_input[1].unicode(); + cc = m_input[1]; if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag2)){ length++; if (inputLength > 2){ - cc = m_input[2].unicode(); + cc = m_input[2]; // the 3rd char flag is the "successor" of the 2nd char flag: int flag = (flag2 << 1); if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag)){ @@ -703,7 +701,7 @@ RplToken* RplLexer::findTokenWithId(RplTokenType tokenType, int flag2, // the rest char flag is the "successor" of the 3nd char flag: flag <<= 1; while (length < inputLength){ - cc = m_input[length].unicode(); + cc = m_input[length]; if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag)) length++; else @@ -715,7 +713,7 @@ RplToken* RplLexer::findTokenWithId(RplTokenType tokenType, int flag2, } RplToken* rc = NULL; if (! (tokenType == TOKEN_KEYWORD && length < inputLength - && (cc = m_input[length].unicode()) < CHAR_INFO_SIZE + && (cc = m_input[length]) < CHAR_INFO_SIZE && (m_charInfo[cc] & CC_REST_ID))) { int id; // the length could be too long: the CC_2nd_.. flag could be ambigous @@ -750,10 +748,10 @@ RplToken* RplLexer::scanNumber() int cc; int length; quint64 value = 0; - if ( (cc = m_input[0].unicode()) == '0' && inputLength > 1 + if ( (cc = m_input[0]) == '0' && inputLength > 1 && (m_numericTypes & NUMTYPE_HEXADECIMAL) - && (m_input[1].unicode() == 'x' || m_input[1].unicode() == 'X')){ - length = RplQString::lengthOfUInt64(m_input, 2, 16, &value); + && (m_input[1] == 'x' || m_input[1] == 'X')){ + length = RplString::lengthOfUInt64(m_input.constData() + 2, 16, &value); if (length > 0) length += 2; else @@ -762,7 +760,7 @@ RplToken* RplLexer::scanNumber() && inputLength > 1){ length = 1; while (length < inputLength){ - if ( (cc = m_input[length].unicode()) >= '0' && cc <= '7') + if ( (cc = m_input[length]) >= '0' && cc <= '7') value = value * 8 + cc - '0'; else if (cc >= '8' && cc <= '9') throw RplLexException(*m_currentPosition, @@ -775,7 +773,7 @@ RplToken* RplLexer::scanNumber() length = 1; value = cc - '0'; while (length < inputLength){ - if ( (cc = m_input[length].unicode()) >= '0' && cc <= '9') + if ( (cc = m_input[length]) >= '0' && cc <= '9') value = value * 10 + cc - '0'; else break; @@ -785,9 +783,9 @@ RplToken* RplLexer::scanNumber() m_currentToken->m_value.m_integer = value; m_currentToken->m_tokenType = TOKEN_NUMBER; if (length + 1 < inputLength - && ((cc = m_input[length].unicode()) == '.' || toupper(cc) == 'E')){ + && ((cc = m_input[length]) == '.' || toupper(cc) == 'E')){ qreal realValue; - int realLength = RplQString::lengthOfReal(m_input, 0, &realValue); + int realLength = RplString::lengthOfReal(m_input.constData(), &realValue); if (realLength > length){ m_currentToken->m_tokenType = TOKEN_REAL; m_currentToken->m_value.m_real = realValue; @@ -805,7 +803,7 @@ RplToken* RplLexer::scanNumber() */ RplToken*RplLexer::scanString() { - int delim = m_input[0].unicode(); + int delim = m_input[0]; int inputLength = m_input.size(); int cc; int length = 1; @@ -813,7 +811,7 @@ RplToken*RplLexer::scanString() m_currentToken->m_value.m_id = delim; bool again = false; do { - while(length < inputLength && (cc = m_input[length].unicode()) != delim){ + while(length < inputLength && (cc = m_input[length]) != delim){ length++; if (cc != '\\' || (m_stringFeatures @@ -823,19 +821,19 @@ RplToken*RplLexer::scanString() if (length >= inputLength) throw RplLexException(*m_currentPosition, "backslash without following character"); - cc = m_input[length++].unicode(); + cc = m_input[length++]; if ( (m_stringFeatures & SF_C_HEX_CHARS) && toupper(cc) == 'X'){ if (length >= inputLength) throw RplLexException(*m_currentPosition, "missing hexadecimal digit behind \\x"); - cc = m_input[length++].unicode(); + cc = m_input[length++]; int hexVal = RplQString::valueOfHexDigit(cc); if (hexVal < 0) throw RplLexException(*m_currentPosition, "not a hexadecimal digit behind \\x: %lc", QChar(cc)); if (length < inputLength){ - cc = m_input[length].unicode(); + cc = m_input[length]; int nibble = RplQString::valueOfHexDigit(cc); if (nibble >= 0){ length++; @@ -876,7 +874,7 @@ RplToken*RplLexer::scanString() length++; } if ( (m_stringFeatures & SF_DOUBLE_DELIM) && length < inputLength - && m_input[length].unicode() == delim){ + && m_input[length] == (char) delim){ m_currentToken->m_printableString.append(delim); length++; again = true; @@ -899,9 +897,9 @@ void RplLexer::scanComment() { int inputLength = m_input.size(); int length = 1; - QString& commentEnd = m_commentEnds[m_currentToken->id()]; + QByteArray& commentEnd = m_commentEnds[m_currentToken->id()]; int ix; - if (commentEnd[0].unicode() == '\n'){ + if (commentEnd[0] == '\n'){ // single line comment: if (m_storageFlags & STORE_COMMENT) m_currentToken->m_string.append(m_input); @@ -983,13 +981,12 @@ RplToken* RplLexer::nextToken() if (! fillInput()){ m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE; } else { - QChar cc = m_input.at(0); - int cc2 = cc.unicode(); - if (cc.isSpace()){ + int cc = m_input.at(0); + if (isspace(cc)){ //waitingPosition = m_currentPosition; m_currentToken->m_tokenType = TOKEN_SPACE; ix = 1; - while(ix < m_input.size() && m_input.at(ix).isSpace()) + while(ix < m_input.size() && isspace(m_input.at(ix))) ix++; if (m_storageFlags & STORE_BLANK){ m_currentToken->m_string.append(m_input.mid(0, ix)); @@ -997,19 +994,19 @@ RplToken* RplLexer::nextToken() m_currentCol += ix; m_input.remove(0, ix); rc = m_currentToken; - } else if (cc.isDigit()){ + } else if (isdigit(cc)){ rc = scanNumber(); - } else if ( (cc2 == '"' && (m_stringFeatures & SF_QUOTE) != 0) - || (cc2 == '\'' && (m_stringFeatures & SF_TICK) != 0)){ + } else if ( (cc == '"' && (m_stringFeatures & SF_QUOTE) != 0) + || (cc == '\'' && (m_stringFeatures & SF_TICK) != 0)){ rc = scanString(); } else { - if (cc2 >= CHAR_INFO_SIZE) + if (cc >= CHAR_INFO_SIZE) throw RplLexException(*m_currentPosition, "no lexical symbol can start with this char: %lc", cc); else { - if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_COMMENT_START)){ + if (rc == NULL && (m_charInfo[cc] & CC_FIRST_COMMENT_START)){ rc = findTokenWithId(TOKEN_COMMENT_START, CC_2nd_COMMENT_START, m_commentStarts); if (rc != NULL) @@ -1017,8 +1014,8 @@ RplToken* RplLexer::nextToken() //waitingPosition = m_currentPosition; } - if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_OP)){ - if ( (m_charInfo[cc2] & CC_OP_1_ONLY) == 0){ + if (rc == NULL && (m_charInfo[cc] & CC_FIRST_OP)){ + if ( (m_charInfo[cc] & CC_OP_1_ONLY) == 0){ rc = findTokenWithId(TOKEN_OPERATOR, CC_2nd_OP, m_operators); } else { @@ -1029,15 +1026,15 @@ RplToken* RplLexer::nextToken() m_currentCol += 1; } } - if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_KEYWORD)){ + if (rc == NULL && (m_charInfo[cc] & CC_FIRST_KEYWORD)){ rc = findTokenWithId(TOKEN_KEYWORD, CC_2nd_KEYWORD, m_keywords); } - if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_ID)){ + if (rc == NULL && (m_charInfo[cc] & CC_FIRST_ID)){ int length = 1; while(length < m_input.size() - && (cc2 = m_input[length].unicode()) < CHAR_INFO_SIZE - && (m_charInfo[cc2] & CC_REST_ID) != 0) + && (cc = m_input[length]) < CHAR_INFO_SIZE + && (m_charInfo[cc] & CC_REST_ID) != 0) length++; rc = m_currentToken; rc->m_tokenType = TOKEN_ID; @@ -1056,9 +1053,9 @@ RplToken* RplLexer::nextToken() rc = m_currentToken; rc->m_tokenType = TOKEN_END_OF_SOURCE; } else { - QString symbol = m_input.mid(0, qMin(20, m_input.size()-1)); + QByteArray symbol = m_input.mid(0, qMin(20, m_input.size()-1)); throw RplLexException(*m_currentPosition, - "unknown lexical symbol: %s", symbol.toUtf8().constData()); + "unknown lexical symbol: %s", symbol.constData()); } } #if defined (RPL_LEXER_TRACE) diff --git a/rplexpr/rpllexer.hpp b/rplexpr/rpllexer.hpp index 232f6f9..cf27d9b 100644 --- a/rplexpr/rpllexer.hpp +++ b/rplexpr/rpllexer.hpp @@ -43,12 +43,12 @@ public: RplToken& operator =(const RplToken& source); public: friend class RplLexer; - const QString& toString(); + const QByteArray& toString(); bool isInteger(); int asInteger() const; quint64 asUInt64() const; qreal asReal() const; - const QString& rawString() const; + const QByteArray& rawString() const; int id() const; RplTokenType tokenType() const; bool isTokenType(RplTokenType expected) const; @@ -61,9 +61,9 @@ public: QByteArray asUtf8() const; protected: RplTokenType m_tokenType; - QString m_string; + QByteArray m_string; // only for TOKEN_STRING: copy from source but with escaped chars like "\\n" - QString m_printableString; + QByteArray m_printableString; union { // only for TOKEN_KEYWORD and TOKEN_OPERATOR int m_id; @@ -77,7 +77,7 @@ class RplSource; class RplLexer { public: - typedef QList StringList; + typedef QList StringList; enum NumericType { NUMTYPE_UNDEF, NUMTYPE_DECIMAL = 1 << 0, @@ -214,12 +214,12 @@ protected: // index: ord(char) content: a sum of CharClassTags int m_charInfo[128]; // a list of QChars with ord(cc) > 127 and which can be the first char - QString m_idFirstRare; + QByteArray m_idFirstRare; // index: ord(char) content: chr(ix) can be the non first char of an id - QString m_idRestRare; + QByteArray m_idRestRare; // a list of QChars with ord(cc) > 127 and which can be the first char int m_numericTypes; - QString m_idRest2; + QByteArray m_idRest2; RplToken* m_currentToken; RplToken* m_waitingToken; RplToken* m_waitingToken2; @@ -229,7 +229,7 @@ protected: const RplSourcePosition* m_waitingPosition1; const RplSourcePosition* m_waitingPosition2; int m_maxTokenLength; - QString m_input; + QByteArray m_input; int m_currentCol; bool m_hasMoreInput; int m_stringFeatures; diff --git a/rplexpr/rplmfparser.cpp b/rplexpr/rplmfparser.cpp index b3aa969..5a2c094 100644 --- a/rplexpr/rplmfparser.cpp +++ b/rplexpr/rplmfparser.cpp @@ -456,7 +456,7 @@ RplASItem* RplMFParser::parseMap() bool again = true; RplToken* token; RplToken* token2; - QString key; + QByteArray key; while(again){ token = m_lexer.nextNonSpaceToken(); if (token->isOperator(O_RBRACE)) @@ -527,7 +527,7 @@ RplASItem* RplMFParser::parseMap() * @return a RplASNamedValue or a * RplASNamedValue instance */ -RplASItem* RplMFParser::buildVarOrField(const QString& name, +RplASItem* RplMFParser::buildVarOrField(const QByteArray& name, const RplSourcePosition* position, RplASItem* parent) { RplASItem* rc = NULL; @@ -671,7 +671,7 @@ RplASItem* RplMFParser::parseOperand(int level, RplASItem* parent) } case TOKEN_ID: { - QString name = token->toString(); + QByteArray name = token->toString(); if (name == "a") name = "a"; token = m_lexer.nextNonSpaceToken(); @@ -1132,15 +1132,15 @@ void RplMFParser::parseMethod() RplToken* token = m_lexer.nextNonSpaceToken(); if (! token->isTokenType(TOKEN_ID)) syntaxError(L_PARSE_METH_NO_CLASS, "type name expected"); - QString type = token->toString(); - if (! type.at(0).isUpper()) + QByteArray type = token->toString(); + if (! isupper(type.at(0))) syntaxError(L_PARSE_METH_NO_CLASS2, "type name expected (must start with an upper case character)"); token = m_lexer.nextNonSpaceToken(); if (! token->isTokenType(TOKEN_ID)) syntaxError(L_PARSE_METH_NO_NAME, "method name expected"); - QString name = token->toString(); - if (! type.at(0).isUpper()) + QByteArray name = token->toString(); + if (! isupper(type.at(0))) syntaxError(L_PARSE_METH_NO_CLASS2, "method name expected (must start with an lower case character)"); token = m_lexer.nextNonSpaceToken(); @@ -1188,7 +1188,7 @@ void RplMFParser::parseClass() syntaxError(L_PARSE_CLASS_NO_NAME, "class name expected"); if (! token->isCapitalizedId()) syntaxError(L_PARSE_CLASS_LOWERCASE, "class name must start with an uppercase character"); - QString name = token->toString(); + QByteArray name = token->toString(); RplASUserClass* clazz = new RplASUserClass(name, startPos, m_tree); RplSymbolSpace* parent = m_tree.currentSpace(); RplASUserClass* alreadyDefined = parent->addClass(clazz); diff --git a/rplexpr/rplmfparser.hpp b/rplexpr/rplmfparser.hpp index 36b4532..900cc60 100644 --- a/rplexpr/rplmfparser.hpp +++ b/rplexpr/rplmfparser.hpp @@ -89,7 +89,7 @@ protected: RplASVariant* tokenToVariant(RplToken* token, bool endsWithComma, RplASNode1* parent); RplASVariant*createFormula(RplASNode1* parent); - RplASItem* buildVarOrField(const QString& name, + RplASItem* buildVarOrField(const QByteArray& name, const RplSourcePosition* position, RplASItem* parent); RplASExprStatement*parseParameterList(); diff --git a/rplexpr/rplparser.cpp b/rplexpr/rplparser.cpp index 81b1011..477d1dc 100644 --- a/rplexpr/rplparser.cpp +++ b/rplexpr/rplparser.cpp @@ -103,7 +103,7 @@ void RplParser::addSimpleMessage(LevelTag prefix, int location, const RplSourcePosition* position, const char* message){ char buffer[2048]; - QString msg; + QByteArray msg; qsnprintf(buffer, sizeof buffer, "%c%04d %s:%d-%d: ", prefix, location, position->sourceUnit()->name(), position->lineNo(), position->column()); diff --git a/rplexpr/rplparser.hpp b/rplexpr/rplparser.hpp index 8e22aa5..69a8c7d 100644 --- a/rplexpr/rplparser.hpp +++ b/rplexpr/rplparser.hpp @@ -34,7 +34,7 @@ public: }; public: - typedef QList MessageList; + typedef QList MessageList; public: RplParser(RplLexer& lexer, RplASTree& ast); public: diff --git a/rplexpr/rplsource.cpp b/rplexpr/rplsource.cpp index 576744f..b10feac 100644 --- a/rplexpr/rplsource.cpp +++ b/rplexpr/rplsource.cpp @@ -602,8 +602,8 @@ void RplStringSourceUnit::setCurrentPosition(int currentPosition) { * * @return the content */ -const RplSourceUnitContent& RplStringSourceUnit::content() const { - return m_content; +RplSourceUnitContent RplStringSourceUnit::content() const { + return m_content.constData(); } /** @class RplStringReader rplsource.hpp "rplexpr/rplsource.hpp" @@ -656,8 +656,7 @@ RplSourceUnit* RplStringReader::openSourceUnit(RplSourceUnitName unit) { * @return false: no more input available
* true: success */ -bool RplStringReader::nextLine(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore) { +bool RplStringReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore) { bool rc = m_currentSourceUnit != NULL; if (rc){ m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1); @@ -677,25 +676,22 @@ bool RplStringReader::nextLine(int maxSize, RplSourceUnitContent& buffer, * @return false: no more input available
* true: success */ -bool RplStringReader::fillBuffer(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore) { +bool RplStringReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) { RplStringSourceUnit* unit = (RplStringSourceUnit*) m_currentSourceUnit; - int start = unit->currentPosition(); - const RplSourceUnitContent& content = unit->content(); - int end = content.indexOf("\n", start); + RplSourceUnitContent content = unit->content(); + int startPos = unit->currentPosition(); + const char* start = content + startPos; + const char* end = strchr(start, '\n'); hasMore = false; - if(end < 0) { - end = content.size() - 1; - } - int size = end - start + 1; + int size = end == NULL ? strlen(start) : end - start + 1; hasMore = false; if(size > maxSize) { size = maxSize; hasMore = true; } if(size > 0) { - buffer += content.mid(start, size); - unit->setCurrentPosition(start + size); + buffer.append(start, size); + unit->setCurrentPosition(startPos + size); } else { removeSourceUnit(); } @@ -709,7 +705,7 @@ bool RplStringReader::fillBuffer(int maxSize, RplSourceUnitContent& buffer, * @param content */ void RplStringReader::addSource(RplSourceUnitName name, - const RplSourceUnitContent& content) { + RplSourceUnitContent content) { // Deletion in the destructor of the base class RplReader RplStringSourceUnit* unit = new RplStringSourceUnit(name, content, this); m_units.insert(m_units.begin(), unit->name(), unit); @@ -722,7 +718,8 @@ void RplStringReader::addSource(RplSourceUnitName name, * @param name name of the source unit * @param content new content */ -void RplStringReader::replaceSource(RplSourceUnitName name, const RplSourceUnitContent& content) +void RplStringReader::replaceSource(RplSourceUnitName name, + RplSourceUnitContent content) { if (m_units.contains(name)){ RplStringSourceUnit* unit = dynamic_cast(m_units[name]); @@ -809,18 +806,24 @@ RplSourceUnit* RplFileReader::openSourceUnit(RplSourceUnitName unit) { * @return false: no more input available
* true: success */ -bool RplFileReader::nextLine(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore) { +bool RplFileReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore) { RplFileSourceUnit* unit = static_cast (m_currentSourceUnit); - bool rc = ! unit->m_textStream.atEnd(); + bool rc = ! feof(unit->m_fp); if(! rc) { m_source.popSourceUnit(this); } else { m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1); unit->m_currentPosition = 0; - unit->m_line = unit->m_textStream.readLine(); - rc = fillBuffer(maxSize, buffer, hasMore); + QByteArray& line = unit->m_line; + line.reserve(maxSize+1); + if (fgets(line.data(), maxSize, unit->m_fp) == NULL) + rc = false; + else{ + line[maxSize] = '\0'; + line.resize(strlen(line.constData())); + rc = fillBuffer(maxSize, buffer, hasMore); + } } return rc; } @@ -836,17 +839,16 @@ bool RplFileReader::nextLine(int maxSize, RplSourceUnitContent& buffer, * @return false: no more input available
* true: success */ -bool RplFileReader::fillBuffer(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore) { +bool RplFileReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) { RplFileSourceUnit* unit = static_cast(m_currentSourceUnit); int start = unit->m_currentPosition; - const RplSourceUnitContent& content = unit->m_line; + QByteArray& content = unit->m_line; int size = content.size() - start; if(size > maxSize) size = maxSize; buffer += content.mid(start, size); unit->m_currentPosition = (start += size); - hasMore = start < content.length(); + hasMore = start < content.size(); return size > 0; } diff --git a/rplexpr/rplsource.hpp b/rplexpr/rplsource.hpp index 830b955..40f80b9 100644 --- a/rplexpr/rplsource.hpp +++ b/rplexpr/rplsource.hpp @@ -13,7 +13,7 @@ // type of buffer names and filenames. Codec: UTF-8 typedef const char* RplSourceUnitName; -typedef QString RplSourceUnitContent; +typedef const char* RplSourceUnitContent; class RplSource; class RplReader; @@ -91,8 +91,7 @@ public: * @return true: the read was successful
* false: no more input is available */ - virtual bool nextLine(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore) = 0; + virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore) = 0; /** * @brief Reads the next part of the current line into a given buffer. * @@ -102,8 +101,7 @@ public: * @return true: the read was successful
* false: no more input is available */ - virtual bool fillBuffer(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore) = 0; + virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) = 0; public: virtual void clear(); RplSource& source(); @@ -175,11 +173,11 @@ public: public: int currentPosition() const; void setCurrentPosition(int currentPosition); - const RplSourceUnitContent& content() const; + RplSourceUnitContent content() const; private: int m_currentPosition; - RplSourceUnitContent m_content; + QByteArray m_content; }; class RplStringReader : public RplReader{ @@ -189,13 +187,11 @@ public: // RplReader interface public: virtual RplSourceUnit* openSourceUnit(RplSourceUnitName unit); - virtual bool nextLine(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore); - virtual bool fillBuffer(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore); + virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore); + virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore); public: - void addSource(RplSourceUnitName name, const RplSourceUnitContent& content); - void replaceSource(RplSourceUnitName name, const RplSourceUnitContent& content); + void addSource(RplSourceUnitName name, RplSourceUnitContent content); + void replaceSource(RplSourceUnitName name, RplSourceUnitContent content); }; class RplFileReader; @@ -211,7 +207,7 @@ private: int m_currentPosition; FILE* m_fp; QTextStream m_textStream; - RplSourceUnitContent m_line; + QByteArray m_line; }; class RplFileReader : public RplReader{ @@ -221,10 +217,8 @@ public: // RplReader interface public: virtual RplSourceUnit* openSourceUnit(RplSourceUnitName unit); - virtual bool nextLine(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore); - virtual bool fillBuffer(int maxSize, RplSourceUnitContent& buffer, - bool& hasMore); + virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore); + virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore); public: void addSource(RplSourceUnitName filename); }; diff --git a/rplexpr/rplvm.cpp b/rplexpr/rplvm.cpp index 873d3e4..828f04b 100644 --- a/rplexpr/rplvm.cpp +++ b/rplexpr/rplvm.cpp @@ -125,15 +125,15 @@ RplSymbolSpace* RplStackFrame::symbols() const */ RplVMThread::RplVMThread(int maxStack, RplVirtualMachine* vm) : m_id(m_nextId++), - m_singleStep(false), m_debugMode(false), + m_singleStep(false), m_maxStack(maxStack), m_frameStack(), // the stack is never empty! m_topOfFrames(0), m_valueStack(), // the stack is never empty! - m_topOfValues(1), + m_topOfValues(0), m_vm(vm), m_logger(new RplLogger()) { @@ -217,6 +217,18 @@ RplASVariant& RplVMThread::topOfValues() return rc; } + +/** + * @brief Returns the entry under the top of the value stack. + * + * @return the 2nd value the value stack + */ +RplASVariant& RplVMThread::top2OfValues() +{ + RplASVariant& rc = *m_valueStack[m_topOfValues-1]; + return rc; +} + /** * @brief Returns the top of stack and removes it. * @@ -284,7 +296,7 @@ RplASVariant& RplVMThread::valueOfVariable(RplSymbolSpace* symbolSpace, } if (frame == NULL) m_logger->logv(LOG_ERROR, LOC_VAL_OF_VAR_1, "no frame has symbolspace %s", - symbolSpace->name().toUtf8().constData()); + symbolSpace->name().constData()); return rc; } @@ -313,11 +325,11 @@ RplVirtualMachine::RplVirtualMachine(RplASTree& tree, RplSource& source, * * @param module the module's name */ -void RplVirtualMachine::executeModule(const QString& module) +void RplVirtualMachine::executeModule(const char* module) { RplSymbolSpace* space = m_tree.findmodule(module); if (space == NULL) - throw RplVmException("module not found: %s", module.toUtf8().constData()); + throw RplVmException("module not found: %s", module); RplStackFrame frame(space); RplSymbolSpace* mainSpace = NULL; RplASItem* mainStatements = NULL; diff --git a/rplexpr/rplvm.hpp b/rplexpr/rplvm.hpp index c86ed48..8109b4f 100644 --- a/rplexpr/rplvm.hpp +++ b/rplexpr/rplvm.hpp @@ -47,6 +47,7 @@ public: RplLogger* logger() const; RplASVariant& reserveValue(); RplASVariant& topOfValues(); + RplASVariant& top2OfValues(); RplASVariant& popValue(); void valueToTop(RplSymbolSpace* symbolSpace, int variableNo); RplASVariant& lValue(RplASItem* item); @@ -80,7 +81,7 @@ public: public: RplVirtualMachine(RplASTree& tree, RplSource& source, int maxStack = 1024); public: - void executeModule(const QString& module); + void executeModule(const char* module); void addThread(RplASItem* initialization, RplSymbolSpace* spaceInitialization, RplASItem* statements, RplSymbolSpace* space, diff --git a/test/rplmfparser/string1.mf b/test/rplmfparser/string1.mf new file mode 100644 index 0000000..7beb37b --- /dev/null +++ b/test/rplmfparser/string1.mf @@ -0,0 +1,3 @@ +Str x1 = "x1 123456789 123456789 123456789 123456789 123456789"; +Str x2 = "x2 123456789 123456789 123456789 123456789 123456789"; +Str x3 = "x3 123456789 123456789 123456789 123456789 123456789"; diff --git a/test/rplmfparser/string1.txt b/test/rplmfparser/string1.txt new file mode 100644 index 0000000..5dfbe02 --- /dev/null +++ b/test/rplmfparser/string1.txt @@ -0,0 +1,24 @@ +Str x1 = "x1 123456789 123456789 123456789 123456789 123456789"; +Str x2 = "x2 123456789 123456789 123456789 123456789 123456789"; +Str x3 = "x3 123456789 123456789 123456789 123456789 123456789"; += test/rplmfparser/string1.mf (module) parent: $global +== Variables: +varDef Str x1 id: 2 namedValue: 1 value: 3 succ: 5 test/rplmfparser/string1.mf:1:4 + namedValue x1 id: 1 attr: 0x0 test/rplmfparser/string1.mf:1:4 + const id: 3 value: 'x1 123456789 123456789 123456789 123456789 123456789' test/rplmfparser/string1.mf:1:9 +varDef Str x2 id: 5 namedValue: 4 value: 6 succ: 8 test/rplmfparser/string1.mf:3:4 + namedValue x2 id: 4 attr: 0x0 test/rplmfparser/string1.mf:3:4 + const id: 6 value: 'x2 123456789 123456789 123456789 123456789 123456789' test/rplmfparser/string1.mf:3:9 +varDef Str x3 id: 8 namedValue: 7 value: 9 succ: 0 test/rplmfparser/string1.mf:5:4 + namedValue x3 id: 7 attr: 0x0 test/rplmfparser/string1.mf:5:4 + const id: 9 value: 'x3 123456789 123456789 123456789 123456789 123456789' test/rplmfparser/string1.mf:5:9 +== Body: +varDef Str x1 id: 2 namedValue: 1 value: 3 succ: 5 test/rplmfparser/string1.mf:1:4 + namedValue x1 id: 1 attr: 0x0 test/rplmfparser/string1.mf:1:4 + const id: 3 value: 'x1 123456789 123456789 123456789 123456789 123456789' test/rplmfparser/string1.mf:1:9 +varDef Str x2 id: 5 namedValue: 4 value: 6 succ: 8 test/rplmfparser/string1.mf:3:4 + namedValue x2 id: 4 attr: 0x0 test/rplmfparser/string1.mf:3:4 + const id: 6 value: 'x2 123456789 123456789 123456789 123456789 123456789' test/rplmfparser/string1.mf:3:9 +varDef Str x3 id: 8 namedValue: 7 value: 9 succ: 0 test/rplmfparser/string1.mf:5:4 + namedValue x3 id: 7 attr: 0x0 test/rplmfparser/string1.mf:5:4 + const id: 9 value: 'x3 123456789 123456789 123456789 123456789 123456789' test/rplmfparser/string1.mf:5:9 diff --git a/unittests/main.cpp b/unittests/main.cpp index fb909fc..9060de5 100644 --- a/unittests/main.cpp +++ b/unittests/main.cpp @@ -11,6 +11,9 @@ #include void testCore(){ + extern void testRplString(); + testRplString(); + extern void testRplCharPtrMap(); testRplCharPtrMap(); @@ -19,6 +22,7 @@ void testCore(){ extern void testRplByteStorage(); testRplByteStorage(); + extern void testRplQString(); testRplQString(); @@ -30,13 +34,11 @@ void testCore(){ } void testExpr(){ - extern void testRplSource(); - testRplSource(); extern void testRplBenchmark(); //testRplBenchmark(); extern void testRplVM(); - //testRplVM(); + testRplVM(); extern void testRplSource(); testRplSource(); @@ -50,6 +52,9 @@ void testExpr(){ extern void testRplASTree(); testRplASTree(); + extern void testRplVM(); + testRplVM(); + } void testStandard(){ diff --git a/unittests/rplmfparser_test.cpp b/unittests/rplmfparser_test.cpp index 6ecc5ed..896566e 100644 --- a/unittests/rplmfparser_test.cpp +++ b/unittests/rplmfparser_test.cpp @@ -18,13 +18,15 @@ private: RplSource m_source; RplASTree m_tree; RplStringReader m_reader; - const char* m_currentSource; + RplFileReader m_fileReader; + QByteArray m_currentSource; public: TestRplMFParser() : RplTest("RplMFParser"), m_source(), m_tree(), - m_reader(m_source) + m_reader(m_source), + m_fileReader(m_source) { m_source.addReader(&m_reader); } @@ -39,6 +41,16 @@ protected: m_source.addReader(&m_reader); m_source.addSourceUnit(m_reader.currentSourceUnit()); } + void setFileSource(const char* filename){ + RplASItem::reset(); + m_currentSource = RplString::read(filename); + m_tree.clear(); + m_source.clear(); + m_fileReader.clear(); + m_fileReader.addSource(filename); + m_source.addReader(&m_fileReader); + m_source.addSourceUnit(m_fileReader.currentSourceUnit()); + } private: void checkAST(const char* fileExpected, int lineNo){ @@ -54,6 +66,13 @@ private: } public: + void fileClassTest(){ + setFileSource("test/rplmfparser/string1.mf"); + RplMFParser parser(m_source, m_tree); + parser.parse(); + checkAST("string1.txt", __LINE__); + } + void baseTest(){ setSource("2+3*4"); RplMFParser parser(m_source, m_tree); @@ -175,7 +194,9 @@ public: parser.parse(); checkAST("meth4.txt", __LINE__); } + virtual void doIt(void) { + fileClassTest(); varDefTest(); repeatTest(); baseTest(); diff --git a/unittests/rplsource_test.cpp b/unittests/rplsource_test.cpp index ecc05fc..49eeeae 100644 --- a/unittests/rplsource_test.cpp +++ b/unittests/rplsource_test.cpp @@ -19,9 +19,9 @@ public: TestRplSource() : RplTest("TestRplSource") {} private: - QString m_content1_1; - QString m_content1_2; - QString m_content2; + QByteArray m_content1_1; + QByteArray m_content1_2; + QByteArray m_content2; RplSource m_source; protected: @@ -33,15 +33,15 @@ protected: void testRplStringSourceUnit(){ RplStringReader reader(m_source); - QString content("a=1;\nveeeeeeeeery looooooooooooooong\n"); + QByteArray content("a=1;\nveeeeeeeeery looooooooooooooong\n"); RplStringSourceUnit unit("test", content, &reader); unit.setLineNo(144); checkE(144, unit.lineNo()); checkE("test", unit.name()); } void checkOne(int maxSize, RplReader& reader){ - QString total; - QString buffer; + QByteArray total; + QByteArray buffer; int lineNo = 0; bool hasMore; checkF(reader.openSourceUnit("unknownSource")); @@ -86,7 +86,7 @@ protected: reader.replaceSource("source2", "content2"); unit = reader.openSourceUnit("source2"); - QString buffer; + QByteArray buffer; bool hasMore; checkT(reader.nextLine(50, buffer, hasMore)); checkE("content2", buffer); diff --git a/unittests/rplstring_test.cpp b/unittests/rplstring_test.cpp index 975e529..8983dc0 100644 --- a/unittests/rplstring_test.cpp +++ b/unittests/rplstring_test.cpp @@ -121,8 +121,60 @@ public: content = "0,3;7.8;8.9"; checkCsv(content, ';'); } + void testLengthOfUInt64(){ + quint64 value = -3; + checkE(1, RplString::lengthOfUInt64("0", 10, &value)); + checkE(0LL, value); + checkE(3, RplString::lengthOfUInt64("432", 10, &value)); + checkE(432LL, value); + checkE(3, RplString::lengthOfUInt64("432 x", 10, &value)); + checkE(432LL, value); + checkE(3, RplString::lengthOfUInt64("432fabc x", 10, &value)); + checkE(432LL, value); + checkE(16, RplString::lengthOfUInt64("1234567890123567", 10, &value)); + checkE(1234567890123567LL, value); + checkE(10, RplString::lengthOfUInt64("1234abcdef", 16, &value)); + checkE(0x1234abcdefLL, value); + checkE(3, RplString::lengthOfUInt64("432", 8, &value)); + checkE(0432LL, value); + checkE(6, RplString::lengthOfUInt64("765432 ", 8, &value)); + checkE(0765432LL, value); + + checkE(0, RplString::lengthOfUInt64(" ", 8, &value)); + checkE(0, RplString::lengthOfUInt64("", 8, &value)); + } + void testLengthOfReal(){ + qreal value; + checkE(1, RplString::lengthOfReal("0", &value)); + checkE(0.0, value); + checkE(1, RplString::lengthOfReal("0%", &value)); + checkE(0.0, value); + checkE(4, RplString::lengthOfReal("0.25", &value)); + checkE(0.25, value); + checkE(3, RplString::lengthOfReal(".25", &value)); + checkE(0.25, value); + checkE(17, RplString::lengthOfReal("12345678901234567", &value)); + checkE(12345678901234567.0, value); + checkE(2, RplString::lengthOfReal(".5", &value)); + checkE(0.5, value); + checkE(5, RplString::lengthOfReal("2.5e2x", &value)); + checkE(250.0, value); + checkE(6, RplString::lengthOfReal("2.5e+2", &value)); + checkE(250.0, value); + checkE(7, RplString::lengthOfReal("2.5E-33", &value)); + checkE(2.5e-33, value); + + checkE(3, RplString::lengthOfReal("2.5E", &value)); + checkE(2.5, value); + checkE(3, RplString::lengthOfReal("2.5E+", &value)); + checkE(2.5, value); + checkE(3, RplString::lengthOfReal("2.5E-a", &value)); + checkE(2.5, value); + } virtual void doIt() { + testLengthOfReal(); + testLengthOfUInt64(); testCountChar(); testCount(); testCutString(); diff --git a/unittests/rplvm_test.cpp b/unittests/rplvm_test.cpp index 8425c95..8294491 100644 --- a/unittests/rplvm_test.cpp +++ b/unittests/rplvm_test.cpp @@ -57,7 +57,7 @@ private: } public: void baseTest(){ - setSource("Int a=2+3*4;"); + setSource("Int a=2+3*4;\nfunc Void main():\na;\nendf"); checkAST("baseTest.txt", __LINE__); } virtual void doIt(void) {