*/
void RplASExprStatement::calc(RplASVariant& value)
{
-
}
/**
delete m_child3;
m_child3 = NULL;
}
+/**
+ * @brief Returns the child3.
+ *
+ * @return the child 3
+ */
+RplASItem* RplASNode3::child3() const
+{
+ return m_child3;
+}
+
+/**
+ * @brief Sets the child3.
+ *
+ * @param child3 the new child3
+ */
+void RplASNode3::setChild3(RplASItem* child3)
+{
+ m_child3 = child3;
+}
+
/** @class RplASNode4 rplastree.hpp "rplexpr/rplastree.hpp"
*
m_child4 = NULL;
}
+/**
+ * @brief Returns the child4.
+ *
+ * @return the child 4
+ */
+RplASItem* RplASNode4::child4() const
+{
+ return m_child4;
+}
+
+/**
+ * @brief Sets the child4.
+ *
+ * @param child4 the new child3
+ */
+void RplASNode4::setChild4(RplASItem* child4)
+{
+ m_child4 = child4;
+}
+
+
+/** @class RplASNode5 rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements a inner node of the abstract syntax tree with 4 childs.
+ *
+ * This class is an abstract class.
+ */
+
+/**
+ * @brief RplASNode5::RplASNode5
+ * @param type
+ */
+RplASNode5::RplASNode5(RplASItemType type) :
+ RplASNode4(type),
+ m_child5(NULL)
+{
+}
+
+/**
+ * @brief Destructor.
+ */
+RplASNode5::~RplASNode5()
+{
+ delete m_child5;
+ m_child5 = NULL;
+}
+
+/**
+ * @brief Returns the child5.
+ *
+ * @return the child 5
+ */
+RplASItem* RplASNode5::child5() const
+{
+ return m_child5;
+}
+
+/**
+ * @brief Sets the child5.
+ *
+ * @param child5 the new child3
+ */
+void RplASNode5::setChild5(RplASItem* child5)
+{
+ m_child5 = child5;
+}
+
/** @class RplASUnaryOp rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements a unary operation.
m_child->dump(fp, indent);
}
+/** @class RplASIf rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements an if statement.
+ *
+ * The if statement has a condition, a then-part and an optional else-part.
+ * If the condition is evaluated to true, the then-part will be executed.
+ * Otherwise the else-part if it exists.
+ */
+
+RplASIf::RplASIf() :
+ RplASNode3(AST_IF)
+{
+}
+
+/**
+ * @brief Executes the statement.
+ *
+ * Meaning of the childs:
+ * m_child: condition
+ * m_child2: if-part
+ * m_child3: else-part
+ */
+void RplASIf::execute()
+{
+ RplASCondition* condition = dynamic_cast<RplASCondition*>(m_child);
+ if (condition == NULL)
+ throw RplASException(m_child == NULL ? m_position : m_child->position(),
+ "if statement: not a condition");
+ RplASStatement* body = NULL;
+ if(condition->calcAsBool()){
+ body = dynamic_cast<RplASStatement*>(m_child2);
+ if (body == NULL)
+ throw RplASException(m_child2 == NULL ? m_position : m_child2->position(),
+ "if statement: then-part is not a statement");
+ } else if (m_child2 != NULL){
+ body = dynamic_cast<RplASStatement*>(m_child3);
+ if (body == NULL)
+ throw RplASException(m_child3->position(),
+ "if statement: else-part is not a statement");
+ }
+ body->execute();
+}
+
+/**
+ * @brief Writes the internals into a file.
+ *
+ * @param fp target file
+ * @param indent nesting level
+ */
+void RplASIf::dump(FILE* fp, int indent)
+{
+ DEFINE_TABS(indent);
+ fprintf(fp, "%sIf id: %d condition: %d then: %d else: %d\n", tabs,
+ m_id, m_child->id(), m_child2->id(),
+ m_child3 == NULL ? 0 : m_child3->id());
+ m_child->dump(fp, indent + 1);
+ m_child2->dump(fp, indent + 1);
+ if (m_child3 != NULL)
+ m_child3->dump(fp, indent + 1);
+}
+
/** @class RplASFor rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements a for statement.
RplASStatement()
{
}
-/**
- * @brief Destructor.
- */
-RplASFor::~RplASFor()
-{
-}
/**
* @brief Executes the statement.
}
}
+/**
+ * @brief Writes the internals into a file.
+ *
+ * @param fp target file
+ * @param indent nesting level
+ */
+void RplASFor::dump(FILE* fp, int indent)
+{
+ DEFINE_TABS(indent);
+ fprintf(fp, "%sfor id: %d condition: %d then: %d else: %d\n", tabs,
+ m_id, m_child->id(), m_child2->id(),
+ m_child3 == NULL ? 0 : m_child3->id());
+ m_child->dump(fp, indent + 1);
+ m_child2->dump(fp, indent + 1);
+ if (m_child3 != NULL)
+ m_child3->dump(fp, indent + 1);
+}
+
+/** @class RplASForCounted rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements a for statement.
+ *
+ * The for statement has an optional variable, an optional start value,
+ * an end value, an optional step and a body.
+ *
+ * The start and end value will be calculated.
+ * The body will be executed so many times given by the start and end value.
+ */
+
+/**
+ * @brief Constructor.
+ */
+RplASForCounted::RplASForCounted() :
+ RplASNode5(AST_FOR),
+ RplASStatement()
+{
+}
+
+/**
+ * @brief Executes the statement.
+ *
+ * Meaning of the childs:
+ * m_child: body
+ * m_child2: variable
+ * m_child3: start value
+ * m_child4: end value
+ * m_child5: step value
+ */
+void RplASForCounted::execute()
+{
+ RplASStatement* body = dynamic_cast<RplASStatement*>(m_child);
+ if (body == NULL)
+ throw RplASException(m_child == NULL ? m_position : m_child->position(),
+ "forc statement: body is not a statement");
+ int start = 1;
+ int step = 1;
+ int end = 0;
+ RplASNamedValue* var = NULL;
+ if (m_child2 != NULL){
+ var = dynamic_cast<RplASNamedValue*>(m_child2);
+ }
+ for(int ii = start; ii <= end; ii++){
+ body->execute();
+ }
+}
+
+/**
+ * @brief Writes the internals into a file.
+ *
+ * @param fp target file
+ * @param indent nesting level
+ */
+void RplASForCounted::dump(FILE* fp, int indent)
+{
+ DEFINE_TABS(indent);
+ fprintf(fp, "%sforc id: %d var: %d from: %d to: %d step: %d body: %d\n",
+ tabs, m_id,
+ m_child2 == NULL ? 0 : m_child2->id(),
+ m_child3 == NULL ? 0 : m_child3->id(),
+ m_child4 == NULL ? 0 : m_child4->id(),
+ m_child5 == NULL ? 0 : m_child5->id(),
+ m_child == NULL ? 0 : m_child->id());
+ if (m_child2 != NULL)
+ m_child2->dump(fp, indent + 1);
+ if (m_child3 != NULL)
+ m_child3->dump(fp, indent + 1);
+ if (m_child4 != NULL)
+ m_child4->dump(fp, indent + 1);
+ if (m_child5 != NULL)
+ m_child5->dump(fp, indent + 1);
+ if (m_child != NULL)
+ m_child->dump(fp, indent + 1);
+}
+
/** @class RplASWhile rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements a while statement.
RplASStatement()
{
}
+
/**
- * @brief Destructor.
+ * @brief Executes the statement.
+ *
+ * Meaning of the childs:
+ * m_child: body
+ * m_child2: condition
+ */
+void RplASWhile::execute()
+{
+ RplASStatement* body = dynamic_cast<RplASStatement*>(m_child);
+ if (body == NULL)
+ throw RplASException(m_child == NULL ? m_position : m_child->position(),
+ "while statement: body is not a statement");
+ RplASCondition* condition = dynamic_cast<RplASCondition*>(m_child2);
+ if (condition == NULL)
+ throw RplASException(m_child2 == NULL ? m_position : m_child2->position(),
+ "for statement: not a condition");
+ while(condition->calcAsBool()){
+ body->execute();
+ }
+}
+
+/**
+ * @brief Writes the internals into a file.
+ *
+ * @param fp target file
+ * @param indent nesting level
+ */
+void RplASWhile::dump(FILE* fp, int indent)
+{
+ DEFINE_TABS(indent);
+ fprintf(fp, "%swhile id: %d condition: %d body: %d\n", tabs, m_id,
+ m_child2 == NULL ? 0 : m_child2->id(),
+ m_child == NULL ? 0 : m_child->id());
+ if (m_child2 != NULL)
+ m_child2->dump(fp, indent + 1);
+ if (m_child != NULL)
+ m_child->dump(fp, indent + 1);
+}
+
+/** @class RplASRepeat rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements a while statement.
+ *
+ * The while statement has an a condition and a body.
+ * The body will be executed while the condition returns true.
+ */
+
+RplASRepeat::RplASRepeat() :
+ RplASNode2(AST_REPEAT),
+ RplASStatement()
+{
+}
+
+/**
+ * @brief Executes the statement.
+ *
+ * Meaning of the childs:
+ * m_child: body
+ * m_child2: condition
+ */
+void RplASRepeat::execute()
+{
+ RplASStatement* body = dynamic_cast<RplASStatement*>(m_child);
+ if (body == NULL)
+ throw RplASException(m_child == NULL ? m_position : m_child->position(),
+ "while statement: body is not a statement");
+ RplASCondition* condition = dynamic_cast<RplASCondition*>(m_child2);
+ if (condition == NULL)
+ throw RplASException(m_child2 == NULL ? m_position : m_child2->position(),
+ "for statement: not a condition");
+ do {
+ body->execute();
+ } while(condition->calcAsBool());
+}
+
+/**
+ * @brief Writes the internals into a file.
+ *
+ * @param fp target file
+ * @param indent nesting level
*/
-RplASWhile::~RplASWhile()
+void RplASRepeat::dump(FILE* fp, int indent)
{
+ DEFINE_TABS(indent);
+ fprintf(fp, "%srepeat id: %d condition: %d body: %d\n", tabs, m_id,
+ m_child2 == NULL ? 0 : m_child2->id(),
+ m_child == NULL ? 0 : m_child->id());
+ if (m_child2 != NULL)
+ m_child2->dump(fp, indent + 1);
+ if (m_child != NULL)
+ m_child->dump(fp, indent + 1);
}
+
/** @class RplASClass rplastree.hpp "rplexpr/rplastree.hpp"
*
* @brief Implements the base class of a Abstract Syntax Tree class.
* @brief constructor
*/
RplASArgument::RplASArgument() :
- RplASNode2(AST_ARGUMENT),
- RplASStatement()
+ RplASNode2(AST_ARGUMENT)
{
}
+
+
L_DEFINITION_UNKNOWN_CLASS,
L_DEFINITION_MISSING_ID,
L_DEFINITION_NO_OP = 2010,
- L_DEFINITION_NO_SEMICOLON
+ L_DEFINITION_NO_SEMICOLON,
+ L_PARSE_IF_NO_THEN,
+ L_PARSE_IF_NO_ELSE,
+ L_PARSE_IF_NO_FI,
+ L_PARSE_WHILE_NO_DO = 2015,
+ L_PARSE_WHILE_NO_OD,
+ L_PARSE_REPEAT_NO_UNTIL,
+ L_PARSE_REPEAT_NO_SEMI
};
*/
RplASItem* RplMFParser::parseIf()
{
- RplASItem*rc = NULL;
+ RplASIf* rc = new RplASIf();
+ rc->setPosition(m_lexer.currentPosition());
+
+ RplASItem* condition = parseExpr();
+ if (! m_lexer.currentToken()->isKeyword(K_THEN))
+ syntaxError(L_PARSE_IF_NO_THEN, "'then' expected");
+ rc->setChild(condition);
+ RplASItem* body = parseBody();
+ rc->setChild2(body);
+ if (! m_lexer.currentToken()->isKeyword(K_ELSE, K_FI))
+ syntaxError(L_PARSE_IF_NO_ELSE, "'else' or 'fi' expected");
+ if ( m_lexer.currentToken()->isKeyword(K_ELSE)){
+ RplASItem* body = parseBody();
+ rc->setChild3(body);
+ }
+ if (! m_lexer.currentToken()->isKeyword(K_FI))
+ syntaxError(L_PARSE_IF_NO_FI, "'fi' expected");
return rc;
}
/**
RplASItem* RplMFParser::parseWhile()
{
- RplASItem*rc = NULL;
+ RplASWhile* rc = new RplASWhile();
+ rc->setPosition(m_lexer.currentPosition());
+
+ RplASItem* condition = parseExpr();
+ if (! m_lexer.currentToken()->isKeyword(K_DO))
+ syntaxError(L_PARSE_WHILE_NO_DO, "'do' expected");
+ rc->setChild2(condition);
+ RplASItem* body = parseBody();
+ rc->setChild(body);
+ if (! m_lexer.currentToken()->isKeyword(K_OD))
+ syntaxError(L_PARSE_WHILE_NO_OD, "'od' expected");
return rc;
}
*/
RplASItem* RplMFParser::parseRepeat()
{
- RplASItem*rc = NULL;
+ RplASRepeat* rc = new RplASRepeat();
+ rc->setPosition(m_lexer.currentPosition());
+
+ RplASItem* body = parseBody();
+ rc->setChild(body);
+ if (! m_lexer.currentToken()->isKeyword(K_UNTIL))
+ syntaxError(L_PARSE_REPEAT_NO_UNTIL, "'until' expected");
+
+ RplASItem* condition = parseExpr();
+ if (! m_lexer.currentToken()->isOperator(O_SEMICOLON))
+ syntaxError(L_PARSE_REPEAT_NO_SEMI, "';' expected");
+ rc->setChild2(condition);
return rc;
}