Browse Source

add -> opt

blueloveTH 3 years ago
parent
commit
710748f58d
5 changed files with 26 additions and 3 deletions
  1. 11 1
      src/compiler.h
  2. 1 0
      src/opcodes.h
  3. 1 1
      src/parser.h
  4. 7 0
      src/vm.h
  5. 6 1
      tests/pointer.py

+ 11 - 1
src/compiler.h

@@ -54,6 +54,7 @@ public:
 #define NO_INFIX nullptr, PREC_NONE
         for(_TokenType i=0; i<__TOKENS_LEN; i++) rules[i] = { nullptr, NO_INFIX };
         rules[TK(".")] =    { nullptr,               METHOD(exprAttrib),         PREC_ATTRIB };
+        rules[TK("->")] =   { nullptr,               METHOD(exprAttribPtr),      PREC_ATTRIB };
         rules[TK("(")] =    { METHOD(exprGrouping),  METHOD(exprCall),           PREC_CALL };
         rules[TK("[")] =    { METHOD(exprList),      METHOD(exprSubscript),      PREC_SUBSCRIPT };
         rules[TK("{")] =    { METHOD(exprMap),       NO_INFIX };
@@ -221,7 +222,9 @@ public:
                     return;
                 }
                 case '-': {
-                    parser->setNextTwoCharToken('=', TK("-"), TK("-="));
+                    if(parser->matchChar('=')) parser->setNextToken(TK("-="));
+                    else if(parser->matchChar('>')) parser->setNextToken(TK("->"));
+                    else parser->setNextToken(TK("-"));
                     return;
                 }
                 case '!':
@@ -556,6 +559,13 @@ __LISTCOMP:
         emitCode(OP_BUILD_ATTR_PTR, index);
     }
 
+    void exprAttribPtr(){
+        consume(TK("@id"));
+        const _Str& name = parser->previous.str();
+        int index = getCode()->addName(name, NAME_ATTR);
+        emitCode(OP_BUILD_ATTR_PTR_PTR, index);
+    }
+
     // [:], [:b]
     // [a], [a:], [a:b]
     void exprSubscript() {

+ 1 - 0
src/opcodes.h

@@ -54,6 +54,7 @@ OPCODE(BUILD_INDEX_PTR)     // no arg, [ptr, expr] -> (*ptr)[expr]
 OPCODE(STORE_NAME_PTR)      // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack
 OPCODE(STORE_PTR)           // no arg, [ptr, expr] -> *ptr = expr
 OPCODE(DELETE_PTR)          // no arg, [ptr] -> [] -> delete ptr
+OPCODE(BUILD_ATTR_PTR_PTR)  // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr
 
 OPCODE(BUILD_SMART_TUPLE)   // if all elements are pointers, build a compound pointer, otherwise build a tuple
 OPCODE(BUILD_STRING)        // arg is the expr count, build a string from the top of the stack

+ 1 - 1
src/parser.h

@@ -7,7 +7,7 @@ typedef uint8_t _TokenType;
 constexpr const char* __TOKENS[] = {
     "@error", "@eof", "@eol", "@sof",
     ".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "%",
-    "+", "-", "*", "/", "//", "**", "=", ">", "<", "...",
+    "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->",
     "<<", ">>", "&", "|", "^",
     "==", "!=", ">=", "<=",
     "+=", "-=", "*=", "/=", "//=",

+ 7 - 0
src/vm.h

@@ -75,6 +75,13 @@ private:
                 PyVar obj = frame->popValue(this);
                 frame->push(PyPointer(std::make_shared<AttrPointer>(obj, attr.get())));
             } break;
+            case OP_BUILD_ATTR_PTR_PTR: {
+                const auto& attr = frame->code->co_names[byte.arg];
+                PyVar obj = frame->popValue(this);
+                __checkType(obj, _tp_user_pointer);
+                const _Pointer& p = std::get<_Pointer>(obj->_native);
+                frame->push(PyPointer(std::make_shared<AttrPointer>(p->get(this, frame), attr.get())));
+            } break;
             case OP_BUILD_INDEX_PTR: {
                 PyVar index = frame->popValue(this);
                 PyVar obj = frame->popValue(this);

+ 6 - 1
tests/pointer.py

@@ -16,4 +16,9 @@ def f():
     assert a == 6
     assert b == 5
 
-f()
+f()
+
+a = [1, 2, 3]
+b = &a
+b->append(4)
+assert a == [1, 2, 3, 4]