LOC_BINOP_CALC_12,
LOC_VARDEF_CHECK_1,
LOC_VARDEF_CHECK_2, // 11020
- LOC_FREE_1,
+ LOC_ITEM_STATEM_LIST_1,
LOC_CONV_CHECK_1,
LOC_CONV_TRY_1,
LOC_ITEM_FORCE_ERROR_1,
{
m_nextId = 1;
}
+/**
+ * @brief Checks the correctness of a statement list.
+ *
+ * @param list statement list to check
+ * @param parser for error processing
+ * @return <code>true</code>: all statements are correct<br>
+ * <code>false</code>: otherwise
+ */
+bool RplASItem::checkStatementList(RplASItem* list, RplParser& parser)
+{
+ bool rc = true;
+
+ while(list != NULL){
+ if (! list->check(parser))
+ rc = false;
+ RplASNode1* node = dynamic_cast<RplASNode1*>(list);
+ if (node == NULL){
+ list->error(LOC_ITEM_STATEM_LIST_1, parser, "not a node: %s",
+ list->nameOfItemType());
+ list = NULL;
+ } else
+ list = node->child();
+ }
+ return rc;
+}
/**
* @brief Returns the node type.
*
/**
* @brief Executes the statement.
+ *
+ * @return 0: continue the current statement list<br>
*/
-void RplASVarDefinition::execute(RplVMThread& thread)
+int RplASVarDefinition::execute(RplVMThread& thread)
{
if (m_child3 != NULL){
// has an initialization:
destination.toString().constData());
destination.copyValue(value);
}
+ return 0;
}
/** @class RplASExprStatement rplastree.hpp "rplexpr/rplastree.hpp"
}
/**
* @brief Executes the statement.
+ *
+ * @return 0: continue the current statement list<br>
*/
-void RplASExprStatement::execute(RplVMThread& thread)
+int RplASExprStatement::execute(RplVMThread& thread)
{
RplASCalculable* expr = dynamic_cast<RplASCalculable*> (m_child2);
expr->calc(thread);
RplASVariant& value = thread.popValue();
value.destroyValue();
+ return 0;
}
/**
RplASStatement::RplASStatement()
{
}
+/**
+ * @brief Executes the statements of a statement list.
+ *
+ * @param list statement list
+ * @param thread execution unit
+ * @return 0: continue the current statement list<br>
+ * n > 0: stop the n most inner statement lists (initialized by leave)
+ * n < 0: stop the -n most inner statement lists (initialized by continue)
+ */
+int RplASStatement::executeStatementList(RplASItem* list, RplVMThread& thread)
+{
+ int rc = 0;
+ while(rc == 0 && list != NULL){
+ RplASStatement* statement = dynamic_cast<RplASStatement*>(list);
+ rc =statement->execute(thread);
+ }
+ return rc;
+}
/** @class RplASCondition rplastree.hpp "rplexpr/rplastree.hpp"
*
*/
bool RplASIf::check(RplParser& parser)
{
- return false;
+ bool rc = m_child2 != NULL && m_child2->check(parser)
+ && (m_child3 == NULL || checkStatementList(m_child3, parser))
+ && (m_child4 == NULL || checkStatementList(m_child4, parser));
+ return rc;
}
/**
* @brief Executes the statement.
*
+ * @return 0: continue the current statement list<br>
+ * n > 0: stop the n most inner statement lists (initialized by leave)
+ * n < 0: stop the -n most inner statement lists (initialized by continue)
*/
-void RplASIf::execute(RplVMThread& thread)
+int RplASIf::execute(RplVMThread& thread)
{
+ int rc = 0;
RplASCondition* condition = dynamic_cast<RplASCondition*>(m_child2);
if (condition == NULL)
throw RplASException(m_child2 == NULL ? m_position : m_child2->position(),
"if statement: not a condition");
RplASStatement* body = NULL;
+ RplASItem* list;
if(condition->calcAsBool(thread)){
+ list = m_child3;
body = dynamic_cast<RplASStatement*>(m_child3);
if (body == NULL)
throw RplASException(m_child2 == NULL ? m_position : m_child2->position(),
"if statement: then-part is not a statement");
} else if (m_child4 != NULL){
+ list = m_child4;
body = dynamic_cast<RplASStatement*>(m_child4);
if (body == NULL)
throw RplASException(m_child4->position(),
"if statement: else-part is not a statement");
}
- body->execute(thread);
+ if ( (rc = executeStatementList(list, thread)) != 0){
+ if (rc < 0)
+ rc--;
+ else if (rc > 0)
+ rc++;
+ }
+ return rc;
}
/**
/**
* @brief Executes the statement.
*
+ * @return 0: continue the current statement list<br>
+ * n > 0: stop the n most inner statement lists (initialized by leave)
+ * n < 0: stop the -n most inner statement lists (initialized by continue)
*/
-void RplASForIterated::execute(RplVMThread& thread)
+int RplASForIterated::execute(RplVMThread& thread)
{
+ return 0;
}
/**
/**
* @brief Executes the statement.
*
+ * @return 0: continue the current statement list<br>
+ * n > 0: stop the n most inner statement lists (initialized by leave)
+ * n < 0: stop the -n most inner statement lists (initialized by continue)
*/
-void RplASForCounted::execute(RplVMThread& thread)
+int RplASForCounted::execute(RplVMThread& thread)
{
+ int rc = 0;
RplASStatement* body = dynamic_cast<RplASStatement*>(m_child2);
if (body == NULL)
throw RplASException(m_child2 == NULL ? m_position : m_child2->position(),
for(int ii = start; ii <= end; ii += step){
body->execute(thread);
}
+ return rc;
}
/**
/**
* @brief Executes the statement.
*
- * Meaning of the childs:
+ * @return 0: continue the current statement list<br>
+ * n > 0: stop the n most inner statement lists (initialized by leave)
+ * n < 0: stop the -n most inner statement lists (initialized by continue)
*/
-void RplASWhile::execute(RplVMThread& thread)
+int RplASWhile::execute(RplVMThread& thread)
{
+ int rc = 0;
RplASStatement* body = dynamic_cast<RplASStatement*>(m_child3);
if (body == NULL)
throw RplASException(m_child3 == NULL ? m_position : m_child3->position(),
while(condition->calcAsBool(thread)){
body->execute(thread);
}
+ return rc;
}
/**
* m_child: body
* m_child2: condition
*/
-void RplASRepeat::execute(RplVMThread& thread)
+int RplASRepeat::execute(RplVMThread& thread)
{
+ int rc = 0;
RplASStatement* body = dynamic_cast<RplASStatement*>(m_child3);
if (body == NULL)
throw RplASException(m_child3 == NULL ? m_position : m_child3->position(),
do {
body->execute(thread);
} while(condition->calcAsBool(thread));
+ return rc;
}
/**
}
/**
- * @brief Executes the statement.
+ * @brief Executes the method call.
+ *
+ * @return 0: continue the current statement list
*/
-void RplASMethodCall::execute(RplVMThread& thread)
+int RplASMethodCall::execute(RplVMThread& thread)
{
+ return 0;
}
RplASMethod* RplASMethodCall::method() const
*
* This method will be never called. Must exit: Otherwise the class is abstract.
*/
-void RplASMethod::execute(RplVMThread& thread)
+int RplASMethod::execute(RplVMThread& thread)
{
+ return 0;
}
virtual void dump(RplWriter& writer,int indent) = 0;
public:
static void reset();
+ static bool checkStatementList(RplASItem* list, RplParser& parser);
+public:
RplASItemType nodeType() const;
const char* nameOfItemType() const;
public:
RplASStatement();
public:
- virtual void execute(RplVMThread& thread) = 0;
+ virtual int execute(RplVMThread& thread) = 0;
+public:
+ static int executeStatementList(RplASItem* list, RplVMThread& thread);
};
RplASVarDefinition();
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
public:
void dump(RplWriter& writer, int indent);
const QByteArray& name() const;
RplASExprStatement();
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
public:
void dump(RplWriter& writer, int indent);
};
RplASIf();
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
virtual void dump(RplWriter& writer, int indent);
};
RplASForIterated(RplASVarDefinition* variable);
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
virtual void dump(RplWriter& writer, int indent);
};
RplASForCounted(RplASVarDefinition* variable);
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
virtual void dump(RplWriter& writer, int indent);
};
RplASWhile();
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
virtual void dump(RplWriter& writer, int indent);
};
RplASRepeat();
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
virtual void dump(RplWriter& writer, int indent);
};
RplASMethodCall(const QByteArray& name, RplASItem* parent);
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
public:
void dump(RplWriter& writer, int indent);
RplASMethod(const QByteArray& name, RplASTree& tree);
public:
virtual bool check(RplParser& parser);
- virtual void execute(RplVMThread& thread);
+ virtual int execute(RplVMThread& thread);
public:
void dump(RplWriter& writer, int indent);
RplSymbolSpace* symbols() const;