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
* will be issued.
*
* @param parser for error processing
+ * @param info additional info
* @return <code>false</code> (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;
}
/** @class RplASNamedValue rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements a named values, a constant or a variable
- *
- * <code>m_child</code>: NULL or the index expression (map/list)
*/
/**
* @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;
}
/**
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());
}
/**
RplASCalculable* expr = dynamic_cast<RplASCalculable*>(m_child);
expr->calc(thread);
RplASVariant& value = thread.topOfValues();
+
switch(m_conversion){
case C_INT_TO_FLOAT:
value.setFloat((qreal) value.asInt());
default:
break;
}
+ if (thread.tracing())
+ thread.vm()->traceWriter()->format("(%s): %s",
+ m_class->name().constData(),
+ value.toString().constData());
}
/**
*/
bool RplASConversion::check(RplParser& parser)
{
- bool rc = false;
+ bool rc = m_child != NULL && m_child->check(parser);
RplASCalculable* expr = dynamic_cast<RplASCalculable*>(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;
}
* @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<br>
+ * No change if no error
*
* @return NULL: no conversion necessary<br>
* 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<RplASCalculable*>(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());
{
}
+/**
+ * @brief Calculates an indexed expression.
+ *
+ * Possible: list index or map index
+ *
+ * @param thread execution value
+ */
+void RplASIndexedValue::calc(RplVMThread& thread)
+{
+ RplASCalculable* expr = dynamic_cast<RplASCalculable*>(m_child2);
+ expr->calc(thread);
+ RplASVariant& ixValue = thread.popValue();
+ int ix = ixValue.asInt();
+ RplASCalculable* list = dynamic_cast<RplASCalculable*>(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.
*
*/
bool RplASIndexedValue::check(RplParser& parser)
{
- bool rc = false;
RplASCalculable* list = dynamic_cast<RplASCalculable*>(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;
}
*/
bool RplASVarDefinition::check(RplParser& parser)
{
- bool rc = false;
- if (m_child3 != NULL){
- RplASNamedValue* var = dynamic_cast<RplASNamedValue*>(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<RplASCalculable*>(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<RplASNamedValue*>(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<RplASCalculable*>(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;
*/
void RplASVarDefinition::execute(RplVMThread& thread)
{
- RplASNamedValue* var = dynamic_cast<RplASNamedValue*>(m_child2);
- RplASCalculable* expr = dynamic_cast<RplASCalculable*>(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<RplASNamedValue*>(m_child2);
+ RplASCalculable* expr = dynamic_cast<RplASCalculable*>(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"
bool RplASExprStatement::check(RplParser& parser)
{
bool rc = m_child2->check(parser);
- RplASCalculable* expr = dynamic_cast<RplASCalculable*> (m_child2);
- if (expr == NULL)
- rc = false;
+ if (rc){
+ RplASCalculable* expr = dynamic_cast<RplASCalculable*> (m_child2);
+ if (expr == NULL)
+ rc = ensureError(parser, "RplASExprStatement::check");
+ }
return rc;
}
/**
*/
void RplASNode1::setChild(RplASItem* child)
{
- if (child->id() == 2)
- m_child = child;
m_child = child;
}
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());
}
/**
RplASCalculable* expr = dynamic_cast<RplASCalculable*>(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:
*/
void RplASCondition::calc(RplVMThread& thread)
{
- RplASCalculable* node = dynamic_cast<RplASCalculable*>(m_child);
- if (node == NULL)
- throw RplASException(m_position, "child of condition is not calculable");
- node->calc(thread);
+ RplASCalculable* expr = dynamic_cast<RplASCalculable*>(m_child);
+ expr->calc(thread);
+ if (thread.tracing())
+ thread.vm()->traceWriter()->format("condition: %s",
+ thread.topOfValues().toString().constData());
}
/**
*/
bool RplASCondition::check(RplParser& parser)
{
+ RplASCalculable* expr = dynamic_cast<RplASCalculable*>(m_child);
+ if (expr == NULL)
+ throw RplASException(m_position, "child of condition is not calculable");
return false;
}
/**