add del impl

This commit is contained in:
blueloveTH 2022-11-07 16:58:43 +08:00
parent 9e426d3291
commit c2fa538f44
4 changed files with 42 additions and 9 deletions

View File

@ -43,7 +43,6 @@ class Compiler {
public: public:
std::unique_ptr<Parser> parser; std::unique_ptr<Parser> parser;
bool repl_mode; bool repl_mode;
bool l_value;
std::stack<_Code> codes; std::stack<_Code> codes;
std::stack<Loop> loops; std::stack<Loop> loops;
@ -466,21 +465,13 @@ public:
throw SyntaxError(path, parser->previous, "expected an expression"); throw SyntaxError(path, parser->previous, "expected an expression");
} }
// Make a "backup" of the l value before parsing next operators to
// reset once it done.
bool l_value = this->l_value;
this->l_value = precedence <= PREC_LOWEST;
(this->*prefix)(); (this->*prefix)();
while (rules[peek()].precedence >= precedence) { while (rules[peek()].precedence >= precedence) {
lexToken(); lexToken();
_TokenType op = parser->previous.type; _TokenType op = parser->previous.type;
GrammarFn infix = rules[op].infix; GrammarFn infix = rules[op].infix;
(this->*infix)(); (this->*infix)();
} }
this->l_value = l_value;
} }
void keepOpcodeLine(){ void keepOpcodeLine(){

View File

@ -7,6 +7,7 @@ class Frame;
struct BasePointer { struct BasePointer {
virtual PyVar get(VM*, Frame*) const = 0; virtual PyVar get(VM*, Frame*) const = 0;
virtual void set(VM*, Frame*, PyVar) const = 0; virtual void set(VM*, Frame*, PyVar) const = 0;
virtual void del(VM*, Frame*) const = 0;
}; };
enum NameScope { enum NameScope {
@ -22,6 +23,7 @@ struct NamePointer : BasePointer {
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;
void del(VM* vm, Frame* frame) const;
bool operator==(const NamePointer& other) const { bool operator==(const NamePointer& other) const {
return name == other.name && scope == other.scope; return name == other.name && scope == other.scope;
@ -35,6 +37,7 @@ struct AttrPointer : BasePointer {
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;
void del(VM* vm, Frame* frame) const;
}; };
struct IndexPointer : BasePointer { struct IndexPointer : BasePointer {
@ -44,4 +47,5 @@ struct IndexPointer : BasePointer {
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;
void del(VM* vm, Frame* frame) const;
}; };

View File

@ -141,6 +141,7 @@ const _Str& __str__ = _Str("__str__");
const _Str& __neg__ = _Str("__neg__"); const _Str& __neg__ = _Str("__neg__");
const _Str& __getitem__ = _Str("__getitem__"); const _Str& __getitem__ = _Str("__getitem__");
const _Str& __setitem__ = _Str("__setitem__"); const _Str& __setitem__ = _Str("__setitem__");
const _Str& __delitem__ = _Str("__delitem__");
const _Str& __contains__ = _Str("__contains__"); const _Str& __contains__ = _Str("__contains__");
const _Str& __init__ = _Str("__init__"); const _Str& __init__ = _Str("__init__");

View File

@ -159,6 +159,10 @@ public:
_Pointer p = PyPointer_AS_C(frame->__pop()); _Pointer p = PyPointer_AS_C(frame->__pop());
p->set(this, frame.get(), obj); p->set(this, frame.get(), obj);
} break; } break;
case OP_DELETE_PTR: {
_Pointer p = PyPointer_AS_C(frame->__pop());
p->del(this, frame.get());
} break;
case OP_STORE_FUNCTION: case OP_STORE_FUNCTION:
{ {
PyVar obj = frame->popValue(this); PyVar obj = frame->popValue(this);
@ -587,6 +591,31 @@ void NamePointer::set(VM* vm, Frame* frame, PyVar val) const{
} }
} }
void NamePointer::del(VM* vm, Frame* frame) const{
switch(scope) {
case NAME_LOCAL: {
if(frame->f_locals.count(name) > 0){
frame->f_locals.erase(name);
}else{
vm->nameError(name);
}
} break;
case NAME_GLOBAL:
{
if(frame->f_locals.count(name) > 0){
frame->f_locals.erase(name);
}else{
if(frame->f_globals->count(name) > 0){
frame->f_globals->erase(name);
}else{
vm->nameError(name);
}
}
} break;
default: UNREACHABLE();
}
}
PyVar AttrPointer::get(VM* vm, Frame* frame) const{ PyVar AttrPointer::get(VM* vm, Frame* frame) const{
return vm->getAttr(obj, attr->name); return vm->getAttr(obj, attr->name);
} }
@ -595,6 +624,10 @@ void AttrPointer::set(VM* vm, Frame* frame, PyVar val) const{
vm->setAttr(obj, attr->name, val); vm->setAttr(obj, attr->name, val);
} }
void AttrPointer::del(VM* vm, Frame* frame) const{
vm->_error("AttributeError", "can't delete attribute");
}
PyVar IndexPointer::get(VM* vm, Frame* frame) const{ PyVar IndexPointer::get(VM* vm, Frame* frame) const{
return vm->call(obj, __getitem__, {index}); return vm->call(obj, __getitem__, {index});
} }
@ -603,6 +636,10 @@ void IndexPointer::set(VM* vm, Frame* frame, PyVar val) const{
vm->call(obj, __setitem__, {index, val}); vm->call(obj, __setitem__, {index, val});
} }
void IndexPointer::del(VM* vm, Frame* frame) const{
vm->call(obj, __delitem__, {index});
}
/**************** Frame ****************/ /**************** Frame ****************/
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);