diff --git a/src/compiler.h b/src/compiler.h index 85be367e..d2abd155 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -43,7 +43,6 @@ class Compiler { public: std::unique_ptr parser; bool repl_mode; - bool l_value; std::stack<_Code> codes; std::stack loops; @@ -466,21 +465,13 @@ public: 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)(); - while (rules[peek()].precedence >= precedence) { lexToken(); _TokenType op = parser->previous.type; GrammarFn infix = rules[op].infix; (this->*infix)(); } - - this->l_value = l_value; } void keepOpcodeLine(){ diff --git a/src/pointer.h b/src/pointer.h index 01afddb9..5ab65494 100644 --- a/src/pointer.h +++ b/src/pointer.h @@ -7,6 +7,7 @@ class Frame; struct BasePointer { virtual PyVar get(VM*, Frame*) const = 0; virtual void set(VM*, Frame*, PyVar) const = 0; + virtual void del(VM*, Frame*) const = 0; }; enum NameScope { @@ -22,6 +23,7 @@ struct NamePointer : BasePointer { PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; + void del(VM* vm, Frame* frame) const; bool operator==(const NamePointer& other) const { return name == other.name && scope == other.scope; @@ -35,6 +37,7 @@ struct AttrPointer : BasePointer { PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; + void del(VM* vm, Frame* frame) const; }; struct IndexPointer : BasePointer { @@ -44,4 +47,5 @@ struct IndexPointer : BasePointer { PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; + void del(VM* vm, Frame* frame) const; }; diff --git a/src/str.h b/src/str.h index be773d95..7b8bc0f4 100644 --- a/src/str.h +++ b/src/str.h @@ -141,6 +141,7 @@ const _Str& __str__ = _Str("__str__"); const _Str& __neg__ = _Str("__neg__"); const _Str& __getitem__ = _Str("__getitem__"); const _Str& __setitem__ = _Str("__setitem__"); +const _Str& __delitem__ = _Str("__delitem__"); const _Str& __contains__ = _Str("__contains__"); const _Str& __init__ = _Str("__init__"); diff --git a/src/vm.h b/src/vm.h index c8f355d8..0f6c33b5 100644 --- a/src/vm.h +++ b/src/vm.h @@ -159,6 +159,10 @@ public: _Pointer p = PyPointer_AS_C(frame->__pop()); p->set(this, frame.get(), obj); } break; + case OP_DELETE_PTR: { + _Pointer p = PyPointer_AS_C(frame->__pop()); + p->del(this, frame.get()); + } break; case OP_STORE_FUNCTION: { 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{ 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); } +void AttrPointer::del(VM* vm, Frame* frame) const{ + vm->_error("AttributeError", "can't delete attribute"); +} + PyVar IndexPointer::get(VM* vm, Frame* frame) const{ 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}); } +void IndexPointer::del(VM* vm, Frame* frame) const{ + vm->call(obj, __delitem__, {index}); +} + /**************** Frame ****************/ inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){ if(v->isType(vm->_tp_pointer)) v = vm->PyPointer_AS_C(v)->get(vm, this);