Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Berry import strict now detects useless expr without side effects #18997

Merged
merged 1 commit into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.

### Breaking Changed
- Berry `bool( [] )` and `bool( {} )` now evaluate as `false` (#18986)
- Berry `import strict` now detects useless expr without side effects

### Changed
- Matter support for temperature in Fahrenheit (`SetOption8 1`) (#18987)
Expand Down
22 changes: 20 additions & 2 deletions lib/libesp32/berry/src/be_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static void begin_block(bfuncinfo *finfo, bblockinfo *binfo, int type)
finfo->binfo = binfo; /* tell parser this is the current block */
binfo->type = (bbyte)type;
binfo->hasupval = 0;
binfo->sideeffect = 0;
binfo->beginpc = finfo->pc; /* set starting pc for this block */
binfo->nactlocals = (bbyte)be_list_count(finfo->local); /* count number of local variables in previous block */
if (type & BLOCK_LOOP) {
Expand Down Expand Up @@ -796,6 +797,7 @@ static void call_expr(bparser *parser, bexpdesc *e)
int argc = 0, base;
int ismember = e->type == ETMEMBER;

parser->finfo->binfo->sideeffect = 1; /* has side effect */
/* func '(' [exprlist] ')' */
check_var(parser, e);
/* code function index to next register */
Expand Down Expand Up @@ -1030,11 +1032,13 @@ static void assign_expr(bparser *parser)
bexpdesc e;
btokentype op;
int line = parser->lexer.linenumber;
parser->finfo->binfo->sideeffect = 0; /* reinit side effect marker */
expr(parser, &e); /* left expression */
check_symbol(parser, &e);
op = get_assign_op(parser);
if (op != OP_NOT_ASSIGN) { /* assign operator */
bexpdesc e1;
parser->finfo->binfo->sideeffect = 1;
scan_next_token(parser);
compound_assign(parser, op, &e, &e1);
if (check_newvar(parser, &e)) { /* new variable */
Expand Down Expand Up @@ -1110,6 +1114,9 @@ static void sub_expr(bparser *parser, bexpdesc *e, int prio)
check_var(parser, e); /* check that left part is valid */
scan_next_token(parser); /* move to next token */
be_code_prebinop(finfo, op, e); /* and or */
if (op == OptConnect) {
parser->finfo->binfo->sideeffect = 1;
}
init_exp(&e2, ETVOID, 0);
sub_expr(parser, &e2, binary_op_prio(op)); /* parse right side */
if ((e2.type == ETVOID) && (op == OptConnect)) {
Expand Down Expand Up @@ -1758,6 +1765,9 @@ static void throw_stmt(bparser *parser)

static void statement(bparser *parser)
{
/* save value of sideeffect */
bbyte sideeffect = parser->finfo->binfo->sideeffect;
parser->finfo->binfo->sideeffect = 1; /* by default declare side effect */
switch (next_type(parser)) {
case KeyIf: if_stmt(parser); break;
case KeyWhile: while_stmt(parser); break;
Expand All @@ -1772,8 +1782,16 @@ static void statement(bparser *parser)
case KeyVar: var_stmt(parser); break;
case KeyTry: try_stmt(parser); break;
case KeyRaise: throw_stmt(parser); break;
case OptSemic: scan_next_token(parser); break; /* empty statement */
default: expr_stmt(parser); break;
case OptSemic:
parser->finfo->binfo->sideeffect = sideeffect; /* restore sideeffect */
scan_next_token(parser); break; /* empty statement */
default:
parser->finfo->binfo->sideeffect = sideeffect; /* restore sideeffect */
expr_stmt(parser);
if (comp_is_strict(parser->vm) && parser->finfo->binfo->sideeffect == 0) {
push_error(parser, "strict: expression without side effect detected");
}
break;
}
be_assert(parser->finfo->freereg >= be_list_count(parser->finfo->local));
}
Expand Down
1 change: 1 addition & 0 deletions lib/libesp32/berry/src/be_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ typedef struct bblockinfo {
bbyte nactlocals; /* number of active local variables */
bbyte type; /* block type mask */
bbyte hasupval; /* has upvalue mark */
bbyte sideeffect; /* did the last expr/statement had a side effect */
int breaklist; /* break list */
int beginpc; /* begin pc */
int continuelist; /* continue list */
Expand Down
2 changes: 1 addition & 1 deletion lib/libesp32/berry_tasmota/src/embedded/persist.be
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class Persist
import json
if isinstance(v, map)
self.json_fdump_map(f, v)
elif isinstance(v, list)v
elif isinstance(v, list)
self.json_fdump_list(f, v)
else
f.write(json.dump(v))
Expand Down