return rc;
}
+/**
+ * @brief Find a method in the instance.
+ *
+ * @param name the method's name
+ * @return NULL: method not found
+ * otherwise: the method description
+ */
+RplASMethod* RplSymbolSpace::findMethod(const QString& name) const
+{
+ RplASMethod* rc = NULL;
+ if (m_methods.contains(name))
+ rc = m_methods[name];
+ return rc;
+}
+
/**
* @brief Writes the content of the instance into a file.
*
m_threads.reserve(8);
}
+/**
+ * @brief Executes the program in a module.
+ *
+ * @param module the module's name
+ */
+void RplVirtualMachine::executeModule(const QString& module)
+{
+ RplSymbolSpace* space = m_tree.findmodule(module);
+ if (space == NULL)
+ throw RplVmException("module not found: %s", module.toUtf8().constData());
+ RplStackFrame frame(space);
+ RplSymbolSpace* mainSpace = NULL;
+ RplASItem* mainStatements = NULL;
+ RplASMethod* method = space->findMethod("main");
+ if (method != NULL){
+ mainStatements = method->child();
+ mainSpace = method->symbols();
+ }
+ addThread(space->body(), space, mainStatements, mainSpace);
+}
+
/**
* @brief Adds a thread to the instance.
*
- * @param program the statement list to execute
- * @param space the current symbol space
+ * @param initialization the statements for initialization
+ * @param spaceInitialization the symbol space of the initialization
+ * @param statements the statement list to execute. This is normally
+ * the body of the main program
+ * @param space the symbol space of the statements, normally
+ * the symbol space of the main program
* @param maxStack the maximal number of nested stack frames.
* <= 0: use the default
*/
-void RplVirtualMachine::addThread(RplASItem* program, RplSymbolSpace* space,
+void RplVirtualMachine::addThread(RplASItem* initialization,
+ RplSymbolSpace* spaceInitialization,
+ RplASItem* statements,
+ RplSymbolSpace* space,
int maxStack)
{
RplVMThread* thread = new RplVMThread(
maxThread <= 0 ? m_maxStack : maxStack, self);
m_threads.append(thread);
- thread->execute(program, space);
+ if (initialization != NULL){
+ thread->execute(initialization, spaceInitialization);
+ }
+ if (statements != NULL)
+ thread->execute(statements, space);
}
/**
* @brief Tests whether a given flag is set.
public:
RplVirtualMachine(RplASTree& tree, RplSource& source, int maxStack = 1024);
public:
- void addThread(RplASItem* program, RplSymbolSpace* space, int maxStack = 0);
+ void executeModule(const QString& module);
+ void addThread(RplASItem* initialization,
+ RplSymbolSpace* spaceInitialization,
+ RplASItem* statements, RplSymbolSpace* space,
+ int maxStack = 0);
bool hasFlag(VMFlag flag) const;
void setFlag(VMFlag flag);
void clearFlag(VMFlag flag);
fnExpected += (char) QDir::separator().toLatin1();
fnExpected += fileExpected;
QByteArray fnCurrent = getTempFile(fileExpected, "rplvm");
+ vm.executeModule("<test>");
vm.dump(fnCurrent, RplASTree::DMP_NO_GLOBALS);
assertEqualFiles(fnExpected.constData(), fnCurrent.constData(),
__FILE__, lineNo);