mirror of
https://github.com/pocketpy/pocketpy
synced 2025-11-07 20:20:17 +00:00
in assignment works
This commit is contained in:
parent
63a00d0faf
commit
b66ef11dac
@ -74,6 +74,8 @@ public:
|
|||||||
rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX };
|
rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX };
|
||||||
rules[TK("@fstr")] = { METHOD(exprFString), NO_INFIX };
|
rules[TK("@fstr")] = { METHOD(exprFString), NO_INFIX };
|
||||||
rules[TK("?")] = { nullptr, METHOD(exprTernary), PREC_TERNARY };
|
rules[TK("?")] = { nullptr, METHOD(exprTernary), PREC_TERNARY };
|
||||||
|
// do not include standalone, as it allows naked assignment
|
||||||
|
//rules[TK(":=")] = { nullptr, METHOD(exprWalrus), 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_ASSIGNMENT };
|
||||||
@ -176,7 +178,7 @@ private:
|
|||||||
}
|
}
|
||||||
}catch(std::exception& _){
|
}catch(std::exception& _){
|
||||||
SyntaxError("invalid number literal");
|
SyntaxError("invalid number literal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lex_token(){
|
void lex_token(){
|
||||||
@ -201,12 +203,12 @@ private:
|
|||||||
case '{': parser->set_next_token(TK("{")); return;
|
case '{': parser->set_next_token(TK("{")); return;
|
||||||
case '}': parser->set_next_token(TK("}")); return;
|
case '}': parser->set_next_token(TK("}")); return;
|
||||||
case ',': parser->set_next_token(TK(",")); return;
|
case ',': parser->set_next_token(TK(",")); return;
|
||||||
case ':': parser->set_next_token(TK(":")); return;
|
|
||||||
case ';': parser->set_next_token(TK(";")); return;
|
case ';': parser->set_next_token(TK(";")); return;
|
||||||
case '(': parser->set_next_token(TK("(")); return;
|
case '(': parser->set_next_token(TK("(")); return;
|
||||||
case ')': parser->set_next_token(TK(")")); return;
|
case ')': parser->set_next_token(TK(")")); return;
|
||||||
case '[': parser->set_next_token(TK("[")); return;
|
case '[': parser->set_next_token(TK("[")); return;
|
||||||
case ']': parser->set_next_token(TK("]")); return;
|
case ']': parser->set_next_token(TK("]")); return;
|
||||||
|
case ':': parser->set_next_token_2('=', TK(":"), TK(":=")); return;
|
||||||
case '%': parser->set_next_token_2('=', TK("%"), TK("%=")); return;
|
case '%': parser->set_next_token_2('=', TK("%"), TK("%=")); return;
|
||||||
case '&': parser->set_next_token_2('=', TK("&"), TK("&=")); return;
|
case '&': parser->set_next_token_2('=', TK("&"), TK("&=")); return;
|
||||||
case '|': parser->set_next_token_2('=', TK("|"), TK("|=")); return;
|
case '|': parser->set_next_token_2('=', TK("|"), TK("|=")); return;
|
||||||
@ -283,7 +285,7 @@ private:
|
|||||||
eat_number();
|
eat_number();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (parser->eat_name())
|
switch (parser->eat_name())
|
||||||
{
|
{
|
||||||
case 0: break;
|
case 0: break;
|
||||||
@ -400,13 +402,21 @@ private:
|
|||||||
emit(OP_LOAD_LAMBDA, co()->add_const(vm->PyFunction(func)));
|
emit(OP_LOAD_LAMBDA, co()->add_const(vm->PyFunction(func)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exprWalrus() {
|
||||||
|
// NAME is on stack
|
||||||
|
EXPR_TUPLE();
|
||||||
|
// EXPR is on stack
|
||||||
|
emit(OP_STORE_REF); // will pop the value and the name off the stack,
|
||||||
|
// we need to return the value now
|
||||||
|
}
|
||||||
void exprAssign() {
|
void exprAssign() {
|
||||||
co()->_rvalue = true;
|
co()->_rvalue = true;
|
||||||
TokenIndex op = parser->prev.type;
|
TokenIndex op = parser->prev.type;
|
||||||
if(op == TK("=")) { // a = (expr)
|
if(op == TK("=")) { // a = (expr)
|
||||||
EXPR_TUPLE();
|
EXPR_TUPLE();
|
||||||
emit(OP_STORE_REF);
|
emit(OP_STORE_REF);
|
||||||
}else{ // a += (expr) -> a = a + (expr)
|
}
|
||||||
|
else{ // a += (expr) -> a = a + (expr)
|
||||||
emit(OP_DUP_TOP);
|
emit(OP_DUP_TOP);
|
||||||
EXPR();
|
EXPR();
|
||||||
switch (op) {
|
switch (op) {
|
||||||
@ -502,8 +512,48 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void exprGrouping() {
|
void exprGrouping() {
|
||||||
|
// either a expr in parens,
|
||||||
|
// or a tuple.
|
||||||
match_newlines(mode()==REPL_MODE);
|
match_newlines(mode()==REPL_MODE);
|
||||||
EXPR_TUPLE();
|
// do {
|
||||||
|
// if (peek() == TK("@id")) {
|
||||||
|
// consume(TK("@id"));
|
||||||
|
// exprAssign();
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// EXPR();
|
||||||
|
// }
|
||||||
|
// } while (match(TK(",")));
|
||||||
|
// EXPR_TUPLE();
|
||||||
|
do {
|
||||||
|
if (peek() == TK(")")) break;
|
||||||
|
if(peek() == TK("@id") && peek_next() == TK(":=")) {
|
||||||
|
consume(TK("@id"));
|
||||||
|
Token tkname = parser->prev;
|
||||||
|
int index = co()->add_name(
|
||||||
|
tkname.str(),
|
||||||
|
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
||||||
|
);
|
||||||
|
emit(OP_LOAD_NAME_REF, index);
|
||||||
|
consume(TK(":="));
|
||||||
|
exprWalrus();
|
||||||
|
emit(OP_LOAD_NAME, index);
|
||||||
|
|
||||||
|
// const Str& key = parser->prev.str();
|
||||||
|
// emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(key)));
|
||||||
|
// consume(TK("="));
|
||||||
|
// co()->_rvalue=true; EXPR(); co()->_rvalue=false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
EXPR_TUPLE();
|
||||||
|
}
|
||||||
|
} while (match(TK(",")));
|
||||||
|
// if (peek() == TK("@id")) {
|
||||||
|
// consume(TK("@id"));
|
||||||
|
// exprAssign();
|
||||||
|
// } else {
|
||||||
|
// EXPR_TUPLE();
|
||||||
|
// }
|
||||||
match_newlines(mode()==REPL_MODE);
|
match_newlines(mode()==REPL_MODE);
|
||||||
consume(TK(")"));
|
consume(TK(")"));
|
||||||
}
|
}
|
||||||
@ -532,7 +582,7 @@ __LISTCOMP:
|
|||||||
emit(OP_BUILD_LIST, 0);
|
emit(OP_BUILD_LIST, 0);
|
||||||
EXPR_FOR_VARS();consume(TK("in"));EXPR_TUPLE();
|
EXPR_FOR_VARS();consume(TK("in"));EXPR_TUPLE();
|
||||||
match_newlines(mode()==REPL_MODE);
|
match_newlines(mode()==REPL_MODE);
|
||||||
|
|
||||||
int _skipPatch = emit(OP_JUMP_ABSOLUTE);
|
int _skipPatch = emit(OP_JUMP_ABSOLUTE);
|
||||||
int _cond_start = co()->codes.size();
|
int _cond_start = co()->codes.size();
|
||||||
int _cond_end_return = -1;
|
int _cond_end_return = -1;
|
||||||
|
|||||||
@ -1,10 +1,21 @@
|
|||||||
## Function Tests.
|
## Function Tests.
|
||||||
|
#a := 1
|
||||||
|
#_b = (1, 2)
|
||||||
|
#(d := 4) + 6
|
||||||
|
#(D := 4)
|
||||||
|
#assert D == 4
|
||||||
|
#x = D + 1
|
||||||
|
x = (a := 3,4)
|
||||||
|
y = (a := 3)
|
||||||
|
print(y)
|
||||||
|
#assert False # (D := 4)==4
|
||||||
|
# b = (d := 4) + (c := 4)
|
||||||
|
# c = (d := 2) + 1
|
||||||
|
# b = (x := a + 1) + 2
|
||||||
def f1():
|
def f1():
|
||||||
return 'f1'
|
return 'f1'
|
||||||
assert f1() == 'f1'
|
assert f1() == 'f1'
|
||||||
def f2(a, b, c, d):
|
def f2(a, b, c, d):
|
||||||
return c
|
return c
|
||||||
assert f2('a', 'b', 'c', 'd') == 'c'
|
assert f2('a', 'b', 'c', 'd') == 'c'
|
||||||
def f3(a,b):
|
def f3(a,b):
|
||||||
@ -15,7 +26,7 @@ def fact(n):
|
|||||||
if n == 1:
|
if n == 1:
|
||||||
return 1
|
return 1
|
||||||
return n * fact(n - 1)
|
return n * fact(n - 1)
|
||||||
assert fact(5)==120
|
assert fact(5)==120
|
||||||
|
|
||||||
def f(a=1, b=-1):
|
def f(a=1, b=-1):
|
||||||
return a + b
|
return a + b
|
||||||
|
|||||||
6
tests/_walrus.py
Normal file
6
tests/_walrus.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
assert ( x := 1) == 1
|
||||||
|
assert ( y := 1) + 2 == 3
|
||||||
|
|
||||||
|
a = (y := 4) + 5
|
||||||
|
assert a == 9
|
||||||
|
assert y == 4
|
||||||
Loading…
x
Reference in New Issue
Block a user