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;
+}
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
* @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),
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);
}
* @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))
* @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))
* @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))
{
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());
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);
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 {
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);
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))
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)){
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 {
*
* @return the name
*/
-const QString& RplSymbolSpace::name() const
+const QByteArray& RplSymbolSpace::name() const
{
return m_name;
}
* @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";
}
{
}
-RplASFloat::RplASFloat(const QString& name, RplASTree& tree) :
+RplASFloat::RplASFloat(const QByteArray& name, RplASTree& tree) :
RplASClass(name, tree)
{
m_superClass = RplASFloat::m_instance;
* @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"
* @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;
}
*/
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;
}
*/
void RplASString::destroyValueInstance(void* object) const
{
- delete (QString*) object;
+ delete (QByteArray*) object;
}
/**
*
* 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
*/
{
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();
* @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;
* @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);
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;
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;
}
* @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);
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;
/**
* @brief Constructor.
*/
-RplVariable::RplVariable(const QString& name) :
+RplVariable::RplVariable(const QByteArray& name) :
m_name(name),
m_namespace(NULL),
m_value(),
*/
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.
*
* @return the name
*/
-const QString& RplVariable::name() const
+const QByteArray& RplVariable::name() const
{
return m_name;
}
* @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"
* @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"
* @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),
* @param maxLength maximum length of the string
* @return
*/
-QString RplASUserClass::toString(void*, int) const
+QByteArray RplASUserClass::toString(void*, int) const
{
return m_name;
}
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;
};
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);
static RplSymbolSpace* createGlobal(RplASTree& tree);
private:
SymbolSpaceType m_type;
- QString m_name;
+ QByteArray m_name;
VariableMap m_variables;
ClassMap m_classes;
MethodMap m_methods;
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;
};
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;
};
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;
};
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;
};
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;
};
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;
};
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;
};
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:
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
};
*/
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)
*/
void RplASVariant::copyValue(const RplASVariant& source)
{
+ destroyValue();
+ m_variantType = source.m_variantType;
+ m_class = source.m_class;
+
switch(source.m_variantType)
{
case VT_BOOL:
break;
default:
m_value.m_object = m_class->newValueInstance(source.m_value.m_object);
+ break;
}
+ m_flags = source.m_flags;
}
/**
{
const char* rc = "?";
switch(m_variantType){
+ case VT_UNDEF:
+ rc = "<undef>";
+ break;
case VT_FLOAT:
rc = "Float";
break;
* @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;
}
*
* @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);
}
/**
* @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);
{
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));
}
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());
}
/**
* @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),
*
* @return the name
*/
-const QString& RplASNamedValue::name() const
+const QByteArray& RplASNamedValue::name() const
{
return m_name;
}
{
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));
}
/**
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)
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(),
*
* @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;
}
/**
* @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),
*
* @return the class name
*/
-const QString& RplASClass::name() const
+const QByteArray& RplASClass::name() const
{
return m_name;
}
*/
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);
}
* @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;
* @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;
*
* @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!
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);
* 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),
{
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(),
/** @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.
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();
}
}
}
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();
case BOP_ASSIGN:
break;
case BOP_PLUS_ASSIGN:
- switch(value.variantType()){
+ //switch(value.variantType()){
- }
+ //}
break;
case BOP_MINUS_ASSIGN:
case BOP_TIMES_ASSIGN:
* @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),
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));
* @return the name
*/
-const QString& RplASMethod::name() const
+const QByteArray& RplASMethod::name() const
{
return m_name;
}
*
* @param name name of the field
*/
-RplASField::RplASField(const QString& name) :
+RplASField::RplASField(const QByteArray& name) :
RplASNode1(AST_FIELD),
m_name(name)
{
{
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);
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;
};
typedef QList<RplASVariant*> RplASListOfVariants;
-typedef QMap<QString, RplASVariant*> RplASMapOfVariants;
+typedef QMap<QByteArray, RplASVariant*> RplASMapOfVariants;
class RplASListConstant : public RplASNode1, public RplASCalculable
{
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);
int variableNo() const;
void setVariableNo(int variableNo);
protected:
- QString m_name;
+ QByteArray m_name;
int m_attributes;
RplASClass* m_dataType;
RplSymbolSpace* m_symbolSpace;
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);
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);
RplASArgument*arg1() const;
private:
- QString m_name;
+ QByteArray m_name;
RplASMethod* m_method;
};
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;
};
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):
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:
/**
* @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;
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();
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();
* @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;
}
*
* @return the value of the token as floating point value
*/
-const QString& RplToken::rawString() const
+const QByteArray& RplToken::rawString() const
{
return m_printableString;
}
*/
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;
}
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);
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:
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)
}
}
}
- qSort(vector.begin(), vector.end(), qLess<QString>());
+ qSort(vector.begin(), vector.end(), qLess<QByteArray>());
}
static void charClassToCharInfo(const char* charClass, int flag,
// 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;
}
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)
else if (compareRc > 0)
lbound = half + 1;
else {
- id = current[currentLength + 1].unicode();
+ id = current[currentLength + 1] + current[currentLength + 2] * 256;
break;
}
}
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)){
// 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
}
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
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
&& 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,
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;
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;
*/
RplToken*RplLexer::scanString()
{
- int delim = m_input[0].unicode();
+ int delim = m_input[0];
int inputLength = m_input.size();
int cc;
int length = 1;
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
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++;
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;
{
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);
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));
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)
//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 {
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;
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)
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;
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;
class RplLexer
{
public:
- typedef QList<QString> StringList;
+ typedef QList<QByteArray> StringList;
enum NumericType {
NUMTYPE_UNDEF,
NUMTYPE_DECIMAL = 1 << 0,
// 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;
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;
bool again = true;
RplToken* token;
RplToken* token2;
- QString key;
+ QByteArray key;
while(again){
token = m_lexer.nextNonSpaceToken();
if (token->isOperator(O_RBRACE))
* @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;
}
case TOKEN_ID:
{
- QString name = token->toString();
+ QByteArray name = token->toString();
if (name == "a")
name = "a";
token = m_lexer.nextNonSpaceToken();
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();
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);
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();
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());
};
public:
- typedef QList<QString> MessageList;
+ typedef QList<QByteArray> MessageList;
public:
RplParser(RplLexer& lexer, RplASTree& ast);
public:
*
* @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"
* @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);
* @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();
}
* @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);
* @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]);
* @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;
}
* @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;
}
// type of buffer names and filenames. Codec: UTF-8
typedef const char* RplSourceUnitName;
-typedef QString RplSourceUnitContent;
+typedef const char* RplSourceUnitContent;
class RplSource;
class RplReader;
* @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.
*
* @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();
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{
// 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;
int m_currentPosition;
FILE* m_fp;
QTextStream m_textStream;
- RplSourceUnitContent m_line;
+ QByteArray m_line;
};
class RplFileReader : public RplReader{
// 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);
};
*/
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())
{
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.
*
}
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;
}
*
* @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;
RplLogger* logger() const;
RplASVariant& reserveValue();
RplASVariant& topOfValues();
+ RplASVariant& top2OfValues();
RplASVariant& popValue();
void valueToTop(RplSymbolSpace* symbolSpace, int variableNo);
RplASVariant& lValue(RplASItem* item);
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,
--- /dev/null
+Str x1 = "x1 123456789 123456789 123456789 123456789 123456789";
+Str x2 = "x2 123456789 123456789 123456789 123456789 123456789";
+Str x3 = "x3 123456789 123456789 123456789 123456789 123456789";
--- /dev/null
+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
#include <QCoreApplication>
void testCore(){
+ extern void testRplString();
+ testRplString();
+
extern void testRplCharPtrMap();
testRplCharPtrMap();
extern void testRplByteStorage();
testRplByteStorage();
+
extern void testRplQString();
testRplQString();
}
void testExpr(){
- extern void testRplSource();
- testRplSource();
extern void testRplBenchmark();
//testRplBenchmark();
extern void testRplVM();
- //testRplVM();
+ testRplVM();
extern void testRplSource();
testRplSource();
extern void testRplASTree();
testRplASTree();
+ extern void testRplVM();
+ testRplVM();
+
}
void testStandard(){
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);
}
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){
}
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);
parser.parse();
checkAST("meth4.txt", __LINE__);
}
+
virtual void doIt(void) {
+ fileClassTest();
varDefTest();
repeatTest();
baseTest();
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:
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"));
reader.replaceSource("source2", "content2");
unit = reader.openSourceUnit("source2");
- QString buffer;
+ QByteArray buffer;
bool hasMore;
checkT(reader.nextLine(50, buffer, hasMore));
checkE("content2", buffer);
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();
}
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) {