Objects Initial

This commit is contained in:
IlushaShurupov 2023-07-24 21:55:19 +03:00
parent 00bc875846
commit 803ce23169
76 changed files with 7895 additions and 17 deletions

View file

@ -0,0 +1,28 @@
#pragma once
#include "opcodes.h"
#include "primitives/intobject.h"
#include "primitives/stringobject.h"
#include "Buffer.hpp"
#include "Strings.hpp"
namespace obj {
typedef Object* ConstData;
struct ByteCode {
tp::Buffer<ConstData> mConstants;
tp::Buffer<OpCode> mInstructions;
tp::ualni mInstructionIdx = 0;
tp::ualni mArgumentsLoaded = 0;
~ByteCode() {
for (auto const_obj : mConstants) {
NDO->destroy(const_obj.data());
}
}
};
};

View file

@ -0,0 +1,32 @@
#pragma once
#include "core/object.h"
#include "primitives/classobject.h"
#include "Map.hpp"
namespace obj {
struct MethodObject;
};
namespace obj {
struct ByteCode;
struct CallStack {
struct CallFrame {
enum { CALL_DEPTH = 1024 };
obj::Object* mSelf = NULL;
obj::MethodObject* mMethod = NULL;
tp::ualni mIp = 0;
};
void enter(const CallFrame& frame);
void leave();
ByteCode* getBytecode();
tp::halni len() const;
tp::ConstSizeBuffer<CallFrame, CallFrame::CALL_DEPTH> mStack;
};
};

View file

@ -0,0 +1,29 @@
#pragma once
#include "operandsstack.h"
#include "scopestack.h"
#include "callstack.h"
namespace obj {
struct Interpreter {
OperandStack mOperandsStack;
ScopeStack mScopeStack;
CallStack mCallStack;
obj::Object* mLastParent = NULL;
bool mIsTypeMethod = false;
const TypeMethod* mTypeMethod = NULL;
typedef struct { obj::Object* obj; tp::String id; } GlobalDef;
void exec(obj::MethodObject* method, obj::ClassObject* self = NULL, obj::DictObject* globals = NULL, tp::init_list<GlobalDef> globals2 = {});
void stepBytecode();
void stepBytecodeIn();
void stepBytecodeOut();
bool finished();
void execAll(obj::MethodObject* method, obj::ClassObject* self = NULL, obj::DictObject* globals = NULL, tp::init_list<GlobalDef> globals2 = {});
};
};

View file

@ -0,0 +1,158 @@
#pragma once
#include "Common.hpp"
// No Nested Scopes
// Opcodes:
// Opcode input can be:
// 0) No Input
// 1) operands from OperandsStack (Operand)
// 2) Index of bytecode->ConstData from bytecode->Instruction (ConstData)
// 3) Raw Bytes from bytecode->Instruction (Param)
namespace obj {
extern struct OpcodeInfos gOpcodeInfos;
enum class OpCode : tp::uint1 {
NONE = 0x00,
HALT,
TERMINATE,
DEF_LOCAL,
// Operand : String : local_id
// Operand : Any : object to be local
LOAD_CONST,
LOAD_LOCAL,
// ConstData : idx of const object
IGNORE,
SCOPE_IN,
SCOPE_OUT,
CALL,
RETURN_OBJ,
// Operand : Base : returned object
RETURN,
CHILD,
// Operand : String : child_id
// Operand : Base : parent
// Param : 1 bytes : is method?
PUSH_ARGS,
SAVE_ARGS,
// Param : nubber of args
OBJ_CREATE_LOCAL,
// Operand : String : type
// Operand : String : id
OBJ_CREATE,
// Operand : String : type
OBJ_COPY,
// Operand : Base: target
// Operand : Base: blueprint
OBJ_SAVE,
OBJ_LOAD,
// Operand : String : path
// Operand : Base : target
OBJ_ADD,
OBJ_SUB,
OBJ_MUL,
OBJ_DIV,
AND,
OR,
EQUAL,
NOT_EQUAL,
MORE,
LESS,
EQUAL_OR_MORE,
EQUAL_OR_LESS,
// Operand : Base: left
// Operand : Base: right
NOT,
// Operand : Base: inv
JUMP,
JUMP_R,
// Param : 2 bytes : offset
JUMP_IF,
JUMP_IF_R,
JUMP_IF_NOT,
JUMP_IF_NOT_R,
// Operand : Base: condition
// Param : 2 bytes : offset
PRINT,
// Operand : Base: target
CLASS_CONSTRUCT,
SELF,
// ...
END_OPCODES
};
struct OpcodeInfos {
struct OperandsInfo {
struct Operand {
const char* obj_type = nullptr;
const char* desc = nullptr;
};
enum { MAX_OPERANDS = 5 };
Operand buff[MAX_OPERANDS];
tp::halni len = 0;
OperandsInfo();
OperandsInfo(tp::init_list<Operand> list);
};
struct ParamsInfo {
struct Param {
const char* desc = nullptr;
tp::halni bytes = 1;
};
enum { MAX_PARAMS = 5 };
Param buff[MAX_PARAMS];
tp::halni len = 0;
ParamsInfo();
ParamsInfo(tp::init_list<Param> list);
};
struct OpInfo {
const char* name = nullptr;
const char* desc = nullptr;
OperandsInfo operands;
ParamsInfo params;
tp::uint1 opsize();
};
OpcodeInfos();
OpInfo fetch(OpCode code);
private:
OpInfo buff[(tp::alni)OpCode::END_OPCODES];
void add(OpCode code, const OpInfo& info);
};
}

View file

@ -0,0 +1,39 @@
#pragma once
#include "bytecode.h"
#include "core/object.h"
namespace obj {
// can be other aligned value as well
typedef obj::Object* Operand;
class OperandStack {
enum : tp::alni {
MAX_STACK_SIZE = 512
};
public:
Operand* mBuff;
tp::ualni mIdx;
OperandStack();
void push(Operand operand);
void pop();
Operand getOperand();
template <typename ObjectType>
ObjectType* getOperand() {
auto operand = getOperand();
auto ret = NDO_CAST(ObjectType, operand);
ASSERT(ret && "Operand Has Invalid Object Type");
return ret;
}
~OperandStack();
};
};

View file

@ -0,0 +1,46 @@
#pragma once
#include "core/object.h"
#include "Map.hpp"
namespace obj {
struct Scope {
typedef tp::Map<tp::String, obj::Object*> ObjDict;
typedef tp::List<obj::Object*> ObjList;
ObjDict mLocals;
ObjList mTemps;
bool mChildReachable = true;
~Scope();
};
class ScopeStack {
enum : tp::alni {
MAX_STACK_SIZE = 1024 * 4
};
public:
Scope* mBuff;
tp::ualni mIdx;
tp::ualni mIterIdx;
ScopeStack();
void enterScope(bool aChildReachable);
void leaveScope();
void addLocal(obj::Object* local, tp::String id);
void addTemp(obj::Object* tmp);
void popTemp();
void addTempReturn(obj::Object* ret);
obj::Object* getLocal(tp::String& str);
Scope* getCurrentScope();
~ScopeStack();
private:
obj::Object* getLocalUtil(Scope& scope, tp::String* id);
};
};

View file

@ -0,0 +1,12 @@
#pragma once
#include "interpreter/bytecode.h"
namespace obj {
struct Script {
obj::StringObject* mReadable;
ByteCode mBytecode;
void compile();
};
};