tmp
This commit is contained in:
parent
f666416696
commit
ed3421321c
11 changed files with 1179 additions and 308 deletions
|
|
@ -9,7 +9,7 @@ Expression::Expression(Type type) :
|
|||
|
||||
ExpressionChild* Expression::ExprChild(tp::String id) { return new ExpressionChild(this, id); }
|
||||
|
||||
ExpressionCall* Expression::ExprCall(tp::InitialierList<Expression*> args) { return new ExpressionCall(this, args); }
|
||||
ExpressionCall* Expression::ExprCall(ExpressionList* args) { return new ExpressionCall(this, args); }
|
||||
|
||||
ExpressionLocal* obj::BCgen::ExprLocal(tp::String id) { return new ExpressionLocal(id); }
|
||||
|
||||
|
|
@ -17,11 +17,15 @@ ExpressionSelf* obj::BCgen::ExprSelf() { return new ExpressionSelf(); }
|
|||
|
||||
ExpressionNew* obj::BCgen::ExprNew(tp::String type) { return new ExpressionNew(type); }
|
||||
|
||||
ExpressionAriphm* obj::BCgen::ExprAriphm(Expression* left, Expression* right, OpCode type) { return new ExpressionAriphm(left, right, type); }
|
||||
ExpressionAriphm* obj::BCgen::ExprAriphm(Expression* left, Expression* right, OpCode type) {
|
||||
return new ExpressionAriphm(left, right, type);
|
||||
}
|
||||
|
||||
ExpressionFunc* obj::BCgen::ExprFunc(tp::String id) { return new ExpressionFunc(id); }
|
||||
|
||||
ExpressionBoolean* obj::BCgen::ExprBool(Expression* left, Expression* right, obj::OpCode type) { return new ExpressionBoolean(left, right, ExpressionBoolean::BoolType(type)); }
|
||||
ExpressionBoolean* obj::BCgen::ExprBool(Expression* left, Expression* right, obj::OpCode type) {
|
||||
return new ExpressionBoolean(left, right, ExpressionBoolean::BoolType(type));
|
||||
}
|
||||
|
||||
ExpressionBoolean* obj::BCgen::ExprBoolNot(Expression* invert) { return new ExpressionBoolean(invert); }
|
||||
|
||||
|
|
@ -36,12 +40,15 @@ ExpressionBoolean::ExpressionBoolean(Expression* invert) :
|
|||
mLeft(invert),
|
||||
mBoolType(BoolType::NOT) {}
|
||||
|
||||
ExpressionCall::ExpressionCall(Expression* mParent, tp::InitialierList<Expression*> args) :
|
||||
ExpressionCall::ExpressionCall(Expression* mParent, ExpressionList* args) :
|
||||
Expression(Type::CALL),
|
||||
mParent(mParent) {
|
||||
mArgs = args;
|
||||
}
|
||||
|
||||
ExpressionList::ExpressionList() :
|
||||
Expression(Type::LIST) {}
|
||||
|
||||
ExpressionNew::ExpressionNew(tp::String type) :
|
||||
Expression(Type::NEW),
|
||||
mNewType(type) {}
|
||||
|
|
|
|||
|
|
@ -348,8 +348,8 @@ void FunctionDefinition::EvalExpr(Expression* expr) {
|
|||
case Expression::Type::CALL:
|
||||
{
|
||||
auto call = (ExpressionCall*) expr;
|
||||
inst(Instruction(OpCode::PUSH_ARGS, call->mArgs.size(), 1));
|
||||
for (auto arg : call->mArgs) {
|
||||
inst(Instruction(OpCode::PUSH_ARGS, call->mArgs->mItems.size(), 1));
|
||||
for (auto arg : call->mArgs->mItems) {
|
||||
EvalExpr(arg.data());
|
||||
}
|
||||
EvalExpr(call->mParent);
|
||||
|
|
|
|||
186
Objects/private/parser/Bindings.cpp
Normal file
186
Objects/private/parser/Bindings.cpp
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
|
||||
#include "Private.hpp"
|
||||
|
||||
#include <parser/parser.h>
|
||||
|
||||
using namespace obj::BCgen;
|
||||
|
||||
typedef lalr::ParserNode<SymbolType> Node;
|
||||
|
||||
static UserData scope(const UserData* start, const Node* nodes, size_t length) { return start[1]; }
|
||||
|
||||
static UserData stm_list_append(const UserData* start, const Node* nodes, size_t length) {
|
||||
auto scope = (StatementScope*) start[0];
|
||||
auto stm = (Statement*) start[2];
|
||||
scope->mStatements.append(stm);
|
||||
return scope;
|
||||
}
|
||||
|
||||
static UserData stm_list_create(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new StatementScope({ (Statement*) start[0] }, true);
|
||||
}
|
||||
|
||||
static UserData stm_log(const UserData* start, const Node* nodes, size_t length) {
|
||||
auto expr = (Expression*) (start[1]);
|
||||
return new StatementPrint(expr);
|
||||
}
|
||||
|
||||
static UserData stm_assign(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new StatementCopy((Expression*) start[0], (Expression*) start[2]);
|
||||
}
|
||||
|
||||
static UserData stm_var_def_new_type(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new StatementLocalDef((char*) nodes[1].lexeme().c_str(), new ExpressionNew((char*) nodes[3].lexeme().c_str()));
|
||||
}
|
||||
|
||||
static UserData stm_var_def_assign(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new StatementLocalDef((char*) nodes[1].lexeme().c_str(), (Expression*) start[3]);
|
||||
}
|
||||
|
||||
static UserData expr_function(const UserData* start, const Node* nodes, size_t length) {
|
||||
auto expr = (Expression*) (start[0]);
|
||||
auto args = (ExpressionList*) (start[2]);
|
||||
return expr->ExprCall(args);
|
||||
}
|
||||
|
||||
static UserData expr_method(const UserData* start, const Node* nodes, size_t length) {
|
||||
auto expr = (Expression*) (start[0]);
|
||||
auto args = (ExpressionList*) (start[4]);
|
||||
auto childId = nodes[1].lexeme();
|
||||
auto method = new ExpressionChild(expr, (char*) childId.c_str());
|
||||
return method->ExprCall(args);
|
||||
}
|
||||
|
||||
static UserData expr_list_append(const UserData* start, const Node* nodes, size_t length) {
|
||||
auto list = (ExpressionList*) start[0];
|
||||
auto expr = (Expression*) start[2];
|
||||
list->mItems.append(expr);
|
||||
return list;
|
||||
}
|
||||
|
||||
static UserData expr_list_create(const UserData* start, const Node* nodes, size_t length) {
|
||||
auto exprList = new ExpressionList();
|
||||
exprList->mItems.append((Expression*) start[0]);
|
||||
return exprList;
|
||||
}
|
||||
|
||||
static UserData expr_child(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionChild((Expression*) start[0], (char*) nodes[2].lexeme().c_str());
|
||||
}
|
||||
|
||||
static UserData expr_bool_eq(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL);
|
||||
}
|
||||
|
||||
static UserData expr_bool_negate(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionBoolean((Expression*) start[1]);
|
||||
}
|
||||
|
||||
static UserData expr_bool_neq(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::NOT_EQUAL);
|
||||
}
|
||||
|
||||
static UserData expr_bool_grater(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::MORE);
|
||||
}
|
||||
|
||||
static UserData expr_bool_lesser(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::LESS);
|
||||
}
|
||||
|
||||
static UserData expr_bool_grater_eq(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionBoolean(
|
||||
(Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL_OR_MORE
|
||||
);
|
||||
}
|
||||
|
||||
static UserData expr_bool_lesser_eq(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionBoolean(
|
||||
(Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL_OR_LESS
|
||||
);
|
||||
}
|
||||
|
||||
static UserData expr_add(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionAriphm((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_ADD);
|
||||
}
|
||||
|
||||
static UserData expr_subtract(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionAriphm((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_SUB);
|
||||
}
|
||||
|
||||
static UserData expr_multiply(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionAriphm((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_MUL);
|
||||
}
|
||||
|
||||
static UserData expr_divide(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionAriphm((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_DIV);
|
||||
}
|
||||
|
||||
static UserData expr_compound(const UserData* start, const Node* nodes, size_t length) { return start[1]; }
|
||||
|
||||
static UserData expr_bool(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionConst(nodes[0].lexeme() == "true");
|
||||
}
|
||||
|
||||
static UserData expr_int(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionConst(stoi(nodes[0].lexeme()));
|
||||
}
|
||||
|
||||
static UserData expr_float(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionConst(stof(nodes[0].lexeme()));
|
||||
}
|
||||
|
||||
static UserData expr_string(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionConst((char*) nodes[0].lexeme().c_str());
|
||||
}
|
||||
|
||||
static UserData expr_id(const UserData* start, const Node* nodes, size_t length) {
|
||||
return new ExpressionLocal((char*) nodes[0].lexeme().c_str());
|
||||
}
|
||||
|
||||
static UserData tmp(const UserData* start, const Node* nodes, size_t length) {
|
||||
// a
|
||||
return *start;
|
||||
}
|
||||
|
||||
#define BIND(name) parser.set_action_handler(#name, &(name));
|
||||
|
||||
void bind(LalrParser& parser) {
|
||||
BIND(scope);
|
||||
|
||||
BIND(stm_list_append);
|
||||
BIND(stm_list_create);
|
||||
|
||||
BIND(expr_list_append);
|
||||
BIND(expr_list_create);
|
||||
|
||||
BIND(stm_var_def_new_type);
|
||||
BIND(stm_var_def_assign);
|
||||
BIND(stm_log);
|
||||
BIND(stm_assign);
|
||||
|
||||
BIND(expr_function)
|
||||
BIND(expr_method)
|
||||
BIND(expr_child)
|
||||
BIND(expr_bool_eq)
|
||||
BIND(expr_bool_negate)
|
||||
BIND(expr_bool_neq)
|
||||
BIND(expr_bool_grater)
|
||||
BIND(expr_bool_lesser)
|
||||
BIND(expr_bool_grater_eq)
|
||||
BIND(expr_bool_lesser_eq)
|
||||
BIND(expr_add)
|
||||
BIND(expr_subtract)
|
||||
BIND(expr_multiply)
|
||||
BIND(expr_divide)
|
||||
BIND(expr_compound)
|
||||
BIND(expr_bool)
|
||||
BIND(expr_int)
|
||||
BIND(expr_float)
|
||||
BIND(expr_string)
|
||||
BIND(expr_id)
|
||||
|
||||
BIND(tmp)
|
||||
|
||||
parser.set_lexer_action_handler("string", &lalr::string_literal<IteratorType>);
|
||||
}
|
||||
16
Objects/private/parser/Private.hpp
Normal file
16
Objects/private/parser/Private.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <lalr/Parser.hpp>
|
||||
#include <lalr/string_literal.hpp>
|
||||
|
||||
typedef void* UserData;
|
||||
typedef char SymbolType;
|
||||
|
||||
typedef std::basic_string<SymbolType>::iterator IteratorType;
|
||||
|
||||
extern const lalr::ParserStateMachine* oscript_parser_state_machine;
|
||||
|
||||
typedef lalr::Parser<IteratorType, UserData> LalrParser;
|
||||
|
||||
void bind(LalrParser& parser);
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,28 +1,60 @@
|
|||
oscript {
|
||||
%whitespace "[ \t\r\n]*";
|
||||
%none error;
|
||||
%none integer;
|
||||
%left '(' ')';
|
||||
%left '+' '-';
|
||||
%left '*' '/';
|
||||
%left '.' '=';
|
||||
%left '==' '>' '<' '>=' '<=' '!=' '!';
|
||||
|
||||
scope:
|
||||
'{' statements '}' [scope]
|
||||
'{' stmts '}' [scope]
|
||||
| ;
|
||||
|
||||
statements:
|
||||
statements ';' statement ';' [stm_scope_append]
|
||||
| statement [stm_scope_create]
|
||||
stmts:
|
||||
stmts ';' stmt ';' [stm_list_append]
|
||||
| stmt [stm_list_create]
|
||||
| ;
|
||||
|
||||
statement:
|
||||
statementVar [tmp]
|
||||
| statementLog [tmp];
|
||||
stmt:
|
||||
stm_var_def_new_type [tmp]
|
||||
| stm_var_def_assign [tmp]
|
||||
| stm_log [tmp]
|
||||
| stm_assign [tmp]
|
||||
;
|
||||
|
||||
statementVar: 'var' id [stm_defVar];
|
||||
statementLog: 'print' value [stm_log];
|
||||
stm_var_def_new_type: 'var' id ':' id [stm_var_def_new_type];
|
||||
stm_var_def_assign: 'var' id '=' expr [stm_var_def_assign];
|
||||
stm_log: 'print' expr [stm_log];
|
||||
stm_assign: expr '=' expr [stm_assign];
|
||||
|
||||
value:
|
||||
boolean [expr_bool]
|
||||
expr_list:
|
||||
expr_list ',' expr ',' [expr_list_append]
|
||||
| expr [expr_list_create]
|
||||
| ;
|
||||
|
||||
expr:
|
||||
id '(' expr_list ')' [expr_function]
|
||||
| expr '.' id '(' expr_list ')' [expr_method]
|
||||
| expr '.' id [expr_child]
|
||||
| expr '==' expr [expr_bool_eq]
|
||||
| '!' expr [expr_bool_negate]
|
||||
| expr '!=' expr [expr_bool_neq]
|
||||
| expr '>' expr [expr_bool_grater]
|
||||
| expr '<' expr [expr_bool_lesser]
|
||||
| expr '>=' expr [expr_bool_grater_eq]
|
||||
| expr '<=' expr [expr_bool_lesser_eq]
|
||||
| expr '+' expr [expr_add]
|
||||
| expr '-' expr [expr_subtract]
|
||||
| expr '*' expr [expr_multiply]
|
||||
| expr '/' expr [expr_divide]
|
||||
| '(' expr ')' [expr_compound]
|
||||
| boolean [expr_bool]
|
||||
| integer [expr_int]
|
||||
| real [expr_float]
|
||||
| string [expr_string]
|
||||
|
|
||||
| id [expr_id]
|
||||
;
|
||||
|
||||
id: "[a-z]";
|
||||
|
|
|
|||
|
|
@ -2,93 +2,17 @@
|
|||
|
||||
#include <parser/parser.h>
|
||||
|
||||
// #include "compiler/function.h"
|
||||
|
||||
#include <lalr/Parser.hpp>
|
||||
#include <lalr/string_literal.hpp>
|
||||
#include "Private.hpp"
|
||||
|
||||
using namespace obj;
|
||||
|
||||
struct ASTNode {
|
||||
BCgen::Expression* expression = nullptr;
|
||||
BCgen::Statement* statement = nullptr;
|
||||
};
|
||||
|
||||
extern const lalr::ParserStateMachine* oscript_parser_state_machine;
|
||||
typedef void* UserData;
|
||||
typedef char SymbolType;
|
||||
|
||||
typedef std::basic_string<SymbolType>::iterator IteratorType;
|
||||
|
||||
namespace action {
|
||||
static UserData expr_bool(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
return new BCgen::ExpressionConst(nodes[0].lexeme() == "true");
|
||||
}
|
||||
|
||||
static UserData expr_int(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static UserData expr_float(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static UserData expr_string(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static UserData stm_log(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
auto expr = (BCgen::Expression*) (start[1]);
|
||||
return new BCgen::StatementPrint(expr);
|
||||
}
|
||||
|
||||
static UserData stm_defVar(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
return new BCgen::StatementLocalDef(nodes[1].lexeme().c_str(), new BCgen::ExpressionConst(false));
|
||||
}
|
||||
|
||||
static UserData stm_scope_append(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
auto scope = (BCgen::StatementScope*) start[0];
|
||||
auto stm = (BCgen::Statement*) start[2];
|
||||
scope->mStatements.append(stm);
|
||||
return scope;
|
||||
}
|
||||
|
||||
static UserData stm_scope_create(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
auto stm = (BCgen::Statement*) start[0];
|
||||
return new BCgen::StatementScope({ stm }, true);
|
||||
}
|
||||
|
||||
static UserData scope(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
return start[1];
|
||||
}
|
||||
|
||||
static UserData tmp(const UserData* start, const lalr::ParserNode<SymbolType>* nodes, size_t length) {
|
||||
return *start;
|
||||
}
|
||||
}
|
||||
|
||||
Parser::Result Parser::parse(const tp::String& stream) {
|
||||
|
||||
lalr::ErrorPolicy errorPolicy;
|
||||
|
||||
lalr::Parser<IteratorType, UserData> parser(oscript_parser_state_machine, &errorPolicy);
|
||||
LalrParser parser(oscript_parser_state_machine, &errorPolicy);
|
||||
|
||||
parser.set_lexer_action_handler("string", &lalr::string_literal<IteratorType>);
|
||||
|
||||
parser.set_action_handler("expr_bool", &action::expr_bool);
|
||||
parser.set_action_handler("expr_int", &action::expr_int);
|
||||
parser.set_action_handler("expr_float", &action::expr_float);
|
||||
parser.set_action_handler("expr_string", &action::expr_string);
|
||||
|
||||
parser.set_action_handler("stm_defVar", &action::stm_defVar);
|
||||
parser.set_action_handler("stm_log", &action::stm_log);
|
||||
|
||||
parser.set_action_handler("stm_scope_create", &action::stm_scope_create);
|
||||
parser.set_action_handler("stm_scope_append", &action::stm_scope_append);
|
||||
|
||||
parser.set_action_handler("scope", &action::scope);
|
||||
|
||||
parser.set_action_handler("tmp", &action::tmp);
|
||||
bind(parser);
|
||||
|
||||
std::string streamStd(stream.read());
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace obj {
|
|||
FUNC,
|
||||
BOOLEAN,
|
||||
SELF,
|
||||
LIST,
|
||||
} mType = Type::NONE;
|
||||
|
||||
bool mValueUsed = false;
|
||||
|
|
@ -32,7 +33,12 @@ namespace obj {
|
|||
Expression(Type type);
|
||||
|
||||
ExpressionChild* ExprChild(tp::String id);
|
||||
ExpressionCall* ExprCall(tp::InitialierList<Expression*> args);
|
||||
ExpressionCall* ExprCall(class ExpressionList* args);
|
||||
};
|
||||
|
||||
struct ExpressionList : public Expression {
|
||||
tp::Buffer<Expression*> mItems;
|
||||
ExpressionList();
|
||||
};
|
||||
|
||||
struct ExpressionNew : public Expression {
|
||||
|
|
@ -59,8 +65,8 @@ namespace obj {
|
|||
|
||||
struct ExpressionCall : public Expression {
|
||||
Expression* mParent = NULL;
|
||||
tp::Buffer<Expression*> mArgs;
|
||||
ExpressionCall(Expression* mParent, tp::InitialierList<Expression*> args);
|
||||
ExpressionList* mArgs;
|
||||
ExpressionCall(Expression* mParent, ExpressionList* args);
|
||||
};
|
||||
|
||||
struct ExpressionAriphm : public Expression {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,10 @@ if (i == 10) {
|
|||
)";
|
||||
|
||||
auto script = R"(
|
||||
{
|
||||
var i = 10;
|
||||
print (i + 10) * 5;
|
||||
}
|
||||
)";
|
||||
|
||||
TEST_DEF_STATIC(Complex) {
|
||||
|
|
@ -64,7 +67,7 @@ TEST_DEF_STATIC(Simple) {
|
|||
|
||||
interpreter->getMember<LinkObject>("target method")->setLink(method);
|
||||
|
||||
method->mScript->mReadable->val = "<< 3;";
|
||||
method->mScript->mReadable->val = script;
|
||||
method->compile();
|
||||
|
||||
interpreter->exec();
|
||||
|
|
@ -77,9 +80,12 @@ TEST_DEF_STATIC(Simple) {
|
|||
|
||||
NDO->destroy(interpreterLoaded);
|
||||
NDO->destroy(interpreter);
|
||||
|
||||
printf("\n\nEnd\n\n");
|
||||
}
|
||||
|
||||
TEST_DEF(Interpreter) {
|
||||
testSimple();
|
||||
exit(0);
|
||||
// testComplex();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using namespace obj;
|
|||
TEST_DEF_STATIC(Basic) {
|
||||
Parser parser;
|
||||
|
||||
String stream = "{ var i; print false; }";
|
||||
String stream = "{ var i = true; print (i + 1) * 10; }";
|
||||
auto res = parser.parse(stream);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@ int main() {
|
|||
tp::ModuleManifest* deps[] = { &gModuleObjects, nullptr };
|
||||
tp::ModuleManifest module("ObjectsTests", nullptr, nullptr, deps);
|
||||
|
||||
if (module.initialize()) {
|
||||
testInterpreter();
|
||||
module.deinitialize();
|
||||
}
|
||||
|
||||
if (module.initialize()) {
|
||||
testParser();
|
||||
module.deinitialize();
|
||||
|
|
@ -31,10 +36,5 @@ int main() {
|
|||
module.deinitialize();
|
||||
}
|
||||
|
||||
if (module.initialize()) {
|
||||
testInterpreter();
|
||||
module.deinitialize();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue