]> gitweb.hamatoma.de Git - reqt/commitdiff
dayly work
authorhama <hama@siduction.net>
Sun, 24 Aug 2014 21:38:17 +0000 (23:38 +0200)
committerhama <hama@siduction.net>
Sun, 24 Aug 2014 21:38:17 +0000 (23:38 +0200)
23 files changed:
rplcore/rplstring.cpp
rplcore/rplstring.hpp
rplexpr/rplasclasses.cpp
rplexpr/rplasclasses.hpp
rplexpr/rplastree.cpp
rplexpr/rplastree.hpp
rplexpr/rpllexer.cpp
rplexpr/rpllexer.hpp
rplexpr/rplmfparser.cpp
rplexpr/rplmfparser.hpp
rplexpr/rplparser.cpp
rplexpr/rplparser.hpp
rplexpr/rplsource.cpp
rplexpr/rplsource.hpp
rplexpr/rplvm.cpp
rplexpr/rplvm.hpp
test/rplmfparser/string1.mf [new file with mode: 0644]
test/rplmfparser/string1.txt [new file with mode: 0644]
unittests/main.cpp
unittests/rplmfparser_test.cpp
unittests/rplsource_test.cpp
unittests/rplstring_test.cpp
unittests/rplvm_test.cpp

index 635658c38da17a62dc31e2333d5565abf5713125..a8bd0396c4a5594d79386407ee2ffd8f6623c196 100644 (file)
@@ -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;
+}
 
index ab12169de3b1ac86a23eccbd7c172b83ab36b635..ee8924cf3b336a0cb9fb372c8a03094cbeae76df 100644 (file)
@@ -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
index aab59630e5ed6fc8279cfa6e1bd21f70de8a83fe..11f21d615c9374ad7a3a90a65f53e253720863b8 100644 (file)
@@ -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<br>
  *              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<br>
  *              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 ? "<none>" : m_parent->name().toUtf8().constData());
-    QList<QString> sorted;
+            m_parent == NULL ? "<none>" : m_parent->name().constData());
+    QList<QByteArray> 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<QString>());
-        QList<QString>::iterator it2;
+        qSort(sorted.begin(), sorted.end(), qLess<QByteArray>());
+        QList<QByteArray>::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<QString>());
-        QList<QString>::iterator it4;
+        qSort(sorted.begin(), sorted.end(), qLess<QByteArray>());
+        QList<QByteArray>::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<QString>::iterator it6;
+        QList<QByteArray>::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<RplASUserClass*>(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 <code>object</code>
  */
-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 <code>object</code>
  */
-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 <code>object</code>
  */
-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<QString*>(object);
+        QByteArray* string = static_cast<QByteArray*>(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 <code>object</code>
  */
-QString RplASString::toString(void* object, int maxLength) const
+QByteArray RplASString::toString(void* object, int maxLength) const
 {
-    QString rc;
-    QString* string = reinterpret_cast<QString*> (object);
+    QByteArray rc;
+    QByteArray* string = reinterpret_cast<QByteArray*> (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 <code>object</code>
  */
-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<RplASListOfVariants*>(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 <code>object</code>
  */
-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<RplASMapOfVariants*>(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<RplASExprStatement*>(object);
 
-    QString rc;
-    rc.sprintf("<formula %d>", expr->id());
-    return rc;
+    char buffer[64];
+    qsnprintf(buffer, sizeof buffer, "<formula %d>", 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;
 }
index 72c20386a6aa41b874ddd102ea4498c97df39300..fbb5df2e75bbccc303a51c8ca54121cddaa09b04 100644 (file)
 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<QString, RplASVarDefinition*> VariableMap;
-    typedef QMap<QString, RplASClass*> ClassMap;
-    typedef QMap<QString, RplASMethod*> MethodMap;
+    typedef QMap<QByteArray, RplASVarDefinition*> VariableMap;
+    typedef QMap<QByteArray, RplASClass*> ClassMap;
+    typedef QMap<QByteArray, RplASMethod*> MethodMap;
     typedef QList<RplASVarDefinition*> 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:
index df05d16af4f81bc5c69524011fc0181a708dc39a..3db6a3ef89cd9234c7ad2dcc760aca9cd0dc563f 100644 (file)
@@ -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<QString> sorted;
+    QList<QByteArray> 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<QString>());
-    QList<QString>::iterator it2;
+    qSort(sorted.begin(), sorted.end(), qLess<QByteArray>());
+    QList<QByteArray>::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 = "<undef>";
+        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<const QString*>(asObject(&clazz));
+    const QByteArray* rc = static_cast<const QByteArray*>(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<RplASNamedValue*>(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<RplASNamedValue*>(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
-                ? "<none>" : m_superClass->name().toUtf8().constData());
+                ? "<none>" : m_superClass->name().constData());
     m_symbols->dump(writer, indent);
 }
 
@@ -2173,7 +2197,7 @@ bool RplASTree::startModule(RplSourceUnitName name)
  * @return      NULL: not found<br>
  *              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<QString> sorted;
+        QList<QByteArray> 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<QString>());
-        QList<QString>::iterator it2;
+        qSort(sorted.begin(), sorted.end(), qLess<QByteArray>());
+        QList<QByteArray>::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.
+ *
+ * <code>m_child</code>: left operand<br>
+ * <code>m_child2</code>: 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<RplASCalculable*>(m_child);
+        RplASCalculable* op2 = dynamic_cast<RplASCalculable*>(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<RplASCalculable*>(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 ? "<NoneType>" : m_resultType->name().toUtf8().constData(),
-            m_name.toUtf8().constData());
+            m_resultType == NULL ? "<NoneType>" : 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);
index 24d54eacf0dc394a744ce632dd59d34e3ec474ba..96492a58d45819263a7dc17a81e31e4032b90b97 100644 (file)
@@ -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<RplASVariant*> RplASListOfVariants;
-typedef QMap<QString, RplASVariant*> RplASMapOfVariants;
+typedef QMap<QByteArray, RplASVariant*> 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<QString, RplASMethod*> MethodMap;
+    typedef QMap<QByteArray, RplASMethod*> 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 <code>object</code>
      */
-    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<QString, RplSymbolSpace*> SymbolSpaceMap;
+    typedef QMap<QByteArray, RplSymbolSpace*> SymbolSpaceMap;
     typedef QList<RplSymbolSpace*> 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();
 
index f573ab51ac1c54a84f7bf81db031a36ae004f274..1366cf81bc5bdea05424275942d4856e2c7dda7d 100644 (file)
@@ -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<QString>());
+    qSort(vector.begin(), vector.end(), qLess<QByteArray>());
 }
 
 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)
index 232f6f9f0135e972285c1f98e588551a19268119..cf27d9be86266b09f3d12cea60d50224201bb8d4 100644 (file)
@@ -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<QString> StringList;
+    typedef QList<QByteArray> 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;
index b3aa969fb3b8cee1b08e5296d6bdb78bc69ff553..5a2c0947dc4d7cbcf3ecc61eab0d201c55bded43 100644 (file)
@@ -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 <code>RplASNamedValue</code> or a
  *                  <code>RplASNamedValue</code> 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);
index 36b4532bd0661964eead6a8181b0c4709fc740dd..900cc604e1edd9ce4413d67267aca83e19f787c9 100644 (file)
@@ -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();
index 81b101175c26ce39b61750ec5019f064c12f8939..477d1dc5f83b880f16301a1ff8cf291ed0dfb2bd 100644 (file)
@@ -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());
index 8e22aa5e6cba3eb480e954c24283569b98f43192..69a8c7d27b3ec8536f370b74c0a4454eba0beb23 100644 (file)
@@ -34,7 +34,7 @@ public:
     };
 
 public:
-    typedef QList<QString> MessageList;
+    typedef QList<QByteArray> MessageList;
 public:
     RplParser(RplLexer& lexer, RplASTree& ast);
 public:
index 576744f7504f3bc3169466c2086dd363edc058bb..b10feacb23088ce7cc0927e9f44587ce2865cfad 100644 (file)
@@ -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<br>
  *                  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<br>
  *                  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<RplStringSourceUnit*>(m_units[name]);
@@ -809,18 +806,24 @@ RplSourceUnit* RplFileReader::openSourceUnit(RplSourceUnitName unit) {
  * @return          false: no more input available<br>
  *                  true: success
  */
-bool RplFileReader::nextLine(int maxSize, RplSourceUnitContent& buffer,
-                                   bool& hasMore) {
+bool RplFileReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore) {
     RplFileSourceUnit* unit  = static_cast<RplFileSourceUnit*>
             (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<br>
  *                  true: success
  */
-bool RplFileReader::fillBuffer(int maxSize, RplSourceUnitContent& buffer,
-                                     bool& hasMore) {
+bool RplFileReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) {
     RplFileSourceUnit* unit  = static_cast<RplFileSourceUnit*>(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;
 }
 
index 830b9550a94b49547afe6cde4565ca0cfb57ebf7..40f80b9bbfe01fb764c29022f6acdbd4c7f167cb 100644 (file)
@@ -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<br>
      *                  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<br>
      *                  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);
 };
index 873d3e4f285dc62bf2109c5d14233370cc57aedd..828f04b421f9aee0ed2aaec636400faf73cd68a2 100644 (file)
@@ -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;
index c86ed4836e2cb146f1566fa0b0d12584916cd153..8109b4f14eac73b8cc5c98c1af23b3adaa236a66 100644 (file)
@@ -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 (file)
index 0000000..7beb37b
--- /dev/null
@@ -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 (file)
index 0000000..5dfbe02
--- /dev/null
@@ -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
index fb909fc6e8d08d6cdfc944e11c39edd239ba466f..9060de535236d37db0b14aff5cbd4d0984595717 100644 (file)
@@ -11,6 +11,9 @@
 #include <QCoreApplication>
 
 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(){
index 6ecc5eda4ac34c2c1ae6f60f56285b4fae8acb92..896566e805ba64ad78cab793d97035476d519a4d 100644 (file)
@@ -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();
index ecc05fc96c343fd64a6d40df78483a2ca1cc75c2..49eeeae3bad5cdbd5ad0021bb4fb886e43b04010 100644 (file)
@@ -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);
index 975e529a038b99ec53c201654a927c0e2a38b5b7..8983dc0b4841c205d308f0bcfdc34ad3dadf0a1c 100644 (file)
@@ -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();
index 8425c958a8fce9046508b07765382961bafd20c7..8294491d9edf552e7e463dfbf79b39d41b74ca83 100644 (file)
@@ -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) {