blueloveTH 3 years ago
parent
commit
9e426d3291
6 changed files with 39 additions and 47 deletions
  1. 9 7
      src/codeobject.h
  2. 8 8
      src/compiler.h
  3. 0 1
      src/parser.h
  4. 2 2
      src/pocketpy.h
  5. 4 4
      src/pointer.h
  6. 16 25
      src/vm.h

+ 9 - 7
src/codeobject.h

@@ -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());

+ 8 - 8
src/compiler.h

@@ -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;

+ 0 - 1
src/parser.h

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

+ 2 - 2
src/pocketpy.h

@@ -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;
     }

+ 4 - 4
src/pointer.h

@@ -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;

+ 16 - 25
src/vm.h

@@ -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});
 }
 
@@ -612,8 +607,4 @@ void IndexPointer::set(VM* vm, Frame* frame, PyVar val) const{
 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());
 }