snprintf(buffer, sizeof buffer, "%s has no content. Does it exist?",
expected);
error(buffer);
- } else if (expectedContent.isEmpty()){
+ } else if (currentContent.isEmpty()){
char buffer[512];
snprintf(buffer, sizeof buffer, "%s has no content. Does it exist?",
current);
error(buffer);
} else {
QList<QByteArray> expLines = expectedContent.split('\n');
- QList<QByteArray> curLines = expectedContent.split('\n');
+ QList<QByteArray> curLines = currentContent.split('\n');
rc = assertEquals(expLines, curLines, file, lineNo);
}
return rc;
return m_id;
}
+/**
+ * @brief Returns the position as a string.
+ *
+ * @param buffer OUT: the target buffer
+ * @param bufferSize size of the target buffer
+ * @return <code>buffer</code>
+ */
+char* RplASItem::positionStr(char buffer[], size_t bufferSize) const
+{
+ char* rc = (char*) "";
+ if (m_position != NULL)
+ rc = m_position->utf8(buffer, bufferSize);
+ return rc;
+}
+
/**
* @brief Resets the static id counter.
*/
{
m_nextId = 1;
}
-
+/**
+ * @brief Returns the node type.
+ *
+ * @return the node type
+ */
+RplASItemType RplASItem::nodeType() const
+{
+ return m_nodeType;
+}
/** @class RplASExpr rplastree.hpp "rplexpr/rplastree.hpp"
*
char buffer[256];
fprintf(fp, "%sconst id: %d value: %s %s\n", tabs, m_id,
m_value.toString().toUtf8().constData(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
}
/**
char buffer[256];
fprintf(fp, "%snamedValue %s id: %d attr: 0x%x %s\n", tabs,
m_name.toUtf8().constData(), m_id, m_attributes,
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
}
/** @class RplVarDefinition rplastree.hpp "rplexpr/rplastree.hpp"
fprintf(fp, "%svarDef %s (%s) id: %d succ: %d attr: 0x%x %s\n",
tabs, name.constData(), className.constData(),
m_id, m_successor == NULL ? 0 : m_successor->id(), m_attributes,
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
if (m_child != NULL)
m_child->dump(fp, indent + 1);
if (m_successor != NULL)
fprintf(fp, "%sExpr id: %d succ: %d expr: %d %s\n", tabs, m_id,
m_successor == NULL ? 0 : m_successor->id(),
m_child == NULL ? 0 : m_child->id(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
if (m_child != NULL)
m_child->dump(fp, indent + 1);
if (m_successor != NULL)
*
* @return the child of the instance
*/
-RplASItem*RplASNode1::child() const
+RplASItem* RplASNode1::child() const
{
-
+ return m_child;
}
/**
* @brief Sets the child.
{
DEFINE_TABS(indent);
char buffer[256];
- fprintf(fp, "%sUnary %d op: %d Child: %d %s\n", tabs, m_id, m_operator,
+ fprintf(fp, "%sUnary %d op: %s (%d) Child: %d %s\n", tabs,
+ m_id,
+ RplLexer::m_active->nameOfOp(m_operator).constData(),
+ m_operator,
m_child == NULL ? 0 : m_child->id(),
- m_position->utf8(buffer, sizeof buffer) );
+ positionStr(buffer, sizeof buffer) );
if (m_child != NULL)
m_child->dump(fp, indent);
}
char buffer[256];
fprintf(fp, "%sCondition %d Child: %d %s\n", tabs, m_id,
m_child == NULL ? 0 : m_child->id(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
if (m_child != NULL)
m_child->dump(fp, indent);
}
fprintf(fp, "%sIf id: %d condition: %d then: %d else: %d %s\n", tabs,
m_id, m_child->id(), m_child2->id(),
m_child3 == NULL ? 0 : m_child3->id(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
m_child->dump(fp, indent + 1);
m_child2->dump(fp, indent + 1);
if (m_child3 != NULL)
/**
* @brief Constructor.
+ *
+ * @param variable NULL or the iterator variable
*/
-RplASFor::RplASFor() :
- RplASNode4(AST_FOR),
+RplASForIterated::RplASForIterated(RplASNamedValue* variable) :
+ RplASNode3(AST_ITERATED_FOR),
RplASStatement()
{
+ m_child2 = variable;
}
/**
* m_child3: forwarding statement
* m_child4: body
*/
-void RplASFor::execute()
+void RplASForIterated::execute()
{
- ((RplASStatement*) m_child)->execute();
- 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");
- RplASStatement* forwarding = dynamic_cast<RplASStatement*>(m_child3);
- if (forwarding == NULL)
- throw RplASException(m_child3 == NULL ? m_position : m_child3->position(),
- "for statement: forwarding is not a statement");
- RplASStatement* body = dynamic_cast<RplASStatement*>(m_child4);
- if (body == NULL)
- throw RplASException(m_child4 == NULL ? m_position : m_child4->position(),
- "for statement: body is not a statement");
- while(condition->calcAsBool()){
- body->execute();
- forwarding->execute();
- }
}
/**
* @param fp target file
* @param indent nesting level
*/
-void RplASFor::dump(FILE* fp, int indent)
+void RplASForIterated::dump(FILE* fp, int indent)
{
DEFINE_TABS(indent);
char buffer[256];
- fprintf(fp, "%sfor id: %d condition: %d then: %d else: %d %s\n", tabs,
- m_id, m_child->id(), m_child2->id(),
+ fprintf(fp, "%sforIt id: %d var: %d set: %d body: %d %s\n", tabs,
+ m_id,
+ m_child2 == NULL ? 0 : m_child2->id(),
m_child3 == NULL ? 0 : m_child3->id(),
- m_position->utf8(buffer, sizeof buffer));
- m_child->dump(fp, indent + 1);
- m_child2->dump(fp, indent + 1);
+ m_child == NULL ? 0 : m_child->id(),
+ positionStr(buffer, sizeof buffer));
+ if (m_child2 != NULL)
+ m_child2->dump(fp, indent + 1);
if (m_child3 != NULL)
m_child3->dump(fp, indent + 1);
+ if (m_child != NULL)
+ m_child->dump(fp, indent + 1);
}
/** @class RplASForCounted rplastree.hpp "rplexpr/rplastree.hpp"
/**
* @brief Constructor.
+ *
+ * @param variable NULL or the counter variable
*/
-RplASForCounted::RplASForCounted() :
- RplASNode5(AST_FOR),
+RplASForCounted::RplASForCounted(RplASNamedValue* variable) :
+ RplASNode5(AST_ITERATED_FOR),
RplASStatement()
{
+ m_child2 = variable;
}
/**
m_child4 == NULL ? 0 : m_child4->id(),
m_child5 == NULL ? 0 : m_child5->id(),
m_child == NULL ? 0 : m_child->id(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
if (m_child2 != NULL)
m_child2->dump(fp, indent + 1);
if (m_child3 != NULL)
fprintf(fp, "%swhile id: %d condition: %d body: %d %s\n", tabs, m_id,
m_child2 == NULL ? 0 : m_child2->id(),
m_child == NULL ? 0 : m_child->id(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
if (m_child2 != NULL)
m_child2->dump(fp, indent + 1);
if (m_child != NULL)
fprintf(fp, "%srepeat id: %d condition: %d body: %d %s\n", tabs, m_id,
m_child2 == NULL ? 0 : m_child2->id(),
m_child == NULL ? 0 : m_child->id(),
- m_position->utf8(buffer, sizeof buffer));
- if (m_child2 != NULL)
- m_child2->dump(fp, indent + 1);
+ positionStr(buffer, sizeof buffer));
if (m_child != NULL)
m_child->dump(fp, indent + 1);
+ if (m_child2 != NULL)
+ m_child2->dump(fp, indent + 1);
}
/** @class RplASClass rplastree.hpp "rplexpr/rplastree.hpp"
fprintf(fp, "%sCall %d instance: %d args: %d %s\n", tabs, m_id,
m_child == NULL ? 0 : m_child->id(),
m_child2 == NULL ? 0 : m_child2->id(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
if (m_child != NULL)
m_child->dump(fp, indent + 1);
if (m_child2 != NULL)
opName.constData(), m_operator,
m_child == NULL ? 0 : m_child->id(),
m_child2 == NULL ? 0 : m_child2->id(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
if (indent < 32 && m_child != NULL)
m_child->dump(fp, indent + 1);
if (indent < 32 && m_child2 != NULL)
m_name.toUtf8().constData());
fprintf(fp, ") body: %d args: %d %s\n", m_child == NULL ? 0 : m_child->id(),
m_child2 == NULL ? 0 : m_child2->id(),
- m_position->utf8(buffer, sizeof buffer));
+ positionStr(buffer, sizeof buffer));
}
/** @class RplASArgument rplastree.hpp "rplexpr/rplastree.hpp"
AST_REPEAT,
AST_IF,
AST_CONDITION,
- AST_FOR,
+ AST_ITERATED_FOR,
AST_COUNTED_FOR,
AST_SWITCH,
AST_LEAVE,
const RplSourcePosition* position() const;
void setPosition(const RplSourcePosition* position);
unsigned int id() const;
+ char* positionStr(char buffer[], size_t bufferSize) const;
public:
/**
* @brief Writes the content of the instance into a file.
virtual void dump(FILE* fp, int indent) = 0;
public:
static void reset();
+ RplASItemType nodeType() const;
+
protected:
unsigned int m_id:16;
RplASItemType m_nodeType:8;
virtual void dump(FILE* fp, int indent);
};
-class RplASFor : public RplASNode4, public RplASStatement
+class RplASForIterated : public RplASNode3, public RplASStatement
{
public:
- RplASFor();
+ RplASForIterated(RplASNamedValue* variable);
public:
virtual void execute();
virtual void dump(FILE* fp, int indent);
class RplASForCounted : public RplASNode5, public RplASStatement
{
public:
- RplASForCounted();
+ RplASForCounted(RplASNamedValue* variable);
public:
virtual void execute();
virtual void dump(FILE* fp, int indent);
// 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 id = m_operators[ix].at(2).unicode();
- m_charInfo[id] |= CC_OP_1_ONLY;
+ int cc = (char) m_operators[ix].at(0).unicode();
+ m_charInfo[cc] |= CC_OP_1_ONLY;
}
}
L_PARSE_WHILE_NO_DO = 2015,
L_PARSE_WHILE_NO_OD,
L_PARSE_REPEAT_NO_UNTIL,
- L_PARSE_REPEAT_NO_SEMI
+ L_PARSE_REPEAT_NO_SEMI,
+ L_PARSE_BODY_WRONG_ITEM,
+ L_PARSE_FOR_NO_TO = 2020
};
RplASIf* rc = new RplASIf();
rc->setPosition(m_lexer.currentPosition());
- RplASItem* condition = parseExpr();
+ RplASItem* condition = parseExpr(0);
if (! m_lexer.currentToken()->isKeyword(K_THEN))
syntaxError(L_PARSE_IF_NO_THEN, "'then' expected");
rc->setChild(condition);
RplASWhile* rc = new RplASWhile();
rc->setPosition(m_lexer.currentPosition());
- RplASItem* condition = parseExpr();
+ RplASItem* condition = parseExpr(0);
if (! m_lexer.currentToken()->isKeyword(K_DO))
syntaxError(L_PARSE_WHILE_NO_DO, "'do' expected");
rc->setChild2(condition);
if (! m_lexer.currentToken()->isKeyword(K_UNTIL))
syntaxError(L_PARSE_REPEAT_NO_UNTIL, "'until' expected");
- RplASItem* condition = parseExpr();
+ RplASItem* condition = parseExpr(0);
if (! m_lexer.currentToken()->isOperator(O_SEMICOLON))
syntaxError(L_PARSE_REPEAT_NO_SEMI, "';' expected");
rc->setChild2(condition);
/**
* @brief Parses a for statement.
+ *
+ * Syntax:
+ * for [ <var> ] [ from <start_expr> ] to <end_expr> [ step <step_expr> ] do
+ * <body> od
+ *
+ * for <var> in <iterable_expr> do <body> od
+ *
*/
RplASItem* RplMFParser::parseFor()
{
- RplASItem*rc = NULL;
+ RplASNode2* rc = NULL;
+ const RplSourcePosition* startPosition = m_lexer.currentPosition();
+ RplToken* token = m_lexer.nextNonSpaceToken();
+ RplASNamedValue* var = NULL;
+ if (token->isTokenType(TOKEN_ID)){
+ var = new RplASNamedValue(token->toString());
+ var->setPosition(m_lexer.currentPosition());
+ token = m_lexer.nextNonSpaceToken();
+ }
+ if (token->isKeyword(K_IN)){
+ RplASForIterated* node = new RplASForIterated(var);
+ rc = node;
+ node->setPosition(startPosition);
+ RplASItem* iterable = parseExpr(0);
+ node->setChild3(iterable);
+ } else {
+ RplASForCounted* node = new RplASForCounted(var);
+ rc = node;
+ node->setPosition(startPosition);
+ if (token->isKeyword(K_FROM)){
+ node->setChild3(parseExpr(0));
+ }
+ if (! token->isKeyword(K_TO)){
+ syntaxError(L_PARSE_FOR_NO_TO, "'to' expected");
+ }
+ node->setChild4(parseExpr(0));
+ if (token->isKeyword(K_STEP)){
+ node->setChild5(parseExpr(0));
+ }
+ }
+ if (! token->isKeyword(K_DO))
+ syntaxError(L_PARSE_FOR_NO_TO, "'to' expected");
+ rc->setChild(parseBody(K_OD));
return rc;
}
if (! token->isOperator(O_ASSIGN, O_SEMICOLON))
syntaxError(L_DEFINITION_NO_OP, "'=' or ';' expected");
if (token->id() == O_ASSIGN){
- RplASItem* value = parseExpr();
+ RplASItem* value = parseExpr(0);
rc->setChild(value);
token = m_lexer.currentToken();
}
switch(token->tokenType()){
case TOKEN_OPERATOR:
{
- Operator op = (Operator) token->id();
- if (op == O_LPARENTH){
- rc = parseTerm(level + 1);
- } else if (IS_UNARY_OP(op)){
- RplASUnaryOp* node = new RplASUnaryOp(token->id(), AST_PRE_UNARY_OP);
- rc = node;
- node->setChild(parseOperand(level));
- token = m_lexer.nextNonSpaceToken();
- if(token->tokenType() != TOKEN_OPERATOR || token->id() != O_RPARENT){
- QByteArray pos = startPosition->toString().toUtf8();
+ Operator opId = (Operator) token->id();
+ if (opId == O_LPARENTH){
+ rc = parseExpr(level + 1);
+ token = m_lexer.currentToken();
+ if(! token->isOperator(O_RPARENT)){
+ char buffer[256];
// this call never comes back (exception!)
syntaxError(L_PARSE_OPERAND_RPARENTH,
- "')' expected. '(' is at %s", pos.constData());
+ "')' expected. '(' is at %s",
+ startPosition->utf8(buffer, sizeof buffer));
}
+ } else if (IS_UNARY_OP(opId)){
+ RplASUnaryOp* op = new RplASUnaryOp(token->id(), AST_PRE_UNARY_OP);
+ op->setPosition(m_lexer.currentPosition());
+ op->setChild(parseOperand(level));
+ rc = op;
}
break;
}
}
/**
- * @brief Parses a term.
+ * @brief Parses an expression.
+ *
+ * This method parses the part of an expression with the same parenthesis level.
+ * The nested parts will be processed recursivly by calling parseOperand which
+ * calls <code>parseExpr</code> in the case of inner parentheses.
*
- * A term is a part of an expression with the same parenthesis level.
* Example: a + (3 * 7 - 2)<br>
- * first term: 3*7-2<br>
- * second term: a + term1<br>
+ * expr with level 1: 3*7-2<br>
+ * expr with level 0: a + expr1<br>
+ *
+ * @precond the nextNonSpaceToken() will return the first token of the expr.
+ * @postcond the next token behind the expression is read
*
* @param depth the level of the parenthesis
* @return the abstract syntax tree representing the parsed expression
*/
-RplASItem* RplMFParser::parseTerm(int depth){
+RplASItem* RplMFParser::parseExpr(int depth){
RplToken* token;
RplASItem* top = parseOperand(depth);
int lastPrio = INT_MAX;
&& ! m_lexer.isRightAssociative(opId))){
op->setChild(top);
top = op;
- } else if (prio > lastPrio){
- RplASBinaryOp* top2 = dynamic_cast<RplASBinaryOp*>(op);
- op->setChild(top2->child2());
- top2->setChild2(op);
} else {
- // right assoc:
+ // right assoc or higher priority:
RplASBinaryOp* top2 = dynamic_cast<RplASBinaryOp*>(top);
op->setChild(top2->child2());
top2->setChild2(op);
return top;
}
+
/**
- * @brief Parses an expression.
+ * @brief Parses an expression as a statement.
*
* @precond the nextNonSpaceToken() will return the first token of the expr.
* @postcond all tokens belonging to the expr are read (not more!)
*
- * @return the tree of the expression
- */
-RplASItem* RplMFParser::parseExpr()
-{
- RplASItem* rc = parseTerm(0);
- return rc;
-}
-
-/**
- * @brief Parses an expression as a statement.
- *
* @return the abstract syntax tree of the expression statement
*/
RplASItem* RplMFParser::parseExprStatement()
{
- RplASItem* item = parseTerm(0);
+ RplASItem* item = parseExpr(0);
RplASExprStatement* statement = new RplASExprStatement();
statement->setPosition(item->position());
statement->setChild(item);
}
lastStatement = dynamic_cast<RplASStatement*>(item);
if (lastStatement == NULL)
- assert("wrong item type" == NULL);
+ error(L_PARSE_BODY_WRONG_ITEM, "wrong item type: %d",
+ item == NULL ? 0 : item->nodeType());
token = m_lexer.currentToken();
if ((keywordStop != K_UNDEF
&& token->isKeyword(keywordStop, keywordStop2))
public:
enum Keyword {
K_UNDEF, K_IF, K_THEN, K_ELSE, K_FI, K_WHILE, K_DO, K_OD, K_REPEAT, K_UNTIL,
- K_FOR, K_FROM, K_TO, K_STEP, K_CASE, K_OF, K_ESAC, K_LEAVE, K_CONTINUE, K_PASS,
+ K_FOR, K_FROM, K_TO, K_STEP, K_IN, K_CASE, K_OF, K_ESAC, K_LEAVE, K_CONTINUE, K_PASS,
K_CLASS, K_ENDC, K_ENDF, K_FUNCTION, K_GENERATOR, K_IMPORT,
K_CONST, K_LAZY, K_NONE, K_TRUE, K_FALSE
};
#define MF_KEYWORDS "if then else fi while do od repeat until" \
- " for from to step case of esac leave continue pass" \
+ " for from to step in case of esac leave continue pass" \
" class endc endf func generator import" \
" const lazy none true false"
enum Operator {
- O_UNDEF, O_SEMI_SEMICOLON, O_SEMICOLON, O_COMMA, O_COLON,
- O_ASSIGN, O_PLUS_ASSIGN, O_MINUS_ASSIGN, O_DIV_ASSIGN, O_TIMES_ASSIGN,
- O_MOD_ASSIGN, O_POWER_ASSIGN, O_OR_ASSIGN, O_AND_ASSIGN,
- O_LSHIFT_ASSIGN, O_RSHIFT_ASSIGN, O_RSHIFT2_ASSIGN,
- O_OR, O_AND,
- O_EQ, O_NE,
- O_LT, O_GT, O_LE, O_GE,
- O_QUESTION,
- O_PLUS, O_MINUS,
- O_DIV, O_MOD, O_TIMES,
- O_POWER,
- O_XOR, O_BIT_OR, O_BIT_AND,
- O_LSHIFT, O_RSHIFT, O_RSHIFT2,
- O_DOT,
- O_NOT, O_BIT_NOT,
- O_INC, O_DEC,
- O_LPARENTH, O_RPARENT, O_LBRACKET, O_RBRACKET, O_LBRACE, O_RBRACE
+ O_UNDEF, O_SEMI_SEMICOLON, O_SEMICOLON, O_COMMA, O_COLON, // 4
+ O_ASSIGN, O_PLUS_ASSIGN, O_MINUS_ASSIGN, O_DIV_ASSIGN, O_TIMES_ASSIGN, // 8
+ O_MOD_ASSIGN, O_POWER_ASSIGN, O_OR_ASSIGN, O_AND_ASSIGN, // 13
+ O_LSHIFT_ASSIGN, O_RSHIFT_ASSIGN, O_RSHIFT2_ASSIGN, // 16
+ O_OR, O_AND, // 18
+ O_EQ, O_NE, // 20
+ O_LT, O_GT, O_LE, O_GE, // 24
+ O_QUESTION, // 25
+ O_PLUS, O_MINUS, // 27
+ O_DIV, O_MOD, O_TIMES, // 30
+ O_POWER, // 31
+ O_XOR, O_BIT_OR, O_BIT_AND, // 34
+ O_LSHIFT, O_RSHIFT, O_RSHIFT2, // 37
+ O_NOT, O_BIT_NOT, // 39
+ O_INC, O_DEC, // 41
+ O_DOT, O_LPARENTH, O_RPARENT, O_LBRACKET, O_RBRACKET, O_LBRACE, O_RBRACE // 48
};
#define IS_BINARY_OP(op) (Operator(op) >= O_ASSIGN && Operator(op) <= O_DOT)
#define IS_UNARY_OP(op) (op==O_PLUS || op==O_MINUS || (op>=O_NOT && op<=O_DEC))
"**\n" \
"^ | &\n" \
"<< >> >>>\n" \
- ".\n" \
"! ~\n" \
"++ --\n" \
". ( ) [ ] { }"
RplASItem* parseRepeat();
RplASItem* parseFor();
RplASItem* parseVarDefinition(Keyword attribute);
- RplASItem* parseExpr();
+ RplASItem* parseExpr(int depth);
RplASItem* parseBody(Keyword keywordStop, Keyword keywordStop2 = K_UNDEF,
Operator opStop = O_UNDEF, Operator opStop2 = O_UNDEF);
RplASItem* parseMethodDefinition();
protected:
RplASArgument* parseArguments();
RplASItem* parseOperand(int level);
- RplASItem* parseTerm(int depth);
private:
///syntax token builder.
/// Note: the super class contains a reference with the same name
-=== Globals:
-= global (global) parent: <none>
+2+3*4
+= <test> (module) parent: global
== Classes:
- class Boolean super: <none>
- class Boolean super: <none>
- class Integer super: Float
- class List super: <none>
- class Map super: <none>
- class String super: <none>
== Variables:
-== Body: <none>
- = <test> (module) parent: global
- == Classes:
- == Variables:
- == Body:
- BinOp 2 op: + (26) left: 1 right: 3
- Constant 1 value: 2
- Constant 3 value: 3
+== Body:
+Expr id: 6 succ: 0 expr: 2 <test>:1:1
+ BinOp id: 2 op: + (26) left: 1 right: 4 <test>:1:1
+ const id: 1 value: 2 <test>:0:0
+ BinOp id: 4 op: * (30) left: 3 right: 5 <test>:1:3
+ const id: 3 value: 3 <test>:1:2
+ const id: 5 value: 4 <test>:1:4
-=== Globals:
-= global (global) parent: <none>
+Int i = 3; const lazy Str s = 'Hi'; const List l;
+= <test> (module) parent: global
== Classes:
- class Bool super: <none>
- class Float super: <none>
- class Int super: Float
- class List super: <none>
- class Map super: <none>
- class Str super: <none>
== Variables:
-== Body: <none>
- = <test> (module) parent: global
- == Classes:
- == Variables:
- == Body:
- varDef i (Int) id: 1 succ: 3 attr: 0x0
- const id: 2 value: 3
- varDef s (Str) id: 3 succ: 5 attr: 0x10
- const id: 4 value: 'Hi'
- varDef l (List) id: 5 succ: 0 attr: 0x2
+== Body:
+varDef i (Int) id: 1 succ: 3 attr: 0x0 <test>:1:4
+ const id: 2 value: 3 <test>:1:8
+varDef s (Str) id: 3 succ: 5 attr: 0x10 <test>:1:26
+ const id: 4 value: 'Hi' <test>:1:30
+varDef l (List) id: 5 succ: 0 attr: 0x2 <test>:1:47
--- /dev/null
+Int a;
+for b from 10 to 1 step -2 do
+a += 1;
+od
+= <test> (module) parent: global
+== Classes:
+== Variables:
+== Body:
+varDef a (Int) id: 1 succ: 3 attr: 0x0 <test>:1:4
+forc id: 3 var: 2 from: 4 to: 5 step: 6 body: 11 <test>:1:7
+ namedValue b id: 2 attr: 0x0 <test>:2:4
+ const id: 4 value: 10 <test>:2:11
+ const id: 5 value: 1 <test>:2:17
+ Unary 6 op: - (27) Child: 7 <test>:2:24
+ const id: 7 value: 2 <test>:2:25
+ Expr id: 11 succ: 0 expr: 9 <test>:3:2
+ BinOp id: 9 op: += (6) left: 8 right: 10 <test>:3:2
+ namedValue a id: 8 attr: 0x0 <test>:3:2
+ const id: 10 value: 1 <test>:3:5
--- /dev/null
+Int a; for to 10 do a += 1 od
+= <test> (module) parent: global
+== Classes:
+== Variables:
+== Body:
+varDef a (Int) id: 1 succ: 2 attr: 0x0 <test>:1:4
+forc id: 2 var: 0 from: 0 to: 3 step: 0 body: 7 <test>:1:7
+ const id: 3 value: 10 <test>:1:14
+ Expr id: 7 succ: 0 expr: 5 <test>:1:22
+ BinOp id: 5 op: += (6) left: 4 right: 6 <test>:1:22
+ namedValue a id: 4 attr: 0x0 <test>:1:22
+ const id: 6 value: 1 <test>:1:25
--- /dev/null
+Map a;
+for x in a do
+a += 1;
+od
+= <test> (module) parent: global
+== Classes:
+== Variables:
+== Body:
+varDef a (Map) id: 1 succ: 3 attr: 0x0 <test>:1:4
+forIt id: 3 var: 2 set: 4 body: 8 <test>:1:7
+ namedValue x id: 2 attr: 0x0 <test>:2:4
+ namedValue a id: 4 attr: 0x0
+ Expr id: 8 succ: 0 expr: 6 <test>:3:2
+ BinOp id: 6 op: += (6) left: 5 right: 7 <test>:3:2
+ namedValue a id: 5 attr: 0x0 <test>:3:2
+ const id: 7 value: 1 <test>:3:5
const id: 10 value: 11 <test>:4:3
const id: 12 value: 12 <test>:4:8
Expr id: 18 succ: 0 expr: 14 <test>:5:7
- BinOp id: 14 op: = (5) left: 13 right: 15 <test>:5:7
+ BinOp id: 14 op: = (5) left: 13 right: 16 <test>:5:7
namedValue a id: 13 attr: 0x0 <test>:5:7
- const id: 15 value: 13 <test>:5:9
+ BinOp id: 16 op: * (30) left: 15 right: 17 <test>:5:12
+ const id: 15 value: 13 <test>:5:9
+ const id: 17 value: 14 <test>:5:14
Expr id: 24 succ: 0 expr: 20 <test>:6:7
- BinOp id: 20 op: = (5) left: 19 right: 21 <test>:6:7
+ BinOp id: 20 op: = (5) left: 19 right: 22 <test>:6:7
namedValue a id: 19 attr: 0x0 <test>:6:7
- const id: 21 value: 15 <test>:6:9
+ BinOp id: 22 op: / (28) left: 21 right: 23 <test>:6:12
+ const id: 21 value: 15 <test>:6:9
+ const id: 23 value: 16 <test>:6:14
-Int a;
---aa;
-aa++;
-a--+3*4
+Int a = 1;
+Int b = 100;
+--a;
+b++;
+a--*++b**(8-3);
+a=b=(a+(b-2)*3)
= <test> (module) parent: global
== Classes:
== Variables:
== Body:
-varDef a (Int) id: 1 succ: 0 attr: 0x0 <test>:1:4
+varDef a (Int) id: 1 succ: 3 attr: 0x0 <test>:1:4
+ const id: 2 value: 1 <test>:1:8
+varDef b (Int) id: 3 succ: 7 attr: 0x0 <test>:2:4
+ const id: 4 value: 100 <test>:2:8
+Expr id: 7 succ: 10 expr: 5 <test>:2:13
+ Unary 5 op: -- (41) Child: 6 <test>:2:13
+ namedValue a id: 6 attr: 0x0 <test>:3:3
+Expr id: 10 succ: 20 expr: 9
+ Unary 9 op: ++ (40) Child: 8
+ namedValue b id: 8 attr: 0x0 <test>:4:1
+Expr id: 20 succ: 32 expr: 13 <test>:5:3
+ BinOp id: 13 op: * (30) left: 12 right: 16 <test>:5:3
+ Unary 12 op: -- (41) Child: 11
+ namedValue a id: 11 attr: 0x0 <test>:5:1
+ BinOp id: 16 op: ** (31) left: 14 right: 18 <test>:5:7
+ Unary 14 op: ++ (40) Child: 15 <test>:5:4
+ namedValue b id: 15 attr: 0x0 <test>:5:7
+ BinOp id: 18 op: - (27) left: 17 right: 19 <test>:5:11
+ const id: 17 value: 8 <test>:5:10
+ const id: 19 value: 3 <test>:5:12
+Expr id: 32 succ: 0 expr: 22 <test>:6:1
+ BinOp id: 22 op: = (5) left: 21 right: 24 <test>:6:1
+ namedValue a id: 21 attr: 0x0 <test>:6:1
+ BinOp id: 24 op: = (5) left: 23 right: 26 <test>:6:3
+ namedValue b id: 23 attr: 0x0 <test>:6:3
+ BinOp id: 26 op: + (26) left: 25 right: 30 <test>:6:6
+ namedValue a id: 25 attr: 0x0 <test>:6:6
+ BinOp id: 30 op: * (30) left: 28 right: 31 <test>:6:12
+ BinOp id: 28 op: - (27) left: 27 right: 29 <test>:6:9
+ namedValue b id: 27 attr: 0x0 <test>:6:9
+ const id: 29 value: 2 <test>:6:10
+ const id: 31 value: 3 <test>:6:13
--- /dev/null
+Int a;
+repeat
+a++;
+until a != 2 * 3;
+= <test> (module) parent: global
+== Classes:
+== Variables:
+== Body:
+varDef a (Int) id: 1 succ: 2 attr: 0x0 <test>:1:4
+repeat id: 2 condition: 7 body: 5 <test>:1:7
+ Expr id: 5 succ: 0 expr: 4
+ Unary 4 op: ++ (40) Child: 3
+ namedValue a id: 3 attr: 0x0 <test>:3:1
+ BinOp id: 7 op: != (20) left: 6 right: 9 <test>:4:8
+ namedValue a id: 6 attr: 0x0 <test>:4:8
+ BinOp id: 9 op: * (30) left: 8 right: 10 <test>:4:13
+ const id: 8 value: 2 <test>:4:11
+ const id: 10 value: 3 <test>:4:15
public:
void testRplASException() {
try{
- RplSourcePosition pos(&m_unit, 1, 2);
- throw RplASException(&pos, "simple string: %s", "Hi");
+ m_reader.addSource("<main>", "12");
+ m_source.addReader(&m_reader);
+ m_source.addSourceUnit(m_reader.currentSourceUnit());
+ const RplSourcePosition* pos = m_source.newPosition(2);
+ throw RplASException(pos, "simple string: %s", "Hi");
checkF(true);
} catch (RplASException exc){
- checkE("<main>-1 (2): simple string: Hi", exc.getMessage().constData());
+ checkE("<main>:0:2: simple string: Hi", exc.getMessage().constData());
}
}
void testRplASVariant(){
checkAST("repeatTest.txt", __LINE__);
}
void forCTest(){
- setSource("Int a;\nfor b from 1 to 10 step 2 do\na += 1;\nod");
+ setSource("Int a;\nfor b from 10 to 1 step -2 do\na += 1;\nod");
RplMFParser parser(m_source, m_tree);
parser.parse();
checkAST("forC1.txt", __LINE__);
checkAST("forC2.txt", __LINE__);
}
void opTest(){
- setSource("--aa;\naa++;\na--+3*4");
+ checkE(25, RplMFParser::O_QUESTION);
+ checkE(37, RplMFParser::O_RSHIFT2);
+ checkE(41, RplMFParser::O_DEC);
+ checkE(48, RplMFParser::O_RBRACE);
+ setSource("Int a = 1;\nInt b = 100;\n--a;\nb++;\na--*++b**(8-3);\na=b=(a+(b-2)*3)");
RplMFParser parser(m_source, m_tree);
parser.parse();
checkAST("opTest1.txt", __LINE__);
}
+ void forItTest(){
+ setSource("Map a;\nfor x in a do\na += 1;\nod");
+ RplMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("forIt1.txt", __LINE__);
+ }
virtual void doIt(void) {
+ forCTest();
+ forItTest();
opTest();
ifTest();
whileTest();
repeatTest();
- forCTest();
defTest();
baseTest();
}