From 710748f58d6abcb53d147d47fae51a7420a7260f Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 21 Nov 2022 17:27:36 +0800 Subject: [PATCH] add -> opt --- src/compiler.h | 12 +++++++++++- src/opcodes.h | 1 + src/parser.h | 2 +- src/vm.h | 7 +++++++ tests/pointer.py | 7 ++++++- 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index 2332fa88..d49a0202 100644 --- a/src/compiler.h +++ b/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() { diff --git a/src/opcodes.h b/src/opcodes.h index 815e1587..1c6911f4 100644 --- a/src/opcodes.h +++ b/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 diff --git a/src/parser.h b/src/parser.h index b5b528a8..79ff025a 100644 --- a/src/parser.h +++ b/src/parser.h @@ -7,7 +7,7 @@ typedef uint8_t _TokenType; constexpr const char* __TOKENS[] = { "@error", "@eof", "@eol", "@sof", ".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "%", - "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", + "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->", "<<", ">>", "&", "|", "^", "==", "!=", ">=", "<=", "+=", "-=", "*=", "/=", "//=", diff --git a/src/vm.h b/src/vm.h index 077ab7dd..41552de3 100644 --- a/src/vm.h +++ b/src/vm.h @@ -75,6 +75,13 @@ private: PyVar obj = frame->popValue(this); frame->push(PyPointer(std::make_shared(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(p->get(this, frame), attr.get()))); + } break; case OP_BUILD_INDEX_PTR: { PyVar index = frame->popValue(this); PyVar obj = frame->popValue(this); diff --git a/tests/pointer.py b/tests/pointer.py index db45627f..89a00bb0 100644 --- a/tests/pointer.py +++ b/tests/pointer.py @@ -16,4 +16,9 @@ def f(): assert a == 6 assert b == 5 -f() \ No newline at end of file +f() + +a = [1, 2, 3] +b = &a +b->append(4) +assert a == [1, 2, 3, 4] \ No newline at end of file