support 1 element tuple

This commit is contained in:
blueloveTH 2023-06-11 23:55:04 +08:00
parent 16086a346f
commit d5128404ae
4 changed files with 31 additions and 15 deletions

View File

@ -23,13 +23,12 @@ The easiest way to test a feature is to [try it on your browser](https://pocketp
1. `__getattr__` and `__setattr__`.
2. Descriptor protocol `__get__` and `__set__`. However, `@property` is implemented.
3. `__slots__` in class definition.
4. One element tuple. `(1,)` is not supported.
5. Unpacking in `list` and `dict` literals, e.g. `[1, 2, *a]`.
6. Access the exception object in try..except.
7. `else` clause in try..except.
8. Inplace methods like `__iadd__` and `__imul__`.
9. `__del__` in class definition.
10. Multiple inheritance.
4. Unpacking in `list` and `dict` literals, e.g. `[1, 2, *a]`.
5. Access the exception object in try..except.
6. `else` clause in try..except.
7. Inplace methods like `__iadd__` and `__imul__`.
8. `__del__` in class definition.
9. Multiple inheritance.
## Different behaviors
@ -41,5 +40,4 @@ The easiest way to test a feature is to [try it on your browser](https://pocketp
6. `__ne__` is not required. Define `__eq__` is enough.
7. Raw string cannot have boundary quotes in it, even escaped. See [#55](https://github.com/blueloveTH/pocketpy/issues/55).
8. In a starred unpacked assignment, e.g. `a, b, *c = x`, the starred variable can only be presented in the last position. `a, *b, c = x` is not supported.
9. `a < b < c` does not work as you expected. Use `a < b and b < c` instead. **(available in main branch now)**
10. A `Tab` is equivalent to 4 spaces. You can mix `Tab` and spaces in indentation, but it is not recommended.
9. A `Tab` is equivalent to 4 spaces. You can mix `Tab` and spaces in indentation, but it is not recommended.

View File

@ -160,10 +160,15 @@ str.strip = __f
##### list #####
list.__repr__ = lambda self: '[' + ', '.join([repr(i) for i in self]) + ']'
tuple.__repr__ = lambda self: '(' + ', '.join([repr(i) for i in self]) + ')'
list.__json__ = lambda self: '[' + ', '.join([i.__json__() for i in self]) + ']'
tuple.__json__ = lambda self: '[' + ', '.join([i.__json__() for i in self]) + ']'
def __f(self):
if len(self) == 1:
return '(' + repr(self[0]) + ',)'
return '(' + ', '.join([repr(i) for i in self]) + ')'
tuple.__repr__ = __f
def __qsort(a: list, L: int, R: int, key):
if L >= R: return;
mid = a[(R+L)//2];

View File

@ -221,7 +221,8 @@ class Compiler {
std::vector<Expr_> items;
items.push_back(ctx()->s_expr.popx());
do {
EXPR(); // NOTE: "1," will fail, "1,2" will be ok
if(!is_expression()) break;
EXPR();
items.push_back(ctx()->s_expr.popx());
} while(match(TK(",")));
ctx()->s_expr.push(make_expr<TupleExpr>(
@ -563,16 +564,21 @@ __SUBSCR_END:
consume_end_stmt();
}
bool is_expression(){
PrattCallback prefix = rules[curr().type].prefix;
return prefix != nullptr;
}
void parse_expression(int precedence, bool push_stack=true) {
PrattCallback prefix = rules[curr().type].prefix;
if (prefix == nullptr) SyntaxError(Str("expected an expression, but got ") + TK_STR(curr().type));
advance();
PrattCallback prefix = rules[prev().type].prefix;
if (prefix == nullptr) SyntaxError(Str("expected an expression, but got ") + TK_STR(prev().type));
(this->*prefix)();
while (rules[curr().type].precedence >= precedence) {
TokenIndex op = curr().type;
advance();
PrattCallback infix = rules[op].infix;
if(infix == nullptr) throw std::runtime_error("(infix == nullptr) is true");
PK_ASSERT(infix != nullptr);
(this->*infix)();
}
if(!push_stack) ctx()->emit_expr();

View File

@ -15,3 +15,10 @@ assert b == (1, 2, 3, 4, 5)
a = tuple([])
b = *a, 1, 2, 3, *a, *a
assert b == (1, 2, 3)
assert (1,) == tuple([1])
assert (1,2,) == tuple([1,2])
a = 1,
assert a == (1,)