From c10a06f4fc3bb3f19cbf73679677803bacf14d65 Mon Sep 17 00:00:00 2001 From: hama Date: Sun, 27 Jul 2014 12:38:14 +0200 Subject: [PATCH] dayly work --- rplexpr/rplasclasses.cpp | 95 +++++++++++++++++++++++++--- rplexpr/rplasclasses.hpp | 12 +++- rplexpr/rplastree.cpp | 123 ++++++++++++++++++++++++++++++++----- rplexpr/rplastree.hpp | 25 ++++++-- rplexpr/rplmfparser.cpp | 67 ++++++++++++-------- rplexpr/rplmfparser.hpp | 6 +- rplexpr/rplparser.cpp | 19 ++++++ rplexpr/rplparser.hpp | 2 + test/rplmfparser/meth1.txt | 13 +++- test/rplmfparser/meth2.txt | 49 ++++++++++++++- 10 files changed, 344 insertions(+), 67 deletions(-) diff --git a/rplexpr/rplasclasses.cpp b/rplexpr/rplasclasses.cpp index 2dc394e..0b4ce34 100644 --- a/rplexpr/rplasclasses.cpp +++ b/rplexpr/rplasclasses.cpp @@ -76,12 +76,13 @@ RplSymbolSpace::RplSymbolSpace(RplSymbolSpace::SymbolSpaceType type, */ RplSymbolSpace::~RplSymbolSpace() { - QMap::iterator it; - for (it = m_variables.begin(); it != m_variables.end(); it++){ + ClassMap::iterator it; + for (it = m_classes.begin(); it != m_classes.end(); it++){ delete it.value(); } - for (it = m_variables.begin(); it != m_variables.end(); it++){ - delete it.value(); + MethodMap::iterator it2; + for (it2 = m_methods.begin(); it2 != m_methods.end(); it2++){ + delete it2.value(); } } @@ -133,19 +134,34 @@ void RplSymbolSpace::dump(FILE* fp, int indent, const char* header) clazz->dump(fp, indent); } - fprintf(fp, "%s== Variables:\n", tabs); + fprintf(fp, "%s== Methods:\n", tabs); sorted.clear(); sorted.reserve(m_variables.size()); - VariableMap::iterator it3; - for (it3 = m_variables.begin(); it3 != m_variables.end(); it3++){ + MethodMap::iterator it3; + for (it3 = m_methods.begin(); it3 != m_methods.end(); it3++){ sorted.append(it3.key()); } qSort(sorted.begin(), sorted.end(), qLess()); QList::iterator it4; for (it4 = sorted.begin(); it4 != sorted.end(); it4++){ - RplVariable* var = m_variables[*it4]; + RplASMethod* var = m_methods[*it4]; + var->dump(fp, indent); + } + + fprintf(fp, "%s== Variables:\n", tabs); + sorted.clear(); + sorted.reserve(m_variables.size()); + VariableMap::iterator it5; + for (it5 = m_variables.begin(); it5 != m_variables.end(); it5++){ + sorted.append(it5.key()); + } + qSort(sorted.begin(), sorted.end(), qLess()); + QList::iterator it6; + for (it6 = sorted.begin(); it6 != sorted.end(); it6++){ + RplASVarDefinition* var = m_variables[*it6]; var->dump(fp, indent); } + fprintf(fp, "%s== Body:%s\n", tabs, m_body == NULL ? " " : ""); RplASNode1::dumpStatements(fp, indent, m_body); } @@ -181,6 +197,17 @@ const char*RplSymbolSpace::spaceTypeName(RplSymbolSpace::SymbolSpaceType type) } return rc; } +/** + * @brief Returns the parent of the symbol space. + * + * @return the symbolspace of the object (module, method, class..) containing + * the object belonging to the instance + */ +RplSymbolSpace* RplSymbolSpace::parent() const +{ + return m_parent; +} + /** * @brief Returns the body (a abstract syntax tree) of the symbol space. * @@ -202,12 +229,62 @@ void RplSymbolSpace::setBody(RplASItem* body) m_body = body; } +/** + * @brief Adds a variable to the symbol space. + * + * @param variable the variable to add + * @return NULL: success
+ * otherwise: the already defined variable/method + */ +RplASItem* RplSymbolSpace::addVariable(RplASVarDefinition* variable) +{ + RplASItem* rc = NULL; + const QString& name = variable->name(); + if (m_variables.contains(name)) + rc = m_variables[name]; + else if (m_methods.contains(name)) + rc = m_methods[name]; + else { + m_variables[name] = variable; + } + return rc; +} + +/** + * @brief Adds a method to the symbol space. + * + * @param method the method to add + * @return NULL: success
+ * otherwise: the already defined variable/method + */ +RplASItem* RplSymbolSpace::addMethod(RplASMethod* method) +{ + RplASItem* rc = NULL; + const QString& name = method->name(); + if (m_variables.contains(name)) + rc = m_variables[name]; + else if (! m_methods.contains(name)){ + m_methods[name] = method; + } else { + RplASMethod* oldMethod = m_methods[name]; + do { + if (oldMethod->equalSignature(*method)) + rc = oldMethod; + else + oldMethod = oldMethod->sibling(); + } while (rc == NULL && oldMethod != NULL); + if (rc == NULL) + m_methods[name] = method; + } + return rc; +} + /** * @brief Returns the name of the symbol space. * * @return the name */ -QString RplSymbolSpace::name() const +const QString& RplSymbolSpace::name() const { return m_name; } diff --git a/rplexpr/rplasclasses.hpp b/rplexpr/rplasclasses.hpp index d1f7d97..fdb21c5 100644 --- a/rplexpr/rplasclasses.hpp +++ b/rplexpr/rplasclasses.hpp @@ -37,19 +37,23 @@ public: }; public: - typedef QMap VariableMap; + typedef QMap VariableMap; typedef QMap ClassMap; + typedef QMap MethodMap; public: RplSymbolSpace(SymbolSpaceType type, const QString& name, RplSymbolSpace* parent); - ~RplSymbolSpace(); + virtual ~RplSymbolSpace(); public: RplVariable* findVariable(const QString& name) const; RplASClass* findClass(const QString& name) const; void dump(FILE* fp, int indent, const char* header = NULL); - QString name() const; + const QString& name() const; RplASItem* body() const; void setBody(RplASItem* body); + RplASItem* addVariable(RplASVarDefinition* variable); + RplASItem* addMethod(RplASMethod* method); + RplASClass* addClass(RplASClass* clazz); public: static void initGlobal(RplSymbolSpace& global); static const char* spaceTypeName(SymbolSpaceType type); @@ -58,10 +62,12 @@ private: QString m_name; VariableMap m_variables; ClassMap m_classes; + MethodMap m_methods; RplSymbolSpace* m_parent; RplASItem* m_body; public: static RplSymbolSpace m_global; + RplSymbolSpace* parent() const; }; class RplASBoolean : public RplASClass { diff --git a/rplexpr/rplastree.cpp b/rplexpr/rplastree.cpp index 2df3291..70a1791 100644 --- a/rplexpr/rplastree.cpp +++ b/rplexpr/rplastree.cpp @@ -716,7 +716,7 @@ RplASNamedValue::RplASNamedValue(RplASClass* dataType, * * @return the name */ -QString RplASNamedValue::name() const +const QString& RplASNamedValue::name() const { return m_name; } @@ -743,6 +743,15 @@ void RplASNamedValue::dump(FILE* fp, int indent) m_name.toUtf8().constData(), m_id, m_attributes, positionStr(buffer, sizeof buffer)); } +/** + * @brief Returns the data type (class) of the instance. + * + * @return the data type + */ +RplASClass* RplASNamedValue::dataType() const +{ + return m_dataType; +} /** @class RplASIndexedValue rplastree.hpp "rplexpr/rplastree.hpp" * @@ -815,6 +824,30 @@ void RplASVarDefinition::dump(FILE* fp, int indent) m_child3->dump(fp, indent + 1); } +/** + * @brief Returns the name of the variable. + * + * @return the name + */ +const QString& RplASVarDefinition::name() const +{ + RplASNamedValue* namedValue = dynamic_cast(m_child2); + const QString& rc = namedValue == NULL ? "?" : namedValue->name(); + return rc; +} + +/** + * @brief Returns the data type (class) of the variable. + * + * @return the data type + */ +RplASClass* RplASVarDefinition::datatype() const +{ + RplASNamedValue* namedValue = dynamic_cast(m_child2); + RplASClass* rc = namedValue->dataType(); + return rc; +} + /** * @brief Executes the statement. */ @@ -1641,6 +1674,17 @@ RplASClass::RplASClass(const QString& name) : { } +/** + * @brief Destructor. + * + * Does nothing but forces a virtual destructor of all derived classes. + * + */ +RplASClass::~RplASClass() +{ + +} + /** * @brief Return the class name. * @@ -1781,9 +1825,10 @@ void RplASTree::finishModule(const QString& name) /** * @brief Handles the start of a new class definition. - * @param name + * @param name name of the class/method + * @return the new symbol space */ -void RplASTree::startClassOrMethod(const QString& name, +RplSymbolSpace* RplASTree::startClassOrMethod(const QString& name, RplSymbolSpace::SymbolSpaceType type) { // the stack m_modules is never empty because of "global" and modules. @@ -1794,6 +1839,7 @@ void RplASTree::startClassOrMethod(const QString& name, m_symbolSpaceHeap[fullName] = space; m_symbolSpaces.append(space); m_currentSpace = space; + return space; } /** @@ -2036,14 +2082,17 @@ void RplASBinaryOp::dump(FILE* fp, int indent) * @param name the method name * @param type the method result type */ -RplASMethod::RplASMethod(const QString& name) : +RplASMethod::RplASMethod(const QString& name, RplASTree& tree) : RplASNode2(AST_METHOD), m_name(name), m_resultType(NULL), - m_parent(NULL) + m_symbols(tree.startClassOrMethod(name, RplSymbolSpace::SST_METHOD)), + m_sibling(NULL), + m_tree(tree) { } + /** * @brief Writes the internals of the instance into a file. * @@ -2057,34 +2106,74 @@ void RplASMethod::dump(FILE* fp, int indent) fprintf(fp, "%sMethod %s %s(", tabs, m_resultType == NULL ? "" : m_resultType->name().toUtf8().constData(), m_name.toUtf8().constData()); - fprintf(fp, ") id: %d parent: %d args: %d body: %d %s\n", m_id, - m_parent == NULL ? 0 : m_parent->id(), + RplSymbolSpace* parent = m_symbols->parent(); + fprintf(fp, ") id: %d parent: %s args: %d body: %d %s\n", m_id, + parent == NULL ? "" : parent->name().toUtf8().constData(), m_child2 == NULL ? 0 : m_child2->id(), m_child->id(), positionStr(buffer, sizeof buffer)); if (m_child2 != NULL) m_child2->dump(fp, indent + 1); - m_child->dump(fp, indent + 1); + dumpStatements(fp, indent + 1, m_child); +} +RplSymbolSpace* RplASMethod::symbols() const +{ + return m_symbols; } /** - * @brief Returns the parent of the method: a class or a method. - * @return NULL: this is a function, not a method
- * otherwise: the parent: a class or a method/func + * @brief Returns the name of the method + * @return the name */ -RplASItem* RplASMethod::parent() const + +const QString& RplASMethod::name() const { - return m_parent; + return m_name; } + /** - * @brief Sets the parent of the method. + * @brief Tests whether an other method has the same signature (parameterlist). + * @param other the method for comparison + * @return true: same signature
+ * false: otherwise + */ +bool RplASMethod::equalSignature(RplASMethod& other) const +{ + bool rc = true; + RplASExprStatement* args = dynamic_cast(m_child2); + RplASExprStatement* otherArgs = dynamic_cast(other.child2()); + + while(rc && (args != NULL || otherArgs != NULL)){ + if (args == NULL || otherArgs == NULL) + rc = false; + else { + RplASVarDefinition* def = dynamic_cast(args->child2()); + RplASVarDefinition* defOther = dynamic_cast(otherArgs->child2()); + if (def->datatype() != defOther->datatype()) + rc = false; + } + } + return rc; +} +/** + * @brief Returns the next overloaded method. * - * @param parent the parent: NULL or a class or a method + * @return NULL: no other method available
+ * otherwise: the next method with the same name but another signature */ -void RplASMethod::setParent(RplASItem* parent) +RplASMethod* RplASMethod::sibling() const { - m_parent = parent; + return m_sibling; } +/** + * @brief Sets the next overloaded method. + * + * @param sibling another method with the same name but another signature + */ +void RplASMethod::setSibling(RplASMethod* sibling) +{ + m_sibling = sibling; +} /** @class RplASArgument rplastree.hpp "rplexpr/rplastree.hpp" * diff --git a/rplexpr/rplastree.hpp b/rplexpr/rplastree.hpp index fbb8cc5..26487d0 100644 --- a/rplexpr/rplastree.hpp +++ b/rplexpr/rplastree.hpp @@ -299,10 +299,12 @@ public: RplASNamedValue(RplASClass* dataType, const QString& name, int attributes); public: - QString name() const; + const QString& name() const; public: virtual void calc(RplASVariant& value); void dump(FILE* fp, int indent); + RplASClass* dataType() const; + protected: QString m_name; int m_attributes; @@ -333,6 +335,8 @@ public: virtual void execute(); virtual void calc(RplASVariant& value); void dump(FILE* fp, int indent); + const QString& name() const; + RplASClass* datatype() const; }; class RplASExprStatement : public RplASNode2, public RplASStatement @@ -474,20 +478,28 @@ private: class RplASClass; +class RplSymbolSpace; class RplASMethod : public RplASNode2 { public: - RplASMethod(const QString& name); + RplASMethod(const QString& name, RplASTree& tree); public: void execute(); void dump(FILE* fp, int indent); - RplASItem* parent() const; - void setParent(RplASItem* parent); + RplSymbolSpace* symbols() const; + + const QString& name() const; + bool equalSignature(RplASMethod& other) const; + RplASMethod* sibling() const; + void setSibling(RplASMethod* sibling); private: QString m_name; RplASClass* m_resultType; - RplASItem* m_parent; + RplSymbolSpace* m_symbols; + // chain over all overloaded methods (same name, other signature): + RplASMethod* m_sibling; + RplASTree& m_tree; }; class RplASClass { @@ -495,6 +507,7 @@ public: typedef QMap MethodMap; public: RplASClass(const QString& name); + virtual ~RplASClass(); public: /** * @brief Creates a value object (used in RplASVariant). @@ -559,7 +572,7 @@ public: public: bool startModule(const QString& name); void finishModule(const QString& name); - void startClassOrMethod(const QString& name, + RplSymbolSpace* startClassOrMethod(const QString& name, RplSymbolSpace::SymbolSpaceType type); void finishClassOrMethod(const QString& name); SymbolSpaceStack& symbolSpaces(); diff --git a/rplexpr/rplmfparser.cpp b/rplexpr/rplmfparser.cpp index e15e695..08a2624 100644 --- a/rplexpr/rplmfparser.cpp +++ b/rplexpr/rplmfparser.cpp @@ -55,7 +55,9 @@ enum MFLocations{ L_PARSE_PARAMLIST_NO_PARENTH, L_PARSE_PARAMLIST_NO_PARENTH2, L_PARSE_METH_NO_END = 2045, - L_PARSE_METH_NO_END2 + L_PARSE_METH_NO_END2, + L_PARSE_VAR_DEF_ALREADY_DEFINED, + L_PARSE_VAR_DEF_ALREADY_DEFINED2 }; /** @class RplMFParser rpllexer.hpp "rplexpr/rplmfparser.hpp" @@ -153,8 +155,8 @@ RplASItem* RplMFParser::parseRepeat() * * for in do od * - * @post the token behind the do is read - * @return the abstract syntax tree of the for statement + * @post the token behind the do is read + * @return the abstract syntax tree of the for statement */ RplASItem* RplMFParser::parseFor() { @@ -249,6 +251,11 @@ RplASItem* RplMFParser::parseVarDefinition(RplASNamedValue::Attributes attribute rc->setChild3(value); token = m_lexer.currentToken(); } + RplSymbolSpace* symbols = m_tree.currentSpace(); + RplASItem* oldSymbol = symbols->addVariable(rc); + if (oldSymbol != NULL) + error(L_PARSE_VAR_DEF_ALREADY_DEFINED, oldSymbol->position(), + "symbol already defined", "previous definition"); return rc; } @@ -532,7 +539,7 @@ RplASItem* RplMFParser::parseOperand(int level, RplASItem* parent) } else if (opId == O_LPARENTH){ rc = parseExpr(level + 1); token = m_lexer.currentToken(); - if(! token->isOperator(O_RPARENT)){ + if(! token->isOperator(O_RPARENTH)){ // this call never comes back (exception!) syntaxError(L_PARSE_OPERAND_RPARENTH, "')' expected", "(", startPosition); @@ -588,7 +595,7 @@ RplASItem* RplMFParser::parseOperand(int level, RplASItem* parent) rc = call; token = m_lexer.nextNonSpaceToken(); - if (! token->isOperator(O_RPARENT)){ + if (! token->isOperator(O_RPARENTH)){ m_lexer.undoLastToken(); RplASArgument* args = parseArguments(); call->setChild2(args); @@ -792,11 +799,11 @@ RplASItem* RplMFParser::parseBody(Keyword keywordStop, Keyword keywordStop2, item = parseFor(); break; case K_CLASS: - item = parseClass(); + parseClass(); break; case K_FUNCTION: case K_GENERATOR: - item = parseMethodDefinition(NULL); + parseMethod(); break; case K_IMPORT: parseImport(); @@ -827,7 +834,7 @@ RplASItem* RplMFParser::parseBody(Keyword keywordStop, Keyword keywordStop2, default: break; } - if (again){ + if (again && item != NULL){ if (body == NULL){ body = item; } else { @@ -898,7 +905,7 @@ RplASExprStatement* RplMFParser::parseParameterList(){ } last = current; } while(m_lexer.currentToken()->isOperator(O_COMMA)); - if (! m_lexer.currentToken()->isOperator(O_RPARENT)) + if (! m_lexer.currentToken()->isOperator(O_RPARENTH)) syntaxError(L_PARSE_PARAMLIST_NO_PARENTH, ") expected", ")", startPos); m_lexer.nextNonSpaceToken(); return rc; @@ -907,13 +914,15 @@ RplASExprStatement* RplMFParser::parseParameterList(){ /** * @brief Parses a class definition. * - * @pre token "func" is read - * @post token behind "endf" is read - * @return the node in an abstract syntax tree + * The method definition will be stored in the symbol space of the parent + * + * @pre token "func" is read + * @post token behind "endf" is read + * @return NULL */ -RplASMethod*RplMFParser::parseMethodDefinition(RplASItem* parent) +void RplMFParser::parseMethod() { - RplASMethod* rc = NULL; + RplASMethod* method = NULL; const RplSourcePosition* startPos = m_lexer.currentPosition(); RplToken* token = m_lexer.nextNonSpaceToken(); if (! token->isTokenType(TOKEN_ID)) @@ -932,37 +941,43 @@ RplASMethod*RplMFParser::parseMethodDefinition(RplASItem* parent) token = m_lexer.nextNonSpaceToken(); if (! token->isOperator(O_LPARENTH, O_COLON)) syntaxError(L_PARSE_METH_NO_LPARENTH, "'(' or ':' expected"); - RplASExprStatement* parameterList; + + RplASExprStatement* parameterList = NULL; + method = new RplASMethod(name, m_tree); + method->setPosition(startPos); + RplSymbolSpace* symbols = m_tree.currentSpace(); + symbols->addMethod(method); + if (token->isOperator(O_LPARENTH)){ token = m_lexer.nextNonSpaceToken(); - if (token->isOperator(O_RPARENT)){ + if (token->isOperator(O_RPARENTH)){ token = m_lexer.nextNonSpaceToken(); } else { parameterList = parseParameterList(); + method->setChild2(parameterList); } } if (! token->isOperator(O_COLON)) syntaxError(L_PARSE_METH_NO_COLON, "':' expected"); - rc = new RplASMethod(name); - rc->setParent(parent); - rc->setPosition(startPos); - rc->setChild2(parameterList); - rc->setChild(parseBody(K_ENDF)); + + method->setChild(parseBody(K_ENDF)); if (! m_lexer.currentToken()->isKeyword(K_ENDF)) syntaxError(L_PARSE_METH_NO_END, "end of function not found", "endf", startPos); m_lexer.nextNonSpaceToken(); - return rc; + m_tree.finishClassOrMethod(name); } /** * @brief Parses a class definition. * @return the node in an abstract syntax tree */ -RplASItem*RplMFParser::parseClass() +void RplMFParser::parseClass() { - RplASItem* rc = NULL; - return rc; + //RplASItem* clazz = NULL; + QString name = ""; + + m_tree.finishClassOrMethod(name); } /** @@ -1021,7 +1036,7 @@ RplASArgument* RplMFParser::parseArguments() bool again = false; do { RplASItem* expr = parseExpr(0); - if (! m_lexer.currentToken()->isOperator(O_COMMA, O_RPARENT)) + if (! m_lexer.currentToken()->isOperator(O_COMMA, O_RPARENTH)) syntaxError(L_PARSE_ARGS_NO_COMMA_OR_PARENT, "',' or ')' expected"); again = m_lexer.currentToken()->isOperator(O_COMMA); RplASArgument* current = new RplASArgument(); diff --git a/rplexpr/rplmfparser.hpp b/rplexpr/rplmfparser.hpp index dcee6ec..0530f47 100644 --- a/rplexpr/rplmfparser.hpp +++ b/rplexpr/rplmfparser.hpp @@ -42,7 +42,7 @@ public: 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 + O_DOT, O_LPARENTH, O_RPARENTH, 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)) @@ -75,8 +75,8 @@ public: RplASItem* parseExpr(int depth); RplASItem* parseBody(Keyword keywordStop, Keyword keywordStop2 = K_UNDEF, Operator opStop = O_UNDEF, Operator opStop2 = O_UNDEF); - RplASMethod*parseMethodDefinition(RplASItem* parent); - RplASItem* parseClass(); + void parseMethod(); + void parseClass(); void parseImport(); RplASItem* parseModule(const QString& name); void parse(); diff --git a/rplexpr/rplparser.cpp b/rplexpr/rplparser.cpp index bc9bcd6..4ed24f8 100644 --- a/rplexpr/rplparser.cpp +++ b/rplexpr/rplparser.cpp @@ -188,6 +188,25 @@ void RplParser::error(int location, const char* format, ...) if (++m_errors >= m_maxErrors) throw RplParserStop("too many errors"); } +/** + * @brief Adds an error message with an additional info message. + * + * If too much errors an exception will be thrown to stop parsing. + * + * @param location unique id of the error/warning message + * @param position source position of the additional message + * @param message describes the error + * @param message2 the additional message + * @param ... optional: the variable argument list + */ +void RplParser::error(int location, const RplSourcePosition* position, + const char* message, const char* message2) +{ + addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message); + addSimpleMessage(LT_INFO, location + 1, position, message2); + if (++m_errors >= m_maxErrors) + throw RplParserStop("too many errors"); +} /** * @brief Adds a warning message. diff --git a/rplexpr/rplparser.hpp b/rplexpr/rplparser.hpp index 5b40149..8e22aa5 100644 --- a/rplexpr/rplparser.hpp +++ b/rplexpr/rplparser.hpp @@ -48,6 +48,8 @@ public: void syntaxError(int location, const char* message, const char* symbol, const RplSourcePosition* position); void error(int location, const char* format, ...); + void error(int location, const RplSourcePosition* position, + const char* message, const char* message2); void warning(int location, const char* format, ...); protected: diff --git a/test/rplmfparser/meth1.txt b/test/rplmfparser/meth1.txt index 70435a3..f0ef7ac 100644 --- a/test/rplmfparser/meth1.txt +++ b/test/rplmfparser/meth1.txt @@ -3,5 +3,14 @@ func Float pi: 3.1415; endf func Str delim(): '/' endf; == Classes: == Variables: == Body: -Method 1 pi() body: 4 args: 36816 :0:0 -Method 4 delim() body: 0 args: 36816 :1:28 +Method pi() id: 1 parent: 0 args: 0 body: 4 :0:0 + Method delim() id: 4 parent: 0 args: 0 body: 6 :1:28 + Expr id: 6 expr: 5 succ: 0 :1:46 + const id: 5 value: '/' :1:46 + Expr id: 6 expr: 5 succ: 0 :1:46 + const id: 5 value: '/' :1:46 +Method delim() id: 4 parent: 0 args: 0 body: 6 :1:28 + Expr id: 6 expr: 5 succ: 0 :1:46 + const id: 5 value: '/' :1:46 +Expr id: 6 expr: 5 succ: 0 :1:46 + const id: 5 value: '/' :1:46 diff --git a/test/rplmfparser/meth2.txt b/test/rplmfparser/meth2.txt index ef65275..df66892 100644 --- a/test/rplmfparser/meth2.txt +++ b/test/rplmfparser/meth2.txt @@ -5,4 +5,51 @@ rc endf == Classes: == Variables: == Body: -Method 4 fac() body: 0 args: 3 :0:55 +Method fac() id: 4 parent: 0 args: 3 body: 6 :0:55 + Expr id: 3 expr: 2 succ: 0 + varDef n id: 2 namedValue: 1 value: 0 succ: 0 :1:23 + namedValue n id: 1 attr: 0x22 :1:23 + varDef rc id: 6 namedValue: 5 value: 0 succ: 7 :2:4 + namedValue rc id: 5 attr: 0x0 :2:4 + If id: 7 condition: 9 then: 14 else: 24 succ: 26:2:8 + BinOp id: 9 op: <= (23) left: 8 right: 10 :2:14 + namedValue rc id: 8 attr: 0x0 :2:14 + const id: 10 value: 1 :2:17 + Expr id: 14 expr: 12 succ: 0 :2:27 + BinOp id: 12 op: = (5) left: 11 right: 13 :2:27 + namedValue rc id: 11 attr: 0x0 :2:27 + const id: 13 value: 1 :2:29 + Expr id: 24 expr: 16 succ: 0 :2:39 + BinOp id: 16 op: = (5) left: 15 right: 18 :2:39 + namedValue rc id: 15 attr: 0x0 :2:39 + BinOp id: 18 op: * (30) left: 17 right: 19 :2:42 + namedValue n id: 17 attr: 0x0 :2:42 + call fac Id: 19 args: 23 parent: 0 succ: 0 :2:46 + arg 1 id: 23 expr: 21 succ: 0 + BinOp id: 21 op: - (27) left: 20 right: 22 :2:48 + namedValue n id: 20 attr: 0x0 :2:48 + const id: 22 value: 1 :2:49 + Expr id: 26 expr: 25 succ: 0 :3:3 + namedValue rc id: 25 attr: 0x0 :3:3 +varDef rc id: 6 namedValue: 5 value: 0 succ: 7 :2:4 + namedValue rc id: 5 attr: 0x0 :2:4 +If id: 7 condition: 9 then: 14 else: 24 succ: 26:2:8 + BinOp id: 9 op: <= (23) left: 8 right: 10 :2:14 + namedValue rc id: 8 attr: 0x0 :2:14 + const id: 10 value: 1 :2:17 + Expr id: 14 expr: 12 succ: 0 :2:27 + BinOp id: 12 op: = (5) left: 11 right: 13 :2:27 + namedValue rc id: 11 attr: 0x0 :2:27 + const id: 13 value: 1 :2:29 + Expr id: 24 expr: 16 succ: 0 :2:39 + BinOp id: 16 op: = (5) left: 15 right: 18 :2:39 + namedValue rc id: 15 attr: 0x0 :2:39 + BinOp id: 18 op: * (30) left: 17 right: 19 :2:42 + namedValue n id: 17 attr: 0x0 :2:42 + call fac Id: 19 args: 23 parent: 0 succ: 0 :2:46 + arg 1 id: 23 expr: 21 succ: 0 + BinOp id: 21 op: - (27) left: 20 right: 22 :2:48 + namedValue n id: 20 attr: 0x0 :2:48 + const id: 22 value: 1 :2:49 +Expr id: 26 expr: 25 succ: 0 :3:3 + namedValue rc id: 25 attr: 0x0 :3:3 -- 2.39.5