]> gitweb.hamatoma.de Git - reqt/commitdiff
dayly work
authorhama <hama@siduction.net>
Sun, 3 Aug 2014 21:18:45 +0000 (23:18 +0200)
committerhama <hama@siduction.net>
Sun, 3 Aug 2014 21:18:45 +0000 (23:18 +0200)
rplexpr/rplasclasses.cpp
rplexpr/rplasclasses.hpp
rplexpr/rplastree.cpp
rplexpr/rplastree.hpp
rplexpr/rplmfparser.cpp
rplexpr/rplvm.cpp
rplexpr/rplvm.hpp
rplexpr/rplvm_test.cpp [new file with mode: 0644]
unittests/main.cpp
unittests/rplmfparser_test.cpp
unittests/unittests.pro

index 62772d33c90216109a96f5fbd06544f23f771c1f..c8c5fc8af2280af94f904a030ec8028af824dc22 100644 (file)
@@ -206,6 +206,16 @@ const char*RplSymbolSpace::spaceTypeName(RplSymbolSpace::SymbolSpaceType type)
     }
     return rc;
 }
+/**
+ * @brief Returns the list of the variables.
+ *
+ * @return the list of the variables
+ */
+RplSymbolSpace::VariableList RplSymbolSpace::listOfVars() const
+{
+    return m_listOfVars;
+}
+
 /**
  * @brief Returns the parent of the symbol space.
  *
@@ -290,6 +300,24 @@ RplASItem* RplSymbolSpace::addMethod(RplASMethod* method)
     }
     return rc;
 }
+/**
+ * @brief Adds a class to the instance.
+ *
+ * @param clazz     the class to add
+ * @return          NULL: success<br>
+ *                  otherwise: the already defined class
+ */
+RplASUserClass* RplSymbolSpace::addClass(RplASUserClass* clazz)
+{
+    RplASUserClass* rc = NULL;
+    const QString& name = clazz->name();
+    if (m_classes.contains(name)){
+        rc = dynamic_cast<RplASUserClass*>(m_classes[name]);
+    } else {
+        m_classes[name] = clazz;
+    }
+    return rc;
+}
 
 /**
  * @brief Returns the name of the symbol space.
@@ -929,8 +957,11 @@ QString RplASFormula::toString(void* object, int) const
  *
  * @param name      name of the user defined class
  */
-RplASUserClass::RplASUserClass(const QString& name, RplASTree& tree) :
-    RplASClass(name, tree)
+RplASUserClass::RplASUserClass(const QString& name,
+                               const RplSourcePosition* position,
+                               RplASTree& tree) :
+    RplASClass(name, tree),
+    m_position(position)
 {
 }
 
@@ -972,10 +1003,20 @@ bool RplASUserClass::boolValueOf(void* object) const
  * @param maxLength     maximum length of the string
  * @return
  */
-QString RplASUserClass::toString(void* object, int maxLength) const
+QString RplASUserClass::toString(void*, int) const
 {
     return m_name;
 }
+/**
+ * @brief Returns the source position of the instance.
+ *
+ * @return  the source position
+ */
+const RplSourcePosition* RplASUserClass::position() const
+{
+    return m_position;
+}
+
 
 
 /** @class RplASUserObject rplastree.hpp "rplexpr/rplastree.hpp"
index d0798bf57ae0c90670abf9a238dcb11ce557856a..888d5ac4dbcb520d599e149c6ce0b359488dbbb7 100644 (file)
@@ -25,6 +25,7 @@ protected:
     RplASClass* m_type;
 };
 
+class RplASUserClass;
 class RplSymbolSpace
 {
 public:
@@ -40,6 +41,7 @@ public:
     typedef QMap<QString, RplASVarDefinition*> VariableMap;
     typedef QMap<QString, RplASClass*> ClassMap;
     typedef QMap<QString, RplASMethod*> MethodMap;
+    typedef QList<RplASVarDefinition*> VariableList;
 public:
     RplSymbolSpace(SymbolSpaceType type, const QString& name,
                    RplSymbolSpace* parent);
@@ -53,7 +55,9 @@ public:
     void setBody(RplASItem* body);
     RplASItem* addVariable(RplASVarDefinition* variable);
     RplASItem* addMethod(RplASMethod* method);
-    RplASClass* addClass(RplASClass* clazz);
+    RplASUserClass* addClass(RplASUserClass* clazz);
+    RplSymbolSpace* parent() const;
+    VariableList listOfVars() const;
 public:
     static void initGlobal(RplSymbolSpace& global);
     static const char* spaceTypeName(SymbolSpaceType type);
@@ -65,9 +69,10 @@ private:
     MethodMap m_methods;
     RplSymbolSpace* m_parent;
     RplASItem* m_body;
+    VariableList m_listOfVars;
+
 public:
     static RplSymbolSpace m_global;
-    RplSymbolSpace* parent() const;
 };
 
 class RplASBoolean : public RplASClass {
@@ -167,12 +172,17 @@ public:
 
 class RplASUserClass : public RplASClass {
 public:
-    RplASUserClass(const QString& name, RplASTree& tree);
+    RplASUserClass(const QString& name, const RplSourcePosition* position,
+                   RplASTree& tree);
 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;
+    const RplSourcePosition* position() const;
+
+private:
+    const RplSourcePosition* m_position;
 };
 
 class RplASUserObject {
index 763da66ccf6915ca4d0c9d12be9b6bb5842b6cd3..8b1638ae74f0cf0d3b9bfe74dfc1534243ca0da2 100644 (file)
@@ -477,16 +477,38 @@ RplASItemType RplASItem::nodeType() const
 {
     return m_nodeType;
 }
-
-/** @class RplASExpr rplastree.hpp "rplexpr/rplastree.hpp"
+/**
+ * @brief Returns the flags of the node.
  *
- * @brief Implements the abstract base class of value containing items.
+ * @return  the bitmask with the flags
+ */
+int RplASItem::flags() const
+{
+    return m_flags;
+}
+/**
+ * @brief Sets the flags of the node.
  *
+ * @param flags     the new value of the bitmask
  */
-RplASCalculable::RplASCalculable()
+void RplASItem::setFlags(int flags)
 {
+    m_flags = flags;
 }
 
+
+/** @class RplASCalculable rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief An abstract base class for items which calculates a value.
+ *
+ */
+
+/** @class RplASStorable rplastree.hpp "rplexpr/rplastree.hpp"
+ *
+ * @brief Implements the abstract base class of value containing items.
+ *
+ */
+
 /** @class RplASConstant rplastree.hpp "rplexpr/rplastree.hpp"
  *
  * @brief Implements a constant for the Abstract Syntax Tree.
@@ -506,11 +528,13 @@ RplASConstant::RplASConstant() :
 /**
  * @brief Calculates the expression.
  *
- * @param value     OUT: the calculated value
+ * @param value     IN/OUT: the calculated value
+ * @return          NULL
  */
-void RplASConstant::calc(RplASVariant& value)
+RplASNode1* RplASConstant::calc(RplASVariant& value)
 {
     value = m_value;
+    return NULL;
 }
 
 /**
@@ -573,11 +597,13 @@ RplASListOfVariants* RplASListConstant::list(){
 /**
  * @brief Calculates the expression.
  *
- * @param value     OUT: the calculated value
+ * @param value     IN/OUT: the calculated value
+ * @return          NULL
  */
-void RplASListConstant::calc(RplASVariant& value)
+RplASNode1* RplASListConstant::calc(RplASVariant& value)
 {
     value = m_value;
+    return NULL;
 }
 
 /**
@@ -631,11 +657,14 @@ RplASMapConstant::RplASMapConstant() :
 /**
  * @brief Calculates the value.
  *
- * @param value     OUT: the value of the instance
+ * @param value     IN/OUT: the value of the instance
+ * @return          NULL
  */
-void RplASMapConstant::calc(RplASVariant&)
+RplASNode1* RplASMapConstant::calc(RplASVariant& value)
 {
-
+    // ToDo: copy map:
+    //value = m_value;
+    return NULL;
 }
 /**
  * @brief Writes the internals into a file.
@@ -723,11 +752,12 @@ const QString& RplASNamedValue::name() const
 /**
  * @brief Calculates the value.
  *
- * @param value     OUT: the value of the instance
+ * @param value     In/OUT: the value of the instance
+ * @return          NULL
  */
-void RplASNamedValue::calc(RplASVariant& )
+RplASNode1* RplASNamedValue::calc(RplASVariant& value, RplStackFrame* frame)
 {
-
+    return NULL;
 }
 /**
  * @brief Writes the internals into a file.
@@ -859,10 +889,12 @@ void RplASVarDefinition::execute()
 /**
  * @brief Calculates the initialation value while interpreting.
  *
- * @param value     OUT: ignored
+ * @param value     IN/OUT: ignored
+ * @return          NULL
  */
-void RplASVarDefinition::calc(RplASVariant&)
+RplASNode1* RplASVarDefinition::calc(RplASVariant&)
 {
+    return NULL;
 }
 
 /** @class RplASExprStatement rplastree.hpp "rplexpr/rplastree.hpp"
@@ -893,10 +925,12 @@ void RplASExprStatement::execute()
 /**
  * @brief Calculates the value of the expression.
  *
- * @param value     OUT: the calculated value
+ * @param value     IN/OUT: the calculated value
+ * @return          NULL
  */
-void RplASExprStatement::calc(RplASVariant& )
+RplASNode1* RplASExprStatement::calc(RplASVariant& )
 {
+    return NULL;
 }
 
 /**
@@ -1279,18 +1313,22 @@ RplASCondition::RplASCondition() :
 {
 }
 
-void RplASCondition::calc(RplASVariant& value)
+/**
+ * @brief Calculates the value of the condition
+ * @param value     IN/OUT: the bool value of the condition
+ * @return          NULL
+ */
+RplASNode1* RplASCondition::calc(RplASVariant& value)
 {
     value.setBool(false);
     RplASCalculable* node = dynamic_cast<RplASCalculable*>(m_child);
     if (node == NULL)
         throw RplASException(m_position, "child of condition is not calculable");
     node->calc(value);
+    return NULL;
 }
 /**
  * @brief Calculates the boolean value and returns it.
- *
- * @return the boolean value of the expression
  */
 bool RplASCondition::calcAsBool()
 {
index 9937bb5b7d7422196e451b90862fae5814f1a45c..4ff89a8dc0be084b7f68137d39b7326d1f9f1cce 100644 (file)
@@ -112,10 +112,12 @@ class RplASItem
 public:
     enum NodeFlags {
         NF_UNDEF,
-        /// Debugger: this node is a breakpoint
-        NF_BREAKPOINT           = 1 << 1,
+        /// the node calculates a value:
+        VF_CALCULABLE   = 1 << 1,
         /// the tree under this node is complete checked for data type correctness
-        NF_TYPECHECK_COMPLETE   = 1 << 2
+        NF_TYPECHECK_COMPLETE   = 1 << 2,
+        /// debugger: this node is a breakpoint
+        NF_BREAKPOINT           = 1 << 5
     };
 
 public:
@@ -140,6 +142,9 @@ public:
     static void reset();
     RplASItemType nodeType() const;
 
+    int flags() const;
+    void setFlags(int flags);
+
 protected:
     unsigned int m_id:16;
     RplASItemType m_nodeType:8;
@@ -150,12 +155,17 @@ private:
     static unsigned int m_nextId;
 };
 
+class RplASNode1;
 class RplASCalculable
 {
 public:
-    RplASCalculable();
+    virtual RplASNode1* calc(RplASVariant& value) = 0;
+};
+
+class RplStackFrame;
+class RplASStorable{
 public:
-    virtual void calc(RplASVariant& value) = 0;
+    virtual RplASNode1* calc(RplASVariant& value, RplStackFrame* frame) = 0;
 };
 
 class RplASConstant : public RplASItem, public RplASCalculable
@@ -163,7 +173,7 @@ class RplASConstant : public RplASItem, public RplASCalculable
 public:
     RplASConstant();
 public:
-    virtual void calc(RplASVariant& value);
+    virtual RplASNode1* calc(RplASVariant& value);
 public:
     virtual void dump(FILE* fp, int indent);
     RplASVariant& value();
@@ -171,6 +181,7 @@ private:
     RplASVariant m_value;
 };
 
+
 class RplASNode1 : public RplASItem
 {
 public:
@@ -255,7 +266,7 @@ class RplASListConstant : public RplASNode1, public RplASCalculable
 public:
     RplASListConstant();
 public:
-    virtual void calc(RplASVariant& value);
+    virtual RplASNode1* calc(RplASVariant& value);
 public:
     virtual void dump(FILE* fp, int indent);
     RplASVariant& value();
@@ -268,7 +279,7 @@ class RplASMapConstant : public RplASNode1, public RplASCalculable
 public:
     RplASMapConstant();
 public:
-    virtual void calc(RplASVariant& value);
+    virtual RplASNode1* calc(RplASVariant& value);
 public:
     virtual void dump(FILE* fp, int indent);
     RplASVariant& value();
@@ -277,7 +288,7 @@ private:
     RplASVariant m_value;
 };
 
-class RplASNamedValue : public RplASNode1, public RplASCalculable
+class RplASNamedValue : public RplASNode1, public RplASStorable
 {
 public:
     enum Attributes {
@@ -301,7 +312,7 @@ public:
 public:
     const QString& name() const;
 public:
-    virtual void calc(RplASVariant& value);
+    virtual RplASNode1* calc(RplASVariant& value, RplStackFrame* frame);
     void dump(FILE* fp, int indent);
     RplASClass* dataType() const;
 
@@ -333,7 +344,7 @@ public:
     RplASVarDefinition();
 public:
     virtual void execute();
-    virtual void calc(RplASVariant& value);
+    virtual RplASNode1* calc(RplASVariant& value);
     void dump(FILE* fp, int indent);
     const QString& name() const;
     RplASClass* datatype() const;
@@ -345,7 +356,7 @@ public:
     RplASExprStatement();
 public:
     virtual void execute();
-    virtual void calc(RplASVariant& value);
+    virtual RplASNode1* calc(RplASVariant& value);
     void dump(FILE* fp, int indent);
 };
 
@@ -377,7 +388,7 @@ class RplASCondition : public RplASNode1, public RplASCalculable
 public:
     RplASCondition();
 public:
-    void calc(RplASVariant& value);
+    RplASNode1* calc(RplASVariant& value);
     bool calcAsBool();
     void dump(FILE* fp, int indent);
 };
index cf9350f4a2b6d2dfe7bc352ec2b97e114bff847d..14e07e74581e182f0001b1578aaeeb83c3813aa3 100644 (file)
@@ -59,7 +59,9 @@ enum MFLocations{
     L_PARSE_VAR_DEF_ALREADY_DEFINED,
     L_PARSE_VAR_DEF_ALREADY_DEFINED2,
     L_PARSE_CLASS_NO_NAME,
-    L_PARSE_CLASS_LOWERCASE = 2050
+    L_PARSE_CLASS_LOWERCASE = 2050,
+    L_PARSE_CLASS_ALREADY_DEFINED,
+    L_PARSE_CLASS_ALREADY_DEFINED2
 
 };
 
@@ -988,9 +990,13 @@ void RplMFParser::parseClass()
     if (! token->isCapitalizedId())
         syntaxError(L_PARSE_CLASS_LOWERCASE, "class name must start with an uppercase character");
     QString name = token->toString();
-    RplASUserClass* clazz = new RplASUserClass(name, m_tree);
+    RplASUserClass* clazz = new RplASUserClass(name, startPos, m_tree);
     RplSymbolSpace* parent = m_tree.currentSpace();
-    parent->addClass(clazz);
+    RplASUserClass* alreadyDefined = parent->addClass(clazz);
+    if (alreadyDefined != NULL){
+        error(L_PARSE_CLASS_ALREADY_DEFINED, alreadyDefined->position(),
+              "class already defined", "previous defined class");
+    }
     m_tree.startClassOrMethod(name, RplSymbolSpace::SST_CLASS);
     clazz->setSymbols();
 
index 8e351c41c7497a0ee286a8b6ea45439da2ff5db9..e63779c284e692b96f8c96b292ffd80f56bea619 100644 (file)
 #include "rplcore/rplcore.hpp"
 #include "rplexpr/rplexpr.hpp"
 
+/** @class RplVmException rplvm.hpp "rplexpr/rplvm.hpp"
+ *
+ * @brief Implements an exception for the virtual machine.
+ *
+ */
+/**
+ * @brief Constructor
+ * @param format    the message with placeholders
+ * @param ...       the values for the placeholders
+ */
+RplVmException::RplVmException(const char* format, ...) :
+    RplException("")
+{
+    char buffer[16000];
+    va_list ap;
+    va_start(ap, format);
+    vsnprintf(buffer, sizeof buffer, format, ap);
+    va_end(ap);
+    m_message = buffer;
+}
 
+/** @class RplStackFrame rplvm.hpp "rplexpr/rplvm.hpp"
+ *
+ * @brief Implements the storage for a symbol space.
+ *
+ * The owner of a symbol space can be "global", a module, a class, or a method.
+ * Some symbol spaces have more than one stack frame, e.g. a recursive called
+ * method.
+ */
+
+
+/**
+ * @brief Constructor.
+ *
+ * @param symbols   the symbol space belonging to the stack frame
+ */
+
+RplStackFrame::RplStackFrame(RplSymbolSpace* symbols) :
+    m_countVariables(symbols->listOfVars().size()),
+    m_variables(NULL),
+    m_symbols(symbols)
+{
+    if (m_countLocals > 0)
+        m_variables = new RplASVariant[m_countVariables];
+}
+
+/**
+ * @brief Destructor.
+ */
+RplStackFrame::~RplStackFrame()
+{
+    delete[] m_variables;
+    m_variables = NULL;
+}
+
+/**
+ * @brief Returns the storage of a variable given by the index.
+ *
+ * @param index the index of the variable
+ *
+ * @return      the storage of the variable
+ */
+RplASVariant& RplStackFrame::valueOfVariable(int index)
+{
+    if (index < 0 || index >= m_countVariables)
+        throw RplVmException("valueOfVariable(): invalid index: %d", index);
+    return *m_listOfVariables[index];
+}
+
+/** @class RplVMThread rplvm.hpp "rplexpr/rplvm.hpp"
+ *
+ * @brief Implements a thread of the virtual machine.
+ *
+ * The virtual machine can execute many threads at the same time.
+ * Each thread has its own stack.
+ */
+
+/**
+ * @brief Constructor.
+ *
+ * @param maxStack  the maximal number of nested stack frames
+ * @param vm        the parent, the virtual machine
+ */
+RplVMThread::RplVMThread(int maxStack, RplVirtualMachine* vm) :
+    m_singleStep(false),
+    m_debugMode(false),
+    m_maxStack(maxStack),
+    m_stack(),
+    m_currentValue(),
+    m_vm(vm)
+{
+    m_stack.reserve(maxStack);
+}
+
+/**
+ * @brief Executes a statement list.
+ *
+ * @param statements    the first statement of a statement list chained by
+ *                      <code>m_child</code>
+ * @param space         the current symbol space
+ */
+void RplVMThread::execute(RplASNode1* statements, RplSymbolSpace* space)
+{
+    bool debugMode = m_debugMode;
+    while(statements != NULL){
+        if (debugMode
+                && (m_singleStep || (statement->flags() & NF_BREAKPOINT) != 0))
+            debug(statements);
+        RplASCalculable* statement = dynamic_cast<RplASCalculable*>(statements);
+        statement->calc(&m_currentValue);
+    }
+}
+
+/**
+ * @brief Handles a debugger break.
+ *
+ * @param statement the current statement (not yet executed)
+ */
+void RplVMThread::debug(RplASNode1* statement)
+{
+
+}
+
+/** @class RplVirtualMachine rplvm.hpp "rplexpr/rplvm.hpp"
+ *
+ * @brief Implements a virtual machine.
+ *
+ * This is a execution unit which interprets an abstract syntax tree.
+ */
+RplVirtualMachine::RplVirtualMachine(RplASTree* tree, RplSource* source,
+                                     int maxStack) :
+    m_maxStack(maxStack),
+    m_threads(),
+    m_flags(VF_UNDEF),
+    m_source(source),
+    m_tree(tree)
+{
+    m_threads.reserve(8);
+}
+
+/**
+ * @brief Adds a thread to the instance.
+ *
+ * @param program   the statement list to execute
+ * @param space     the current symbol space
+ * @param maxStack  the maximal number of nested stack frames.
+ *                  <= 0: use the default
+ */
+void RplVirtualMachine::addThread(RplASItem* program, RplSymbolSpace* space,
+                                  int maxStack)
+{
+    RplVMThread* thread = new RplVMThread(
+                maxThread <= 0 ? m_maxStack : maxStack, self);
+    m_threads.append(thread);
+    thread->execute(program, space);
+}
+/**
+ * @brief Tests whether a given flag is set.
+ *
+ * @param flag      flag to test
+ * @return          true: the flag is set<br>
+ *                  false: otherwise
+ */
+bool RplVirtualMachine::hasFlag(RplVirtualMachine::VMFlag flag) const
+{
+    bool rc = (m_flags & flag) != 0;
+}
+/**
+ * @brief Adds a flag to the current flags.
+ *
+ * @param flag
+ * @return
+ */
+void RplVirtualMachine::setFlag(RplVirtualMachine::VMFlag flag)
+{
+    m_flag |= flag;
+}
+
+/**
+ * @brief Adds a flag to the current flags.
+ *
+ * @param flag
+ * @return
+ */
+void RplVirtualMachine::clearFlag(RplVirtualMachine::VMFlag flag)
+{
+    m_flag &= ~flag;
+}
index c8f8d62a9c03c9cb8442c07d89c8e72b59975a5f..2fa0a07dc9aa96ecf3ec84392751b80285ae919e 100644 (file)
 #ifndef RPLVM_HPP
 #define RPLVM_HPP
 
+class RplVmException : public RplException {
+public:
+    RplVmException(const char* message, ...);
+};
 class RplStackFrame {
 public:
-    RplStackFrame(int countArgs, int countLocals);
+    RplStackFrame(RplSymbolSpace* symbols);
     ~RplStackFrame();
 public:
+    RplASVariant& valueOfVariable(int index);
 private:
+    int m_countVariables;
     RplASVariant* m_variables;
+    RplSymbolSpace* m_symbols;
 };
 
-class RPLVirtualMachine
+class RplVirtualMachine;
+class RplVMThread
 {
 public:
-    RPLVirtualMachine();
+    typedef QList<RplStackFrame*> StackFrameList;
+public:
+    RplVMThread(int maxStack, RplVirtualMachine* vm);
+public:
+    void execute(RplASNode1* statements, RplSymbolSpace* space);
+    virtual void debug(RplASNode1* statement);
+protected:
+    bool m_debugMode;
+    bool m_singleStep;
+    int m_maxStack;
+    StackFrameList m_stack;
+    RplASVariant m_currentValue;
+    RplVirtualMachine* m_vm;
+};
+
+class RplVirtualMachine
+{
+public:
+    enum VMFlag {
+        VF_UNDEF,
+        VF_TRACE_STATEMENTS     = 1<<1,
+        VF_TRACE_LOCALS         = 1<<2,
+        VF_TRACE_AUTO_VARIABLES = 1<<3
+
+    };
+
+public:
+    RplVirtualMachine(RplASTree& tree, RplSource& source, int maxStack = 1024);
 public:
-    void calc();
+    void addThread(RplASItem* program, RplSymbolSpace* space, int maxStack = 0);
+    bool hasFlag(VMFlag flag) const;
+    void setFlag(VMFlag flag);
+    void clearFlag(VMFlag flag);
 private:
-    RplStackFrame m_global;
-    QMap<QString, RplSymbolSpace*> m_modules;
-    QList<RplStackFrame*> m_stack;
+    int m_maxStack;
+    QList<RplVMThread*> m_threads;
+    int m_flags;
+    RplSource& m_source;
+    RplASTree& m_tree;
 };
 
 #endif // RPLVM_HPP
diff --git a/rplexpr/rplvm_test.cpp b/rplexpr/rplvm_test.cpp
new file mode 100644 (file)
index 0000000..d3acb7f
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+#include "rplcore/rplcore.hpp"
+#include "rplexpr/rplexpr.hpp"
+#include "rplcore/rpltest.hpp"
+
+class TestRplVM : public RplTest{
+private:
+    RplSource m_source;
+    RplASTree m_tree;
+    RplStringReader m_reader;
+    const char* m_currentSource;
+public:
+    TestRplVM() :
+        RplTest("RplVM"),
+        m_source(),
+        m_tree(),
+        m_reader(m_source)
+    {
+        m_source.addReader(&m_reader);
+    }
+protected:
+    void setSource(const char* content){
+        RplASItem::reset();
+        m_currentSource = content;
+        m_tree.clear();
+        m_source.clear();
+        m_reader.clear();
+        m_reader.addSource("<test>", content);
+        m_source.addReader(&m_reader);
+        m_source.addSourceUnit(m_reader.currentSourceUnit());
+    }
+
+private:
+    void checkAST(RplVirtualMachine& vm, const char* fileExpected, int lineNo){
+        QByteArray fnExpected = "test";
+        fnExpected += QDir::separator().toLatin1();
+        fnExpected += "rplvm";
+        fnExpected += (char) QDir::separator().toLatin1();
+        fnExpected += fileExpected;
+        QByteArray fnCurrent = getTempFile(fileExpected, "rplvm");
+        vm.dump(fnCurrent, RplASTree::DMP_NO_GLOBALS);
+        assertEqualFiles(fnExpected.constData(), fnCurrent.constData(),
+                         __FILE__, lineNo);
+    }
+public:
+    void baseTest(){
+        setSource("Int a=2+3*4");
+        RplMFParser parser(m_source, m_tree);
+        parser.parse();
+        RplVirtualMachine vm(m_tree, m_source);
+        checkAST(vm, "baseTest.txt", __LINE__);
+    }
+    virtual void doIt(void) {
+        baseTest();
+    }
+};
+void testRplVM() {
+    TestRplVM test;
+    test.run();
+}
+
index bee689c4f1d324c542210cb1f252cd58deeeca58..87406f888c049f0cf92f077c470ca0f5f8b6390c 100644 (file)
@@ -22,6 +22,9 @@ void testCore(){
 }
 
 void testExpr(){
+    extern void testRplVM();
+    testRplVM();
+
     extern void testRplMFParser();
     testRplMFParser();
 
index 14f1174698c915f43b455ad14f0fcac26bb4449f..13edfaa43a5edda900a02d99ee49d8a2a6c84f37 100644 (file)
 #include "rplexpr/rplexpr.hpp"
 #include "rplcore/rpltest.hpp"
 
-class TestRplMFParser : public RplTest{
+class TestRplVM : public RplTest{
 private:
     RplSource m_source;
     RplASTree m_tree;
     RplStringReader m_reader;
     const char* m_currentSource;
 public:
-    TestRplMFParser() :
+    TestRplVM() :
         RplTest("RplMFParser"),
         m_source(),
         m_tree(),
@@ -189,7 +189,7 @@ public:
     }
 };
 void testRplMFParser() {
-    TestRplMFParser test;
+    TestRplVM test;
     test.run();
 }
 
index 4ce578f88b7e5640accf4b8bc7f853b9203df230..891dbfdaaf3c84e6b60258b37e606e7294a38562 100644 (file)
@@ -36,5 +36,6 @@ SOURCES += main.cpp \
     ../rplcore/rplqstring.cpp \
     ../rplexpr/rplasclasses.cpp \
     rplastree_test.cpp \
-    rplmfparser_test.cpp
+    rplmfparser_test.cpp \
+    ../rplexpr/rplvm_test.cpp