From 00b55cc8d5f7c94989baf15d7bfc6791fc7baf7b Mon Sep 17 00:00:00 2001 From: hama Date: Fri, 5 Sep 2014 00:49:23 +0200 Subject: [PATCH] dayly work --- rplexpr/rplastree.cpp | 205 +++++++++++++++++++++-------------- rplexpr/rplastree.hpp | 11 +- test/mfparser/repeatTest.txt | 2 +- unittests/main.cpp | 3 + 4 files changed, 134 insertions(+), 87 deletions(-) diff --git a/rplexpr/rplastree.cpp b/rplexpr/rplastree.cpp index b1d1cda..33fb565 100644 --- a/rplexpr/rplastree.cpp +++ b/rplexpr/rplastree.cpp @@ -40,8 +40,8 @@ enum { LOC_BINOP_CALC_12, LOC_VARDEF_CHECK_1, LOC_VARDEF_CHECK_2, // 11020 + LOC_FREE_1, LOC_CONV_CHECK_1, - LOC_CONV_CHECK_2, LOC_CONV_TRY_1, LOC_ITEM_FORCE_ERROR_1, LOC_UNARY_CHECK_4, // 11025 @@ -735,12 +735,13 @@ bool RplASItem::error(int location, RplParser& parser, const char* format, ...) * will be issued. * * @param parser for error processing + * @param info additional info * @return false (for chaining) */ -bool RplASItem::ensureError(RplParser& parser) +bool RplASItem::ensureError(RplParser& parser, const char* info) { if (parser.errors() == 0) - error(LOC_ITEM_FORCE_ERROR_1, parser, "lost error (internal error)"); + error(LOC_ITEM_FORCE_ERROR_1, parser, "lost error (internal error): %s"); return false; } @@ -1005,8 +1006,6 @@ RplASMapOfVariants* RplASMapConstant::map() /** @class RplASNamedValue rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements a named values, a constant or a variable - * - * m_child: NULL or the index expression (map/list) */ /** @@ -1017,14 +1016,15 @@ RplASMapOfVariants* RplASMapConstant::map() * @param space the current symbol space * @param attributes the attributes of the variable */ -RplASNamedValue::RplASNamedValue(RplASClass* dataType,RplSymbolSpace* space, +RplASNamedValue::RplASNamedValue(RplASClass* clazz,RplSymbolSpace* space, const QByteArray& name, int attributes) : - RplASNode1(AST_NAMED_VALUE), + RplASItem(AST_NAMED_VALUE), m_name(name), m_attributes(attributes), m_symbolSpace(space), m_variableNo(-1) { + m_class = clazz; } /** @@ -1055,6 +1055,10 @@ void RplASNamedValue::setSymbolSpace(RplSymbolSpace* space, int variableNo) void RplASNamedValue::calc(RplVMThread& thread) { thread.valueToTop(m_symbolSpace, m_variableNo); + if (thread.tracing()) + thread.vm()->traceWriter()->format("nVal %s=%.80s", + m_name.constData(), + thread.topOfValues().toString().constData()); } /** @@ -1143,6 +1147,7 @@ void RplASConversion::calc(RplVMThread& thread) RplASCalculable* expr = dynamic_cast(m_child); expr->calc(thread); RplASVariant& value = thread.topOfValues(); + switch(m_conversion){ case C_INT_TO_FLOAT: value.setFloat((qreal) value.asInt()); @@ -1159,6 +1164,10 @@ void RplASConversion::calc(RplVMThread& thread) default: break; } + if (thread.tracing()) + thread.vm()->traceWriter()->format("(%s): %s", + m_class->name().constData(), + value.toString().constData()); } /** @@ -1200,23 +1209,20 @@ RplASConversion::Conversion RplASConversion::findConversion(RplASClass* from, */ bool RplASConversion::check(RplParser& parser) { - bool rc = false; + bool rc = m_child != NULL && m_child->check(parser); RplASCalculable* expr = dynamic_cast(m_child); - if (expr == NULL){ - parser.error(LOC_CONV_CHECK_1, "missing expr"); - } else { + if (! rc || expr == NULL) + ensureError(parser, "RplASConversion::check"); + else { RplASClass* from = expr->clazz(); - rc = m_child->check(parser); - if (rc){ - m_conversion = findConversion(from, m_class); - if (m_conversion != C_UNDEF) - rc = true; - else - parser.error(LOC_CONV_CHECK_2, - "invalid data type conversion: %s -> %s", - from->name().constData(), - m_class->name().constData()); - } + m_conversion = findConversion(from, m_class); + if (m_conversion != C_UNDEF) + rc = true; + else + parser.error(LOC_CONV_CHECK_1, + "invalid data type conversion: %s -> %s", + from->name().constData(), + m_class->name().constData()); } return rc; } @@ -1245,20 +1251,24 @@ void RplASConversion::dump(RplWriter& writer, int indent) * @param expected the expected data type * @param expr the expression to convert * @param parser for error processing + * @param isCorrect OUT: false: error has been detected
+ * No change if no error * * @return NULL: no conversion necessary
* otherwise: a converter to the given type */ RplASConversion* RplASConversion::tryConversion(RplASClass* expected, - RplASItem* expr, RplParser& parser) + RplASItem* expr, RplParser& parser, bool& isCorrect) { RplASConversion* rc = NULL; - if (expr->check(parser)){ + if (! expr->check(parser)) + isCorrect = false; + else { RplASCalculable* expr2 = dynamic_cast(expr); if (expr2 != NULL){ Conversion type = findConversion(expr2->clazz(), expected); if (type == C_UNDEF){ - parser.error(LOC_CONV_TRY_1, + isCorrect = parser.error(LOC_CONV_TRY_1, "invalid data type conversion: %s -> %s", expr2->clazz()->name().constData(), expected->name().constData()); @@ -1284,6 +1294,28 @@ RplASIndexedValue::RplASIndexedValue() : { } +/** + * @brief Calculates an indexed expression. + * + * Possible: list index or map index + * + * @param thread execution value + */ +void RplASIndexedValue::calc(RplVMThread& thread) +{ + RplASCalculable* expr = dynamic_cast(m_child2); + expr->calc(thread); + RplASVariant& ixValue = thread.popValue(); + int ix = ixValue.asInt(); + RplASCalculable* list = dynamic_cast(m_child); + list->calc(thread); + RplASVariant& listValue = thread.popValue(); + //@ToDo: access to the lists element: assignment or to stack + if (thread.tracing()) + thread.vm()->traceWriter()->format("[%d]: %.80s", + ix, thread.topOfValues().toString().constData()); +} + /** * @brief Checks the correctness of the instance. * @@ -1293,19 +1325,22 @@ RplASIndexedValue::RplASIndexedValue() : */ bool RplASIndexedValue::check(RplParser& parser) { - bool rc = false; RplASCalculable* list = dynamic_cast(m_child); - if (list == NULL) - throw RplASException(m_position, "indexed value: empty list"); - m_child->check(parser); - RplASConversion* converter = RplASConversion::tryConversion( - RplASInteger::m_instance, m_child, parser); - if (converter == NULL){ - RplASClass* clazz = list->clazz(); - rc = clazz != NULL && clazz == RplASInteger::m_instance; - } else { - m_child = converter; - rc = true; + bool rc = m_child != NULL && m_child->check(parser); + if (! rc || list == NULL) + ensureError(parser, "RplASIndexedValue::check"); + else { + // index value: + // tryConversion() calls m_child2->check()! + RplASConversion* converter = RplASConversion::tryConversion( + RplASInteger::m_instance, m_child2, parser, rc); + if (rc && converter != NULL) + m_child = converter; + if (rc){ + //@ToDo: dynamic subclass of list + m_class = RplASString::m_instance; + rc = m_class != NULL && m_class == RplASInteger::m_instance; + } } return rc; } @@ -1430,28 +1465,25 @@ void RplASVarDefinition::setEndOfScope(int endOfScope) */ bool RplASVarDefinition::check(RplParser& parser) { - bool rc = false; - if (m_child3 != NULL){ - RplASNamedValue* var = dynamic_cast(m_child2); - if (var == NULL) - error(LOC_VARDEF_CHECK_1, parser, "Not a named value: id: %d", - m_child2 == NULL ? 0 : m_child2->id()); - else{ - if (m_child3 == NULL) - // no initialization: - rc = true; - else { - rc = m_child3->check(parser); - if (rc){ - RplASCalculable* expr = dynamic_cast(m_child3); - if (! typeCheck(var->clazz(), expr->clazz())) - rc = error(LOC_VARDEF_CHECK_2, parser, - "data types are not compatible: %s/%s", - var->clazz()->name().constData(), - expr->clazz() == NULL ? "?" - : expr->clazz()->name().constData()); - } - } + RplASNamedValue* var = dynamic_cast(m_child2); + + bool rc = var != NULL && (m_child3 == NULL || m_child3->check(parser)); + if (! rc) + ensureError(parser, "RplASVarDefinition::check"); + else { + if (m_child3 != NULL){ + // with initialization: + RplASCalculable* expr = dynamic_cast(m_child3); + if (expr == NULL) + rc = error(LOC_VARDEF_CHECK_1, parser, + "Not a calculable expression: %s", + m_child3->nameOfItemType()); + else if (! typeCheck(var->clazz(), expr->clazz())) + rc = error(LOC_VARDEF_CHECK_2, parser, + "data types are not compatible: %s/%s", + var->clazz()->name().constData(), + expr->clazz() == NULL ? "?" + : expr->clazz()->name().constData()); } } return rc; @@ -1462,18 +1494,21 @@ bool RplASVarDefinition::check(RplParser& parser) */ void RplASVarDefinition::execute(RplVMThread& thread) { - RplASNamedValue* var = dynamic_cast(m_child2); - RplASCalculable* expr = dynamic_cast(m_child3); - expr->calc(thread); - RplASVariant& value = thread.popValue(); - RplASVariant& destination = thread.valueOfVariable( - var->m_symbolSpace, var->m_variableNo); - if (thread.tracing()) - thread.vm()->traceWriter()->format("%s = %.80s [%.80s]", - var->m_name.constData(), - value.toString().constData(), - destination.toString().constData()); - destination.copyValue(value); + if (m_child3 != NULL){ + // has an initialization: + RplASNamedValue* var = dynamic_cast(m_child2); + RplASCalculable* expr = dynamic_cast(m_child3); + expr->calc(thread); + RplASVariant& value = thread.popValue(); + RplASVariant& destination = thread.valueOfVariable( + var->m_symbolSpace, var->m_variableNo); + if (thread.tracing()) + thread.vm()->traceWriter()->format("%s = %.80s [%.80s]", + var->m_name.constData(), + value.toString().constData(), + destination.toString().constData()); + destination.copyValue(value); + } } /** @class RplASExprStatement rplastree.hpp "rplexpr/rplastree.hpp" @@ -1504,9 +1539,11 @@ RplASExprStatement::RplASExprStatement() : bool RplASExprStatement::check(RplParser& parser) { bool rc = m_child2->check(parser); - RplASCalculable* expr = dynamic_cast (m_child2); - if (expr == NULL) - rc = false; + if (rc){ + RplASCalculable* expr = dynamic_cast (m_child2); + if (expr == NULL) + rc = ensureError(parser, "RplASExprStatement::check"); + } return rc; } /** @@ -1579,8 +1616,6 @@ RplASItem* RplASNode1::child() const */ void RplASNode1::setChild(RplASItem* child) { - if (child->id() == 2) - m_child = child; m_child = child; } @@ -1873,6 +1908,10 @@ void RplASUnaryOp::calc(RplVMThread& thread) error(thread.logger(), LOC_UNOP_CALC_1, "unknown operator: %d", m_operator); break; } + if (thread.tracing()) + thread.vm()->traceWriter()->format("unary %s: %s", + nameOfOp(m_operator), + value.toString().constData()); } /** @@ -1889,7 +1928,7 @@ bool RplASUnaryOp::check(RplParser& parser) RplASCalculable* expr = dynamic_cast(m_child); RplASClass* clazz = expr == NULL ? NULL : expr->clazz(); if (clazz == NULL){ - rc = ensureError(parser); + rc = ensureError(parser, "RplASUnaryOp::check"); } else { switch(m_operator){ case UOP_PLUS: @@ -2036,10 +2075,11 @@ RplASCondition::RplASCondition() : */ void RplASCondition::calc(RplVMThread& thread) { - RplASCalculable* node = dynamic_cast(m_child); - if (node == NULL) - throw RplASException(m_position, "child of condition is not calculable"); - node->calc(thread); + RplASCalculable* expr = dynamic_cast(m_child); + expr->calc(thread); + if (thread.tracing()) + thread.vm()->traceWriter()->format("condition: %s", + thread.topOfValues().toString().constData()); } /** @@ -2051,6 +2091,9 @@ void RplASCondition::calc(RplVMThread& thread) */ bool RplASCondition::check(RplParser& parser) { + RplASCalculable* expr = dynamic_cast(m_child); + if (expr == NULL) + throw RplASException(m_position, "child of condition is not calculable"); return false; } /** diff --git a/rplexpr/rplastree.hpp b/rplexpr/rplastree.hpp index a12554e..942b253 100644 --- a/rplexpr/rplastree.hpp +++ b/rplexpr/rplastree.hpp @@ -157,7 +157,7 @@ public: bool typeCheck(RplASClass* clazz1, RplASClass* clazz2); bool error(int location, RplParser& parser, const char* format, ...); - bool ensureError(RplParser& parser); + bool ensureError(RplParser& parser, const char* info); protected: unsigned int m_id:16; RplASItemType m_nodeType:8; @@ -312,7 +312,7 @@ private: }; class RplSymbolSpace; -class RplASNamedValue : public RplASNode1, public RplASStorable +class RplASNamedValue : public RplASItem, public RplASStorable { friend class RplASVarDefinition; public: @@ -333,7 +333,7 @@ public: }; public: - RplASNamedValue(RplASClass* dataType, RplSymbolSpace* space, + RplASNamedValue(RplASClass* clazz, RplSymbolSpace* space, const QByteArray& name, int attributes); public: virtual void calc(RplVMThread& thread); @@ -369,16 +369,17 @@ public: virtual void dump(RplWriter& writer,int indent); public: static RplASConversion* tryConversion(RplASClass* expected, RplASItem* expr, - RplParser& parser); + RplParser& parser, bool& isCorrect); static Conversion findConversion(RplASClass* from, RplASClass* to); private: Conversion m_conversion; }; -class RplASIndexedValue : public RplASNode2 { +class RplASIndexedValue : public RplASNode2, public RplASCalculable { public: RplASIndexedValue(); public: + virtual void calc(RplVMThread& thread); virtual bool check(RplParser& parser); public: void dump(RplWriter& writer, int indent); diff --git a/test/mfparser/repeatTest.txt b/test/mfparser/repeatTest.txt index b23a54a..953a0d5 100644 --- a/test/mfparser/repeatTest.txt +++ b/test/mfparser/repeatTest.txt @@ -16,5 +16,5 @@ repeat id: 3 condition: 8 body: 6 succ: 0 :1:7 const id: 9 value: 2 :4:11 const id: 11 value: 3 :4:15 Expr id: 6 expr: 5 succ: 0 - Unary 5 op: ++ (5) expr: 4 + Unary 5 op: ++ (6) expr: 4 namedValue a id: 4 attr: 0x0 :3:1 diff --git a/unittests/main.cpp b/unittests/main.cpp index 9060de5..588f9e8 100644 --- a/unittests/main.cpp +++ b/unittests/main.cpp @@ -34,6 +34,9 @@ void testCore(){ } void testExpr(){ + extern void testRplMFParser(); + testRplMFParser(); + extern void testRplBenchmark(); //testRplBenchmark(); -- 2.39.5