Skip to content

Commit

Permalink
Make del dict[value] work
Browse files Browse the repository at this point in the history
Delete a dictionary entry.

Signed-off-by: Keith Packard <keithp@keithp.com>
  • Loading branch information
keith-packard committed Mar 3, 2019
1 parent bb72bab commit 5229a7f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 6 deletions.
19 changes: 19 additions & 0 deletions snek-code.c
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,25 @@ snek_code_run(snek_code_t *code_in)
ip += sizeof (snek_id_t);
snek_frame_mark_global(id);
break;
case snek_op_del:
memcpy(&id, &snek_code->code[ip], sizeof (snek_id_t));
ip += sizeof (snek_id_t);
if (id == SNEK_ID_NONE) {
snek_poly_t lp = snek_stack_pop();

snek_list_t *l;
if (snek_poly_type(lp) != snek_list ||
snek_list_type(l = snek_poly_to_list(lp)) != snek_list_dict)
{
snek_error_type_1(lp);
} else {
snek_list_del(l, snek_a);
snek_a = SNEK_NULL;
}
} else {
snek_id_del(id);
}
break;
case snek_op_branch:
memcpy(&ip, &snek_code->code[ip], sizeof (snek_offset_t));
break;
Expand Down
22 changes: 17 additions & 5 deletions snek-gram.ll
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,21 @@ command : @{ snek_print_val = snek_interactive; }@ stat
if (ref)
*ref = poly;
}@
| DEL NAME
| DEL del dels-p
| IMPORT NAME
;
dels-p : COMMA del
dels-p
|
;
del : expr-array
@{
if (!snek_id_del(snek_token_val.id))
snek_undefined(snek_token_val.id);
snek_token_val.op = snek_op_del;
goto extract_lvalue;
}@
@{
goto add_op_lvalue;
}@
| IMPORT NAME
;
opt-formals : formals
|
Expand Down Expand Up @@ -112,6 +121,7 @@ assign-expr : expr assign-expr-p
;
assign-expr-p : ASSIGN
@{
extract_lvalue:
snek_print_val = false;
snek_offset_t prev_offset = snek_code_prev_insn();
uint8_t *prev = snek_code_at(prev_offset);
Expand All @@ -125,7 +135,8 @@ assign-expr-p : ASSIGN
memcpy(&id, prev + 1, sizeof (snek_id_t));
break;
case snek_op_array:
snek_code_set_push(snek_code_prev_prev_insn());
if (snek_token_val.op != snek_op_del)
snek_code_set_push(snek_code_prev_prev_insn());
id = SNEK_ID_NONE;
break;
default:
Expand All @@ -141,6 +152,7 @@ assign-expr-p : ASSIGN
}@
expr
@{
add_op_lvalue:;
snek_op_t op = value_pop().offset;
snek_id_t id = value_pop().id;

Expand Down
14 changes: 13 additions & 1 deletion snek-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,19 @@ snek_list_get(snek_list_t *list, snek_poly_t p, bool report_error)
snek_poly_t *r = _snek_list_ref(list, p, report_error, false);
if (r)
return *r;
return SNEK_ZERO;
return SNEK_NULL;
}

void
snek_list_del(snek_list_t *list, snek_poly_t p)
{
snek_poly_t *r = snek_list_ref(list, p, true);
if (!r)
return;
r--;
snek_offset_t remain = snek_list_data(list) + list->size - r;
memmove(r, r+2, (remain - 2) * sizeof (snek_poly_t));
list->size -= 2;
}

int8_t
Expand Down
4 changes: 4 additions & 0 deletions snek.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ typedef enum {
snek_op_slice,

snek_op_global,
snek_op_del,

snek_op_branch,
snek_op_branch_true,
Expand Down Expand Up @@ -581,6 +582,9 @@ snek_list_get(snek_list_t *list, snek_poly_t p, bool report_error);
snek_poly_t *
snek_list_data(snek_list_t *list);

void
snek_list_del(snek_list_t *list, snek_poly_t p);

int8_t
snek_list_cmp(snek_list_t *a, snek_list_t *b);

Expand Down
6 changes: 6 additions & 0 deletions test/dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,9 @@ def check(expect,got,which):

check(7, a[6], "a[6] == 7")
check("g", b["f"], "b['f'] == 'g'")

del a[1]
del b['c']

check({3:4, 6:7}, a, "a = {3:4, 6:7}")
check({'a': 'e', 'f': 'g'}, b, "b = {'a': 'e', 'f': 'g'}")

0 comments on commit 5229a7f

Please sign in to comment.