Apply cpp naming to files
This commit is contained in:
parent
89eec0e329
commit
9d01ba2c8a
73 changed files with 160 additions and 160 deletions
|
|
@ -1,605 +0,0 @@
|
|||
|
||||
#include "interpreter/interpreter.h"
|
||||
|
||||
#include "primitives/primitives.h"
|
||||
|
||||
#include "Timing.hpp"
|
||||
|
||||
using namespace obj;
|
||||
|
||||
inline tp::uint1 read_byte(ByteCode* bytecode) {
|
||||
auto out = (tp::uint1) bytecode->mInstructions[bytecode->mInstructionIdx];
|
||||
bytecode->mInstructionIdx++;
|
||||
return out;
|
||||
}
|
||||
|
||||
// exeption for opcodes
|
||||
// reads 2 bytes from instructions in order to load constant onto operands stack
|
||||
tp::uint2 loadConstDataIdx(ByteCode* bytecode) {
|
||||
tp::uint2 out = 0;
|
||||
out |= ((tp::uint2) read_byte(bytecode));
|
||||
out |= ((tp::uint2) read_byte(bytecode) << 8);
|
||||
return out;
|
||||
}
|
||||
|
||||
// exeption for opcodes
|
||||
// reads 2 bytes from instructions in order to load constant onto operands stack
|
||||
void skip_param(ByteCode* bytecode) { bytecode->mInstructionIdx += 2; }
|
||||
|
||||
tp::uint2 param(ByteCode* bytecode) { return loadConstDataIdx(bytecode); }
|
||||
|
||||
void Interpreter::exec(obj::MethodObject* method, obj::ClassObject* self, obj::DictObject* globals, tp::InitialierList<GlobalDef> globals2) {
|
||||
if (!method->mScript->mBytecode.mInstructions.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCallStack.enter({ NULL, method, 0 });
|
||||
mCallStack.mStack.last().mSelf = self;
|
||||
|
||||
stepBytecodeIn();
|
||||
|
||||
if (globals) {
|
||||
for (auto glb : globals->getItems()) {
|
||||
mScopeStack.addLocal(glb->val, glb->key);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto global_def : globals2) {
|
||||
mScopeStack.addLocal(global_def.obj, global_def.id);
|
||||
}
|
||||
}
|
||||
|
||||
bool Interpreter::finished() { return !mCallStack.len(); }
|
||||
|
||||
void Interpreter::stepBytecode() {
|
||||
tp::halni call_depth = mCallStack.len();
|
||||
do {
|
||||
stepBytecodeIn();
|
||||
if (finished()) {
|
||||
return;
|
||||
}
|
||||
} while (call_depth != mCallStack.len());
|
||||
}
|
||||
|
||||
void Interpreter::stepBytecodeOut() {
|
||||
if (finished()) {
|
||||
return;
|
||||
}
|
||||
|
||||
tp::halni call_depth = mCallStack.len();
|
||||
if (!call_depth) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
stepBytecodeIn();
|
||||
if (finished()) {
|
||||
return;
|
||||
}
|
||||
} while (call_depth - 1 != mCallStack.len());
|
||||
}
|
||||
|
||||
void Interpreter::stepBytecodeIn() {
|
||||
using namespace obj;
|
||||
using namespace tp;
|
||||
|
||||
DEBUG_BREAK(finished());
|
||||
|
||||
auto bytecode = mCallStack.getBytecode();
|
||||
|
||||
if (bytecode->mInstructionIdx >= (tp::ualni) bytecode->mInstructions.size()) {
|
||||
// just return
|
||||
if (mScopeStack.mIdx) {
|
||||
mScopeStack.leaveScope();
|
||||
}
|
||||
|
||||
mCallStack.leave();
|
||||
|
||||
if (mCallStack.len()) {
|
||||
mOperandsStack.push(NDO_NULL_REF);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto opcode = bytecode->mInstructions[bytecode->mInstructionIdx];
|
||||
bytecode->mInstructionIdx++;
|
||||
|
||||
switch (opcode) {
|
||||
|
||||
case OpCode::NONE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::HALT:
|
||||
{
|
||||
while (true) {
|
||||
tp::sleep(3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::TERMINATE:
|
||||
{
|
||||
// tp::terminate(0);
|
||||
}
|
||||
|
||||
case OpCode::IGNORE:
|
||||
{
|
||||
mOperandsStack.getOperand();
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::LOAD_CONST:
|
||||
{
|
||||
auto idx = loadConstDataIdx(bytecode);
|
||||
auto const_obj = bytecode->mConstants[idx];
|
||||
mOperandsStack.push(const_obj);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::LOAD_LOCAL:
|
||||
{
|
||||
auto idx = loadConstDataIdx(bytecode);
|
||||
auto const_obj = bytecode->mConstants[idx];
|
||||
NDO_CASTV(StringObject, const_obj, local_id);
|
||||
ASSERT(local_id && "Invalid Object Type");
|
||||
auto local = mScopeStack.getLocal(local_id->val);
|
||||
mOperandsStack.push(local);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::SCOPE_IN:
|
||||
{
|
||||
mScopeStack.enterScope(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::JUMP:
|
||||
{
|
||||
bytecode->mInstructionIdx += param(bytecode);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::JUMP_IF:
|
||||
{
|
||||
auto cond = mOperandsStack.getOperand();
|
||||
if (NDO->toBool(cond)) {
|
||||
bytecode->mInstructionIdx += param(bytecode);
|
||||
} else {
|
||||
skip_param(bytecode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::JUMP_IF_NOT:
|
||||
{
|
||||
auto cond = mOperandsStack.getOperand();
|
||||
if (!NDO->toBool(cond)) {
|
||||
bytecode->mInstructionIdx += param(bytecode);
|
||||
} else {
|
||||
skip_param(bytecode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::JUMP_R:
|
||||
{
|
||||
bytecode->mInstructionIdx -= param(bytecode);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::JUMP_IF_R:
|
||||
{
|
||||
auto cond = mOperandsStack.getOperand();
|
||||
if (NDO->toBool(cond)) {
|
||||
bytecode->mInstructionIdx -= param(bytecode);
|
||||
} else {
|
||||
skip_param(bytecode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::JUMP_IF_NOT_R:
|
||||
{
|
||||
auto cond = mOperandsStack.getOperand();
|
||||
if (!NDO->toBool(cond)) {
|
||||
bytecode->mInstructionIdx -= param(bytecode);
|
||||
} else {
|
||||
skip_param(bytecode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::SCOPE_OUT:
|
||||
{
|
||||
mScopeStack.leaveScope();
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::PRINT:
|
||||
{
|
||||
auto obj = mOperandsStack.getOperand();
|
||||
if (obj->type->convesions && obj->type->convesions->to_string) {
|
||||
auto str = NDO->toString(obj);
|
||||
printf("%s\n", str.c_str());
|
||||
} else {
|
||||
printf("Object with type '%s' has no string representation.\n", obj->type->name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::OBJ_CREATE_LOCAL:
|
||||
{
|
||||
auto type = mOperandsStack.getOperand<StringObject>();
|
||||
auto id = mOperandsStack.getOperand<StringObject>();
|
||||
mScopeStack.addLocal(NDO->create(type->val), id->val);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::DEF_LOCAL:
|
||||
{
|
||||
auto id = mOperandsStack.getOperand<StringObject>();
|
||||
auto obj = mOperandsStack.getOperand();
|
||||
mScopeStack.addLocal(obj, id->val);
|
||||
NDO->refinc(obj);
|
||||
// mScopeStack.popTemp();
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::OBJ_CREATE:
|
||||
{
|
||||
auto type = mOperandsStack.getOperand<StringObject>();
|
||||
Object* new_obj = NULL;
|
||||
|
||||
// basic types
|
||||
auto idx = NDO->types.presents(type->val);
|
||||
if (idx) {
|
||||
auto new_obj = NDO->create(type->val);
|
||||
|
||||
mOperandsStack.push(new_obj);
|
||||
mScopeStack.addTemp(new_obj);
|
||||
break;
|
||||
}
|
||||
|
||||
// class creation
|
||||
auto local_class = mScopeStack.getLocal(type->val);
|
||||
NDO_CASTV(MethodObject, local_class, method);
|
||||
ASSERT(method);
|
||||
|
||||
// class is a function - execute it as a constructor
|
||||
|
||||
// PUSH_ARGS protocol
|
||||
tp::uint2 len = 0;
|
||||
mOperandsStack.push((Object*) len);
|
||||
mOperandsStack.push(NULL);
|
||||
|
||||
// CALL protocol
|
||||
mScopeStack.enterScope(false);
|
||||
mCallStack.enter({ NULL, method, 0 });
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::CLASS_CONSTRUCT:
|
||||
{
|
||||
auto class_obj = (ClassObject*) NDO->create("class");
|
||||
|
||||
for (auto local : mScopeStack.getCurrentScope()->mLocals) {
|
||||
class_obj->addMember(local->val, local->key);
|
||||
}
|
||||
|
||||
mOperandsStack.push(class_obj);
|
||||
mScopeStack.addTempReturn(class_obj);
|
||||
|
||||
mScopeStack.leaveScope();
|
||||
mCallStack.leave();
|
||||
return;
|
||||
}
|
||||
|
||||
case OpCode::RETURN:
|
||||
{
|
||||
// mScopeStack.addTempReturn(NDO_NULL_REF);
|
||||
mScopeStack.leaveScope();
|
||||
mCallStack.leave();
|
||||
if (mCallStack.len()) {
|
||||
mOperandsStack.push(NDO_NULL_REF);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::PUSH_ARGS:
|
||||
{
|
||||
|
||||
// Layout of OperandsStack:
|
||||
// ....
|
||||
// +1) length : to chech number of args
|
||||
// +2) NULL : stop saving args
|
||||
// +3) object1
|
||||
// +4) object2
|
||||
// ...
|
||||
|
||||
tp::uint2 len = read_byte(bytecode);
|
||||
mOperandsStack.push((Object*) len);
|
||||
mOperandsStack.push(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::SAVE_ARGS:
|
||||
{
|
||||
tp::uint2 args_len = read_byte(bytecode);
|
||||
auto argument = mOperandsStack.getOperand();
|
||||
|
||||
while (argument) {
|
||||
NDO->refinc(argument);
|
||||
|
||||
auto argument_id = bytecode->mConstants[loadConstDataIdx(bytecode)];
|
||||
NDO_CASTV(StringObject, argument_id, id);
|
||||
DEBUG_ASSERT(id);
|
||||
mScopeStack.addLocal(argument, id->val);
|
||||
bytecode->mArgumentsLoaded++;
|
||||
argument = mOperandsStack.getOperand();
|
||||
}
|
||||
|
||||
tp::uint2 saved_len = tp::uint2(tp::ualni(mOperandsStack.getOperand()));
|
||||
ASSERT(args_len == saved_len && "invalid number of arguments passefd");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::RETURN_OBJ:
|
||||
{
|
||||
if (mCallStack.len() > 1) {
|
||||
auto ret = mOperandsStack.getOperand();
|
||||
mOperandsStack.push(ret);
|
||||
mScopeStack.addTempReturn(ret);
|
||||
}
|
||||
|
||||
mScopeStack.leaveScope();
|
||||
mCallStack.leave();
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::CALL:
|
||||
{
|
||||
auto obj = mOperandsStack.getOperand();
|
||||
|
||||
if (!mIsTypeMethod) {
|
||||
NDO_CASTV(MethodObject, obj, method);
|
||||
|
||||
mScopeStack.enterScope(false);
|
||||
mCallStack.enter({ NULL, method, 0 });
|
||||
|
||||
// push self
|
||||
mCallStack.mStack.last().mSelf = mLastParent;
|
||||
break;
|
||||
}
|
||||
|
||||
(*mTypeMethod)(this);
|
||||
mIsTypeMethod = false;
|
||||
mTypeMethod = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::OBJ_ADD:
|
||||
{
|
||||
auto left = mOperandsStack.getOperand();
|
||||
auto right = mOperandsStack.getOperand();
|
||||
|
||||
ASSERT(left->type == right->type && "addition of different types is not implemented");
|
||||
ASSERT(left->type->ariphmetics && left->type->ariphmetics->add && "cannot add object of this type");
|
||||
|
||||
auto res = NDO->instatiate(left);
|
||||
res->type->ariphmetics->add(res, right);
|
||||
|
||||
mScopeStack.addTemp(res);
|
||||
mOperandsStack.push(res);
|
||||
break;
|
||||
}
|
||||
case OpCode::OBJ_SUB:
|
||||
{
|
||||
auto left = mOperandsStack.getOperand();
|
||||
auto right = mOperandsStack.getOperand();
|
||||
|
||||
ASSERT(left->type == right->type && "addition of different types is not implemented");
|
||||
ASSERT(left->type->ariphmetics && left->type->ariphmetics->add && "cannot add object of this type");
|
||||
|
||||
auto res = NDO->instatiate(left);
|
||||
res->type->ariphmetics->sub(res, right);
|
||||
|
||||
mScopeStack.addTemp(res);
|
||||
mOperandsStack.push(res);
|
||||
break;
|
||||
}
|
||||
case OpCode::OBJ_MUL:
|
||||
{
|
||||
auto left = mOperandsStack.getOperand();
|
||||
auto right = mOperandsStack.getOperand();
|
||||
|
||||
ASSERT(left->type == right->type && "addition of different types is not implemented");
|
||||
ASSERT(left->type->ariphmetics && left->type->ariphmetics->add && "cannot add object of this type");
|
||||
|
||||
auto res = NDO->instatiate(left);
|
||||
res->type->ariphmetics->mul(res, right);
|
||||
|
||||
mScopeStack.addTemp(res);
|
||||
mOperandsStack.push(res);
|
||||
break;
|
||||
}
|
||||
case OpCode::OBJ_DIV:
|
||||
{
|
||||
auto left = mOperandsStack.getOperand();
|
||||
auto right = mOperandsStack.getOperand();
|
||||
|
||||
ASSERT(left->type == right->type && "addition of different types is not implemented");
|
||||
ASSERT(left->type->ariphmetics && left->type->ariphmetics->add && "cannot add object of this type");
|
||||
|
||||
auto res = NDO->instatiate(left);
|
||||
res->type->ariphmetics->div(res, right);
|
||||
|
||||
mScopeStack.addTemp(res);
|
||||
mOperandsStack.push(res);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::OBJ_COPY:
|
||||
{
|
||||
auto left = mOperandsStack.getOperand();
|
||||
auto right = mOperandsStack.getOperand();
|
||||
NDO->copy(left, right);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::CHILD:
|
||||
{
|
||||
auto child_id = mOperandsStack.getOperand<StringObject>();
|
||||
auto parent = mOperandsStack.getOperand();
|
||||
bool is_method = read_byte(bytecode);
|
||||
|
||||
Object* child = NULL;
|
||||
TypeMethods::LookupKey tm_key;
|
||||
|
||||
if (is_method) {
|
||||
tm_key = TypeMethods::presents(parent->type, child_id->val);
|
||||
}
|
||||
|
||||
if (tm_key) {
|
||||
mTypeMethod = TypeMethods::getMethod(parent->type, tm_key);
|
||||
mIsTypeMethod = true;
|
||||
|
||||
} else {
|
||||
NDO_CASTV(ClassObject, parent, class_obj);
|
||||
ASSERT(class_obj && "not a class object");
|
||||
auto idx = class_obj->members->presents(child_id->val);
|
||||
ASSERT(idx && "No child with such id");
|
||||
child = class_obj->members->getSlotVal(idx);
|
||||
}
|
||||
|
||||
// mScopeStack.addTemp(obj);
|
||||
mOperandsStack.push(child);
|
||||
mLastParent = parent;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::SELF:
|
||||
{
|
||||
// mScopeStack.addTemp(obj);
|
||||
ASSERT(mCallStack.mStack.last().mSelf);
|
||||
mOperandsStack.push(mCallStack.mStack.last().mSelf);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::OBJ_LOAD:
|
||||
{
|
||||
auto path = mOperandsStack.getOperand<StringObject>();
|
||||
auto obj = NDO->load(path->val);
|
||||
mScopeStack.addTemp(obj);
|
||||
mOperandsStack.push(obj);
|
||||
break;
|
||||
}
|
||||
case OpCode::OBJ_SAVE:
|
||||
{
|
||||
auto path = mOperandsStack.getOperand<StringObject>();
|
||||
auto target = mOperandsStack.getOperand();
|
||||
NDO->save(target, path->val);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::AND:
|
||||
{
|
||||
auto left = NDO->toBool(mOperandsStack.getOperand());
|
||||
auto right = NDO->toBool(mOperandsStack.getOperand());
|
||||
auto out = BoolObject::create(left && right);
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
case OpCode::OR:
|
||||
{
|
||||
auto left = NDO->toBool(mOperandsStack.getOperand());
|
||||
auto right = NDO->toBool(mOperandsStack.getOperand());
|
||||
auto out = BoolObject::create(left || right);
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
case OpCode::NOT:
|
||||
{
|
||||
auto inv = NDO->toBool(mOperandsStack.getOperand());
|
||||
auto out = BoolObject::create(!inv);
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
case OpCode::NOT_EQUAL:
|
||||
{
|
||||
auto left = mOperandsStack.getOperand();
|
||||
auto right = mOperandsStack.getOperand();
|
||||
auto out = BoolObject::create(!NDO->compare(left, right));
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
case OpCode::EQUAL:
|
||||
{
|
||||
auto left = mOperandsStack.getOperand();
|
||||
auto right = mOperandsStack.getOperand();
|
||||
auto out = BoolObject::create(NDO->compare(left, right));
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpCode::MORE:
|
||||
{
|
||||
auto left = NDO->toFloat(mOperandsStack.getOperand());
|
||||
auto right = NDO->toFloat(mOperandsStack.getOperand());
|
||||
auto out = BoolObject::create(left > right);
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
case OpCode::LESS:
|
||||
{
|
||||
auto left = NDO->toFloat(mOperandsStack.getOperand());
|
||||
auto right = NDO->toFloat(mOperandsStack.getOperand());
|
||||
auto out = BoolObject::create(left < right);
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
case OpCode::EQUAL_OR_MORE:
|
||||
{
|
||||
auto left = NDO->toFloat(mOperandsStack.getOperand());
|
||||
auto right = NDO->toFloat(mOperandsStack.getOperand());
|
||||
auto out = BoolObject::create(left >= right);
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
case OpCode::EQUAL_OR_LESS:
|
||||
{
|
||||
auto left = NDO->toFloat(mOperandsStack.getOperand());
|
||||
auto right = NDO->toFloat(mOperandsStack.getOperand());
|
||||
auto out = BoolObject::create(left <= right);
|
||||
mScopeStack.addTemp(out);
|
||||
mOperandsStack.push(out);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
ASSERT("Invalid OpCode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::execAll(obj::MethodObject* method, obj::ClassObject* self, obj::DictObject* globals, tp::InitialierList<GlobalDef> globals2) {
|
||||
if (!method->mScript->mBytecode.mInstructions.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
exec(method, self, globals, globals2);
|
||||
while (!finished()) {
|
||||
stepBytecodeIn();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue