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

View File

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

View File

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

View File

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

View File

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

View File

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