This commit is contained in:
blueloveTH 2022-11-07 16:42:47 +08:00
parent 4bdb268d93
commit 9e426d3291
6 changed files with 39 additions and 47 deletions

View File

@ -25,19 +25,18 @@ _Str pad(const _Str& s, const int n){
return s + _Str(n - s.size(), ' ');
}
class CodeObject {
public:
struct CodeObject {
std::vector<ByteCode> co_code;
_Str co_filename;
_Str co_name;
PyVarList co_consts;
std::vector<NamePointer> co_names;
std::vector<std::shared_ptr<NamePointer>> co_names;
int addName(const _Str& name, NameScope scope){
auto p = NamePointer(name, scope);
auto p = std::make_shared<NamePointer>(name, scope);
for(int i=0; i<co_names.size(); i++){
if(co_names[i] == p) return i;
if(*co_names[i] == *p) return i;
}
co_names.push_back(p);
return co_names.size() - 1;
@ -74,7 +73,7 @@ public:
_StrStream names;
names << "co_names: ";
for(int i=0; i<co_names.size(); i++){
names << co_names[i].name;
names << co_names[i]->name;
if(i != co_names.size() - 1) names << ", ";
}
ss << '\n' << consts.str() << '\n' << names.str() << '\n';
@ -108,6 +107,10 @@ public:
return code->co_code[ip].line;
}
int stackSize() const {
return s_data.size();
}
inline bool isEnd() const {
return ip >= code->co_code.size();
}
@ -119,7 +122,6 @@ public:
}
inline PyVar __deref_pointer(VM*, PyVar);
inline _Pointer popPtr(VM*);
inline PyVar popValue(VM* vm){
return __deref_pointer(vm, __pop());

View File

@ -105,12 +105,12 @@ public:
rules[TK("@id")] = { METHOD(exprName), NO_INFIX };
rules[TK("@num")] = { METHOD(exprLiteral), NO_INFIX };
rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX };
rules[TK("=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
rules[TK("+=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
rules[TK("-=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
rules[TK("*=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
rules[TK("/=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
rules[TK("//=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
rules[TK("=")] = { nullptr, METHOD(exprAssign), PREC_LOWEST };
rules[TK("+=")] = { nullptr, METHOD(exprAssign), PREC_LOWEST };
rules[TK("-=")] = { nullptr, METHOD(exprAssign), PREC_LOWEST };
rules[TK("*=")] = { nullptr, METHOD(exprAssign), PREC_LOWEST };
rules[TK("/=")] = { nullptr, METHOD(exprAssign), PREC_LOWEST };
rules[TK("//=")] = { nullptr, METHOD(exprAssign), PREC_LOWEST };
#undef METHOD
#undef NO_INFIX
}
@ -301,12 +301,12 @@ public:
void exprAssign(){
_TokenType op = parser->previous.type;
if(op == TK("=")) { // a = (expr)
parsePrecedence((Precedence)(rules[op].precedence + 1));
compileExpressionTuple();
emitCode(OP_STORE_PTR);
}else{ // a += (expr) -> a = a + (expr)
// TODO: optimization is needed for inplace operators
emitCode(OP_DUP_TOP);
parsePrecedence((Precedence)(rules[op].precedence + 1));
compileExpression();
switch (op) {
case TK("+="): emitCode(OP_BINARY_OP, 0); break;
case TK("-="): emitCode(OP_BINARY_OP, 1); break;

View File

@ -66,7 +66,6 @@ struct Token{
enum Precedence {
PREC_NONE,
PREC_LOWEST,
PREC_ASSIGNMENT, // =
PREC_LOGICAL_OR, // or
PREC_LOGICAL_AND, // and
PREC_EQUALITY, // == !=

View File

@ -434,8 +434,8 @@ extern "C" {
VM* createVM(PrintFn printFn){
VM* vm = new VM();
__initializeBuiltinFunctions(vm);
//__runCodeBuiltins(vm, __BUILTINS_CODE);
//__addModuleRandom(vm);
__runCodeBuiltins(vm, __BUILTINS_CODE);
__addModuleRandom(vm);
vm->printFn = printFn;
return vm;
}

View File

@ -29,18 +29,18 @@ struct NamePointer : BasePointer {
};
struct AttrPointer : BasePointer {
const _Pointer root;
mutable PyVar obj;
const NamePointer* attr;
AttrPointer(const _Pointer& root, const NamePointer* attr) : root(root), attr(attr) {}
AttrPointer(PyVar obj, const NamePointer* attr) : obj(obj), attr(attr) {}
PyVar get(VM* vm, Frame* frame) const;
void set(VM* vm, Frame* frame, PyVar val) const;
};
struct IndexPointer : BasePointer {
const _Pointer root;
mutable PyVar obj;
const PyVar index;
IndexPointer(_Pointer root, PyVar index) : root(root), index(index) {}
IndexPointer(PyVar obj, PyVar index) : obj(obj), index(index) {}
PyVar get(VM* vm, Frame* frame) const;
void set(VM* vm, Frame* frame, PyVar val) const;

View File

@ -132,32 +132,31 @@ public:
callstack.push(frame);
while(!frame->isEnd()){
const ByteCode& byte = frame->readCode();
printf("%s (%d)\n", OP_NAMES[byte.op], byte.arg);
printf("%s (%d) stack_size: %d\n", OP_NAMES[byte.op], byte.arg, frame->stackSize());
switch (byte.op)
{
case OP_LOAD_CONST: frame->push(frame->code->co_consts[byte.arg]); break;
case OP_LOAD_NAME_PTR: {
const NamePointer* p = &frame->code->co_names[byte.arg];
frame->push(PyPointer(_Pointer(p)));
frame->push(PyPointer(frame->code->co_names[byte.arg]));
} break;
case OP_STORE_NAME_PTR: {
const NamePointer& p = frame->code->co_names[byte.arg];
p.set(this, frame.get(), frame->popValue(this));
const auto& p = frame->code->co_names[byte.arg];
p->set(this, frame.get(), frame->popValue(this));
} break;
case OP_BUILD_ATTR_PTR: {
const NamePointer* attr = &frame->code->co_names[byte.arg];
_Pointer root = frame->popPtr(this);
frame->push(PyPointer(std::make_shared<AttrPointer>(root, attr)));
const auto& attr = frame->code->co_names[byte.arg];
PyVar obj = frame->popValue(this);
frame->push(PyPointer(std::make_shared<AttrPointer>(obj, attr.get())));
} break;
case OP_BUILD_INDEX_PTR: {
PyVar index = frame->popValue(this);
_Pointer root = frame->popPtr(this);
frame->push(PyPointer(std::make_shared<IndexPointer>(root, index)));
PyVar obj = frame->popValue(this);
frame->push(PyPointer(std::make_shared<IndexPointer>(obj, index)));
} break;
case OP_STORE_PTR: {
PyVar obj = frame->popValue(this);
_Pointer p = frame->popPtr(this);
_Pointer p = PyPointer_AS_C(frame->__pop());
p->set(this, frame.get(), obj);
} break;
case OP_STORE_FUNCTION:
@ -168,7 +167,7 @@ public:
} break;
case OP_BUILD_CLASS:
{
const _Str& clsName = frame->code->co_names[byte.arg].name;
const _Str& clsName = frame->code->co_names[byte.arg]->name;
PyVar clsBase = frame->popValue(this);
if(clsBase == None) clsBase = _tp_object;
__checkType(clsBase, _tp_type);
@ -321,7 +320,7 @@ public:
} break;
case OP_IMPORT_NAME:
{
const _Str& name = frame->code->co_names[byte.arg].name;
const _Str& name = frame->code->co_names[byte.arg]->name;
auto it = _modules.find(name);
if(it == _modules.end()){
_error("ImportError", "module '" + name + "' not found");
@ -578,33 +577,29 @@ void NamePointer::set(VM* vm, Frame* frame, PyVar val) const{
case NAME_LOCAL: frame->f_locals[name] = val; break;
case NAME_GLOBAL:
{
if(frame->f_locals.find(name) != frame->f_locals.end()){
frame->f_locals[name] = frame->popValue(vm);
if(frame->f_locals.count(name) > 0){
frame->f_locals[name] = val;
}else{
frame->f_globals->operator[](name) = frame->popValue(vm);
frame->f_globals->operator[](name) = val;
}
} break;
default: UNREACHABLE();
}
UNREACHABLE();
}
PyVar AttrPointer::get(VM* vm, Frame* frame) const{
PyVar obj = root->get(vm, frame);
return vm->getAttr(obj, attr->name);
}
void AttrPointer::set(VM* vm, Frame* frame, PyVar val) const{
PyVar obj = root->get(vm, frame);
vm->setAttr(obj, attr->name, val);
}
PyVar IndexPointer::get(VM* vm, Frame* frame) const{
PyVar obj = root->get(vm, frame);
return vm->call(obj, __getitem__, {index});
}
void IndexPointer::set(VM* vm, Frame* frame, PyVar val) const{
PyVar obj = root->get(vm, frame);
vm->call(obj, __setitem__, {index, val});
}
@ -613,7 +608,3 @@ inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){
if(v->isType(vm->_tp_pointer)) v = vm->PyPointer_AS_C(v)->get(vm, this);
return v;
}
inline _Pointer Frame::popPtr(VM* vm){
return vm->PyPointer_AS_C(__pop());
}