]> gitweb.hamatoma.de Git - reqt/commitdiff
day's work
authorhama <hama@siduction.net>
Thu, 3 Jul 2014 17:27:54 +0000 (19:27 +0200)
committerhama <hama@siduction.net>
Thu, 3 Jul 2014 17:27:54 +0000 (19:27 +0200)
rplexpr/rplasclasses.cpp
rplexpr/rplasclasses.hpp
rplexpr/rplastree.cpp
rplexpr/rplastree.hpp
rplexpr/rpllexer.cpp
rplexpr/rplmfparser.cpp
rplexpr/rplmfparser.hpp
rplexpr/rplsource.cpp
rplexpr/rplsource.hpp
unittests/rplmfparser_test.cpp

index 9edd3408c90d21c9d58a22f9ae6a15d8eb2a597e..3f24a0da63a7faf3af7d9454bdb63f09335a6e10 100644 (file)
@@ -16,6 +16,7 @@ RplASFloat RplASFloat::m_instance;
 RplASInteger RplASInteger::m_instance;
 RplASString RplASString::m_instance;
 RplASBoolean RplASBoolean::m_instance;
+RplASVoid RplASVoid::m_instance;
 
 /** @class RplSymbolSpace rplastree.hpp "rplexpr/rplastree.hpp"
  *
@@ -64,6 +65,7 @@ RplSymbolSpace::RplSymbolSpace(RplSymbolSpace::SymbolSpaceType type,
         m_classes[RplASString::m_instance.name()] = &RplASString::m_instance;
         m_classes[RplASList::m_instance.name()] = &RplASList::m_instance;
         m_classes[RplASMap::m_instance.name()] = &RplASMap::m_instance;
+        m_classes[RplASVoid::m_instance.name()] = &RplASVoid::m_instance;
     }
 }
 
@@ -126,7 +128,7 @@ void RplSymbolSpace::dump(FILE* fp, int indent, const char* header)
     QList<QString>::iterator it2;
     for (it2 = sorted.begin(); it2 != sorted.end(); it2++){
         RplASClass* clazz = m_classes[*it2];
-        clazz->dump(fp, indent + 1);
+        clazz->dump(fp, indent);
     }
 
     fprintf(fp, "%s== Variables:\n", tabs);
@@ -140,11 +142,11 @@ void RplSymbolSpace::dump(FILE* fp, int indent, const char* header)
     QList<QString>::iterator it4;
     for (it4 = sorted.begin(); it4 != sorted.end(); it4++){
         RplVariable* var = m_variables[*it4];
-        var->dump(fp, indent + 1);
+        var->dump(fp, indent);
     }
     fprintf(fp, "%s== Body:%s\n", tabs, m_body == NULL ? " <none>" : "");
     if (m_body != NULL)
-        m_body->dump(fp, indent + 1);
+        m_body->dump(fp, indent);
 }
 
 /**
@@ -710,3 +712,59 @@ void RplVariable::dump(FILE* fp, int indent)
            name1.constData(),
            name2.constData(), val.constData());
 }
+
+/** @class RplVariable rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements a data type representing a none type.
+ */
+RplASVoid::RplASVoid() :
+    RplASClass("Void")
+{
+}
+
+/**
+ * @brief Instantiates a new object.
+ *
+ * In this case we do nothing.
+ *
+ * @param source    ignored
+ * @return
+ */
+void*RplASVoid::newValueInstance(void*) const
+{
+    return NULL;
+}
+
+/**
+ * @brief Destroys an object created by newValueInstance.
+ *
+ * In this case we do nothing.
+ *
+ * @param object    object to
+ * @return
+ */
+void RplASVoid::destroyValueInstance(void* object) const
+{
+}
+
+/**
+ * @brief Returns the bool value of the given object
+ * @param object    ignored
+ * @return          false
+ */
+bool RplASVoid::boolValueOf(void*) const
+{
+    return false;
+}
+
+/**
+ * @brief Converts the object into a string.
+ *
+ * @param object    ignored
+ * @param maxLength ignored
+ * @return          the empty string
+ */
+QString RplASVoid::toString(void*, int) const
+{
+    return QString("");
+}
index 5b6481cc4255f34577935b5ba247c17305700308..f4bf4335c9420d56314a1c5c59e88d0814f5ed9c 100644 (file)
@@ -139,6 +139,17 @@ public:
     static RplASMap m_instance;
 };
 
+class RplASVoid : public RplASClass {
+public:
+    RplASVoid();
+public:
+    void* newValueInstance(void* source = NULL) const;
+    void destroyValueInstance(void* object) const;
+    virtual bool boolValueOf(void* object) const;
+    virtual QString toString(void *object, int maxLength = 80) const;
+public:
+    static RplASVoid m_instance;
+};
 
 
 #endif // RPLASCLASSES_HPP
index 428304a260482790497016f68cd332b510c184d4..49724606747b38bbe4099052027314c068ebcf82 100644 (file)
@@ -239,9 +239,9 @@ const QString* RplASVariant::asString() const
 {
     const RplASClass* clazz;
     const QString* rc = static_cast<const QString*>(asObject(&clazz));
-    if (clazz->name() != "String"){
+    if (clazz != &RplASString::m_instance){
         const QString& name = clazz->name();
-        throw RplException("RplASVariant::asString: not an string: %s",
+        throw RplException("RplASVariant::asString: not a string: %s",
                            name.toUtf8().constData());
     }
     return rc;
@@ -568,6 +568,9 @@ void RplASVarDefinition::dump(FILE* fp, int indent)
         m_successor->dump(fp, indent);
 }
 
+/**
+ * @brief Executes the statement.
+ */
 void RplASVarDefinition::execute()
 {
     //@ToDo
@@ -582,6 +585,57 @@ void RplASVarDefinition::calc(RplASVariant&)
 {
 }
 
+/** @class RplASExprStatement rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements an statement consisting of an expression
+ */
+
+/**
+ * @brief Constructor.
+ */
+RplASExprStatement::RplASExprStatement() :
+    RplASNode1(AST_EXPR_STATEMENT),
+    RplASStatement()
+{
+}
+
+/**
+ * @brief Executes the statement.
+ */
+void RplASExprStatement::execute()
+{
+
+}
+
+/**
+ * @brief Calculates the value of the expression.
+ *
+ * @param value     OUT: the calculated value
+ */
+void RplASExprStatement::calc(RplASVariant& value)
+{
+
+}
+
+/**
+ * @brief Writes the internals into a file.
+ *
+ * @param fp        target file
+ * @param indent    nesting level
+ */
+
+void RplASExprStatement::dump(FILE* fp, int indent)
+{
+    DEFINE_TABS(indent);
+    fprintf(fp, "%sExpr id: %d succ: %d expr: %d\n", tabs, m_id,
+            m_successor == NULL ? 0 : m_successor->id(),
+            m_child == NULL ? 0 : m_child->id() );
+    if (m_child != NULL)
+        m_child->dump(fp, indent + 1);
+    if (m_successor != NULL)
+        m_successor->dump(fp, indent);
+}
+
 /** @class RplASNode1 rplastree.hpp "rplexpr/rplastree.hpp"
  *
  * @brief Implements a inner node of the abstract syntax tree with one child.
@@ -1214,6 +1268,9 @@ void RplASMethodCall::dump(FILE* fp, int indent)
         m_child->dump(fp, indent + 1);
 }
 
+/**
+ * @brief Executes the statement.
+ */
 void RplASMethodCall::execute()
 {
 }
@@ -1344,7 +1401,7 @@ void RplASMethod::dump(FILE* fp, int indent)
  * @brief Implements an argument of a method for the Abstract Syntax Tree.
  */
 /**
- * @brief RplASArgument::RplASArgument
+ * @brief constructor
  */
 RplASArgument::RplASArgument() :
     RplASNode2(AST_ARGUMENT),
index 63b08a2ac86689b49770016bbea57bb075ad89a2..7c64dcc84c063eb4d204a0e49095164646a4c819 100644 (file)
@@ -15,6 +15,7 @@ enum RplASItemType {
     AST_CONSTANT,
     AST_NAMED_VALUE,
     AST_VAR_DEFINITION,
+    AST_EXPR_STATEMENT,
     AST_METHOD,
     AST_ARGUMENT,
     AST_INTRINSIC_METHOD,
@@ -37,7 +38,8 @@ public:
     RplASException();
     RplASException(const RplSourcePosition* position, const char* message, ...);
 protected:
-    void build(const RplSourcePosition* position, const char* format, va_list varList);
+    void build(const RplSourcePosition* position, const char* format,
+               va_list varList);
 };
 
 class RplASClass;
@@ -253,6 +255,16 @@ public:
     void dump(FILE* fp, int indent);
 };
 
+class RplASExprStatement : public RplASNode1, public RplASStatement
+{
+public:
+    RplASExprStatement();
+public:
+    virtual void execute();
+    virtual void calc(RplASVariant& value);
+    void dump(FILE* fp, int indent);
+};
+
 class RplASUnaryOp : public RplASNode1
 {
 public:
index 82a0f8aeef1b0591cb79f0ae5e0df746decc1c8e..a13b0113feb365cbba16e526aff97d32fd198bb0 100644 (file)
@@ -845,73 +845,77 @@ RplToken* RplLexer::nextToken()
                 ? &m_position2 : &m_position1;
     } else {
         m_currentToken->clear();
-        m_currentPosition->setLineNo(m_source->currentReader()
-                ->currentSourceUnit()->lineNo());
-        m_currentPosition->setColumn(m_currentCol);
-        if (! fillInput()){
+        RplReader* reader = m_source->currentReader();
+        if (reader == NULL)
             m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE;
-        } else {
-            QChar cc = m_input.at(0);
-            int cc2 = cc.unicode();
-            if (cc.isSpace()){
-                m_currentToken->m_tokenType = TOKEN_SPACE;
-                ix = 1;
-                while(ix < m_input.size() && m_input.at(ix).isSpace())
-                    ix++;
-                if (m_storageFlags & STORE_BLANK){
-                    m_currentToken->m_string.append(m_input.mid(0, ix));
-                }
-                m_currentCol += ix;
-                m_input.remove(0, ix);
-                rc = m_currentToken;
-            } else if (cc.isDigit()){
-                rc = scanNumber();
-            } else if ( (cc2 == '"' && (m_stringFeatures & SF_QUOTE) != 0)
-                       || (cc2 == '\'' && (m_stringFeatures & SF_TICK) != 0)){
-                rc = scanString();
+        else {
+            m_currentPosition->setLineNo(reader->currentSourceUnit()->lineNo());
+            m_currentPosition->setColumn(m_currentCol);
+            if (! fillInput()){
+                m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE;
             } else {
-                if (cc2 >= CHAR_INFO_SIZE)
-                    throw RplLexException(*m_currentPosition,
-                        "no lexical symbol can start with this char: %lc",
-                        cc);
-                else
-                {
-                    if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_COMMENT_START)){
-                        rc = findTokenWithId(TOKEN_COMMENT_START,
-                                             CC_2nd_COMMENT_START, m_commentStarts);
-                        if (rc != NULL)
-                            scanComment();
+                QChar cc = m_input.at(0);
+                int cc2 = cc.unicode();
+                if (cc.isSpace()){
+                    m_currentToken->m_tokenType = TOKEN_SPACE;
+                    ix = 1;
+                    while(ix < m_input.size() && m_input.at(ix).isSpace())
+                        ix++;
+                    if (m_storageFlags & STORE_BLANK){
+                        m_currentToken->m_string.append(m_input.mid(0, ix));
                     }
+                    m_currentCol += ix;
+                    m_input.remove(0, ix);
+                    rc = m_currentToken;
+                } else if (cc.isDigit()){
+                    rc = scanNumber();
+                } else if ( (cc2 == '"' && (m_stringFeatures & SF_QUOTE) != 0)
+                           || (cc2 == '\'' && (m_stringFeatures & SF_TICK) != 0)){
+                    rc = scanString();
+                } else {
+                    if (cc2 >= CHAR_INFO_SIZE)
+                        throw RplLexException(*m_currentPosition,
+                            "no lexical symbol can start with this char: %lc",
+                            cc);
+                    else
+                    {
+                        if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_COMMENT_START)){
+                            rc = findTokenWithId(TOKEN_COMMENT_START,
+                                                 CC_2nd_COMMENT_START, m_commentStarts);
+                            if (rc != NULL)
+                                scanComment();
+                        }
 
-                    if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_OP)){
-                        if ( (m_charInfo[cc2] & CC_OP_1_ONLY) == 0){
-                            rc = findTokenWithId(TOKEN_OPERATOR,
-                                             CC_2nd_OP, m_operators);
-                        } else {
+                        if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_OP)){
+                            if ( (m_charInfo[cc2] & CC_OP_1_ONLY) == 0){
+                                rc = findTokenWithId(TOKEN_OPERATOR,
+                                                 CC_2nd_OP, m_operators);
+                            } else {
+                                rc = m_currentToken;
+                                rc->m_tokenType = TOKEN_OPERATOR;
+                                rc->m_value.m_id = findInVector(1, m_operators);
+                                m_input.remove(0, 1);
+                                m_currentCol += 1;
+                            }
+                        }
+                        if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_KEYWORD)){
+                            rc = findTokenWithId(TOKEN_KEYWORD,
+                                                 CC_2nd_KEYWORD, m_keywords);
+                        }
+                        if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_ID)){
+                            int length = 1;
+                            while(length < m_input.size()
+                                && (cc2 = m_input[length].unicode()) < CHAR_INFO_SIZE
+                                    && (m_charInfo[cc2] & CC_REST_ID) != 0)
+                                  length++;
                             rc = m_currentToken;
-                            rc->m_tokenType = TOKEN_OPERATOR;
-                            rc->m_value.m_id = findInVector(1, m_operators);
-                            m_input.remove(0, 1);
-                            m_currentCol += 1;
+                            rc->m_tokenType = TOKEN_ID;
+                                  rc->m_string.append(m_input.mid(0, length));
+                            m_input.remove(0, length);
+                            m_currentCol += length;
                         }
-                    }
-                    if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_KEYWORD)){
-                        rc = findTokenWithId(TOKEN_KEYWORD,
-                                             CC_2nd_KEYWORD, m_keywords);
-                    }
-                    if (rc == NULL && (m_charInfo[cc2] & CC_FIRST_ID)){
-                        int length = 1;
-                        while(length < m_input.size()
-                            && (cc2 = m_input[length].unicode()) < CHAR_INFO_SIZE
-                                && (m_charInfo[cc2] & CC_REST_ID) != 0)
-                              length++;
-                        rc = m_currentToken;
-                        rc->m_tokenType = TOKEN_ID;
-                              rc->m_string.append(m_input.mid(0, length));
-                        m_input.remove(0, length);
-                        m_currentCol += length;
-                    }
 
+                    }
                 }
             }
         }
index f3a4203fc646683fb50ac797d733c3001c8ef371..bf2268dc32f47579803ada7b49849d28bb1e1f27 100644 (file)
@@ -318,6 +318,21 @@ RplASItem* RplMFParser::parseExpr()
     return rc;
 }
 
+/**
+ * @brief Parses an expression as a statement.
+ *
+ * @return the abstract syntax tree of the expression statement
+ */
+RplASItem* RplMFParser::parseExprStatement()
+{
+    RplSourcePosition *pos = m_lexer.currentPosition();
+    RplASItem* item = parseExpr();
+    RplASExprStatement* statement = new RplASExprStatement();
+    statement->setPosition(pos);
+    statement->setChild(item);
+    return statement;
+}
+
 /**
  * @brief Parses the body.
  *
@@ -340,7 +355,7 @@ RplASItem* RplMFParser::parseBody()
             case TOKEN_REAL:
             case TOKEN_OPERATOR:
                 m_lexer.undoLastToken();
-                item = parseExpr();
+                item = parseExprStatement();
                 break;
             case TOKEN_KEYWORD:
                 switch (token->id()){
@@ -380,7 +395,7 @@ RplASItem* RplMFParser::parseBody()
                     item = parseVarDefinition(K_UNDEF);
                 } else {
                     m_lexer.undoLastToken();
-                    item = parseExpr();
+                    item = parseExprStatement();
                 }
                 break;
             }
index c888be05a40677674d289d91da93c6af8747c99e..d0d7daa1d63be99bc9bad0e78a54f5575f68c9fd 100644 (file)
@@ -17,14 +17,12 @@ public:
         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_CLASS, K_ENDC, K_ENDF, K_FUNCTION, K_GENERATOR, K_IMPORT,
-        K_CONST, K_LAZY, K_INT, K_FLOAT, K_BOOL, K_NONE, K_TRUE, K_FALSE
+        K_CONST, K_LAZY, K_NONE, K_TRUE, K_FALSE
          };
-#define IS_KEYWORD_BEHIND_EXPR(o) (o==K_THEN||o==K_DO||o==K_FROM||o==K_OF \
-    ||o==K_ENDF||o==K_ENDC)
 #define MF_KEYWORDS "if then else fi while do od repeat until" \
     " for from to step case of esac leave continue pass" \
     " class endc endf func generator import" \
-    " const lazy None True False"
+    " 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,
@@ -82,6 +80,7 @@ public:
     void parseImport();
     RplASItem* parseModule(const QString& name);
     void parse();
+    RplASItem*parseExprStatement();
 protected:
     RplASArgument* parseArguments();
     RplASItem* parseOperand(int level);
index 850c63c32cc81c682a533721c5e8278fea0034d2..f7837dec74802be477488690309a1080e215c6ae 100644 (file)
@@ -240,12 +240,23 @@ RplReader::RplReader(RplSource& source) :
 /**
  * @brief Destructor.
  */
-RplReader::~RplReader() {
+RplReader::~RplReader()
+{
+    clear();
+}
+
+/**
+ * @brief Frees the resources.
+ */
+void RplReader::clear()
+{
     QMap<QString, RplSourceUnit*>::iterator it;
     for(it = m_units.begin(); it != m_units.end(); it++) {
         RplStringSourceUnit* unit = (RplStringSourceUnit*)(*it);
         delete unit;
     }
+    m_units.clear();
+    m_currentSourceUnit = NULL;
 }
 
 /**
@@ -429,11 +440,11 @@ void RplSource::pushSourceUnit(RplSourceUnit* unit) {
  *                  otherwise: the last entry from the source unit stack
  */
 RplSourceUnit* RplSource::popSourceUnit(RplReader* reader) {
+    RplSourceUnit* rc = NULL;
     if(m_unitStack.size() > 0)
         m_unitStack.pop();
     m_currentReader = m_unitStack.size() <= 0
                       ? NULL : m_unitStack.top()->reader();
-    RplSourceUnit* rc = NULL;
     if(m_currentReader == reader)
         rc = m_unitStack.top();
     else {
@@ -538,6 +549,7 @@ RplStringReader::RplStringReader(RplSource& source) :
  * @brief Destructor.
  */
 RplStringReader::~RplStringReader() {
+    clear();
 }
 
 /**
@@ -569,8 +581,11 @@ RplSourceUnit* RplStringReader::openSourceUnit(const QString& unit) {
  */
 bool RplStringReader::nextLine(int maxSize, QString& buffer,
                                      bool& hasMore) {
-    m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1);
-    bool rc = fillBuffer(maxSize, buffer, hasMore);
+    bool rc = m_currentSourceUnit != NULL;
+    if (rc){
+        m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1);
+        rc = fillBuffer(maxSize, buffer, hasMore);
+    }
     return rc;
 }
 
index e341f44798a1bec8288e21da9c034ff57d82e65f..b9684b380b4ad1dccbb404129bcdcc87b029adf5 100644 (file)
@@ -92,6 +92,7 @@ public:
      */
     virtual bool fillBuffer(int maxSize, QString& buffer, bool& hasMore) = 0;
 public:
+    virtual void clear();
     RplSource& source();
     RplSourceUnit* currentSourceUnit() const;
     bool setCurrentSourceUnit(const QString& currentSourceUnit);
index 6fe622e88dee11c1d19354ad0ad64a7343492291..011652a65847b5934d926326bde55129bf8eff66 100644 (file)
@@ -22,14 +22,14 @@ public:
         m_tree(),
         m_reader(m_source)
     {
-        m_reader.addSource("<test>", "");
         m_source.addReader(&m_reader);
     }
 protected:
     void setSource(const char* content){
         m_tree.clear();
         m_source.clear();
-        m_reader.replaceSource("<test>", content);
+        m_reader.clear();
+        m_reader.addSource("<test>", content);
         m_source.addReader(&m_reader);
         m_source.addSourceUnit(m_reader.currentSourceUnit());
     }