Skip to content

Commit

Permalink
updated to r2779 from original svn repo
Browse files Browse the repository at this point in the history
  • Loading branch information
irmen committed Oct 26, 2021
1 parent 47b44c6 commit f707c0a
Show file tree
Hide file tree
Showing 11 changed files with 287 additions and 65 deletions.
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ Stepping through a[from:to:step]
omitted in case it starts from the beginning or end at the end. If the
`step' is negative then it's done in reverse.
Extract multiple elements a[list]
Extract elements based on a list. So "abcd"[[1,3]] will be ["b", "d"].
Extract elements based on a list. So "abcd"[[1,3]] will be "bd".

The fun start with nested lists and tuples, as these can be used to create a
matrix. The examples will be given for a two dimensional matrix for easier
Expand Down
4 changes: 2 additions & 2 deletions README.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<html lang="en">
<!-- $Id: README.html 2768 2021-10-17 00:03:15Z soci $ -->
<!-- $Id: README.html 2779 2021-10-17 21:18:07Z soci $ -->
<head>
<title>64tass v1.56 r2625 reference manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Expand Down Expand Up @@ -1749,7 +1749,7 @@ <h4>Slicing and indexing<a name="slicing_indexing" href="#slicing_indexing"></a>
The <q>from</q> and <q>to</q> can be omitted in case it starts from the
beginning or end at the end. If the <q>step</q> is negative then it's done in reverse.
<dt>Extract multiple elements <code>a[list]</code>
<dd>Extract elements based on a list. So <code>"abcd"[[1,3]]</code> will be <code>["b", "d"]</code>.
<dd>Extract elements based on a list. So <code>"abcd"[[1,3]]</code> will be <code>"bd"</code>.
</dl>

<p>The fun start with nested lists and tuples, as these can be used to create a matrix. The
Expand Down
46 changes: 34 additions & 12 deletions bitsobj.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
$Id: bitsobj.c 2768 2021-10-17 00:03:15Z soci $
$Id: bitsobj.c 2778 2021-10-17 21:11:15Z soci $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -1189,24 +1189,46 @@ static MUST_CHECK Obj *slice(oper_t op, argcount_t indx) {

if (io.val->obj->iterable) {
struct iter_s iter;
List *l;
Obj **vals;
iter.data = io.val; io.val->obj->getiter(&iter);
op->inplace = NULL;

if (iter.len == 0) {
iter_destroy(&iter);
return val_reference(null_list);
return val_reference(null_bits);
}
l = new_list();
l->data = vals = list_create_elements(l, iter.len);
for (i = 0; i < iter.len && (args->val[indx].val = iter.next(&iter)) != NULL; i++) {
vals[i] = slice(op, indx);
sz = (iter.len + SHIFT - 1) / SHIFT;

vv = new_bits2(sz);
if (vv == NULL) {
iter_destroy(&iter);
goto failed;
}
v = vv->data;

uv = inv;
bits = 0; sz = 0;
for (i = 0; i < iter.len && (io.val = iter.next(&iter)) != NULL; i++) {
err = indexoffs(&io);
if (err != NULL) {
val_destroy(Obj(vv));
iter_destroy(&iter);
return err;
}
o = io.offs / SHIFT;
if (o < bitslen(vv1) && ((vv1->data[o] >> (io.offs % SHIFT)) & 1) != 0) {
uv ^= 1U << bits;
}
bits++;
if (bits == SHIFT) {
v[sz++] = uv;
uv = inv;
bits = 0;
}
}
l->len = i;
args->val[indx].val = io.val;
iter_destroy(&iter);
return Obj(l);
if (bits != 0) v[sz++] = uv & ((1U << bits) - 1);

vv->bits = i;
return normalize(vv, sz, false);
}
if (io.val->obj == COLONLIST_OBJ) {
struct sliceparam_s s;
Expand Down
33 changes: 21 additions & 12 deletions bytesobj.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
$Id: bytesobj.c 2768 2021-10-17 00:03:15Z soci $
$Id: bytesobj.c 2778 2021-10-17 21:11:15Z soci $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -1177,24 +1177,31 @@ static MUST_CHECK Obj *slice(oper_t op, argcount_t indx) {

if (io.val->obj->iterable) {
struct iter_s iter;
List *l;
Obj **vals;
iter.data = io.val; io.val->obj->getiter(&iter);
op->inplace = NULL;

if (iter.len == 0) {
iter_destroy(&iter);
return val_reference(null_list);
return val_reference(null_bytes);
}
v = new_bytes2(iter.len);
if (v == NULL) {
iter_destroy(&iter);
goto failed;
}
l = new_list();
l->data = vals = list_create_elements(l, iter.len);
for (i = 0; i < iter.len && (args->val[indx].val = iter.next(&iter)) != NULL; i++) {
vals[i] = slice(op, indx);
p2 = v->data;
for (i = 0; i < iter.len && (io.val = iter.next(&iter)) != NULL; i++) {
err = indexoffs(&io);
if (err != NULL) {
val_destroy(Obj(v));
iter_destroy(&iter);
return err;
}
p2[i] = v1->data[io.offs] ^ inv;
}
l->len = i;
args->val[indx].val = io.val;
iter_destroy(&iter);
return Obj(l);
if (i > SSIZE_MAX) goto failed2; /* overflow */
v->len = (ssize_t)i;
return Obj(v);
}
if (io.val->obj == COLONLIST_OBJ) {
struct sliceparam_s s;
Expand Down Expand Up @@ -1257,6 +1264,8 @@ static MUST_CHECK Obj *slice(oper_t op, argcount_t indx) {
err = indexoffs(&io);
if (err != NULL) return err;
return bytes_from_u8(v1->data[io.offs] ^ inv);
failed2:
val_destroy(Obj(v));
failed:
return new_error_mem(op->epoint3);
}
Expand Down
22 changes: 13 additions & 9 deletions codeobj.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
$Id: codeobj.c 2768 2021-10-17 00:03:15Z soci $
$Id: codeobj.c 2778 2021-10-17 21:11:15Z soci $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -423,22 +423,26 @@ static MUST_CHECK Obj *slice(oper_t op, argcount_t indx) {

if (io.val->obj->iterable) {
struct iter_s iter;
Tuple *v;
size_t i;
List *v;
iter.data = io.val; io.val->obj->getiter(&iter);
op->inplace = NULL;

if (iter.len == 0) {
iter_destroy(&iter);
return val_reference(null_list);
return val_reference(null_tuple);
}
v = new_list();
v->data = vals = list_create_elements(v, iter.len);
for (i = 0; i < iter.len && (args->val[indx].val = iter.next(&iter)) != NULL; i++) {
vals[i] = slice(op, indx);
v = new_tuple(iter.len);
vals = v->data;
for (i = 0; i < iter.len && (io.val = iter.next(&iter)) != NULL; i++) {
err = indexoffs(&io);
if (err != NULL) {
vals[i] = err;
continue;
}
ci.offs2 = (address_t)io.offs;
vals[i] = code_item(&ci);
}
v->len = i;
args->val[indx].val = io.val;
iter_destroy(&iter);
return Obj(v);
}
Expand Down
103 changes: 96 additions & 7 deletions dictobj.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
$Id: dictobj.c 2768 2021-10-17 00:03:15Z soci $
$Id: dictobj.c 2778 2021-10-17 21:11:15Z soci $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -35,6 +35,10 @@ static Type obj;

Type *const DICT_OBJ = &obj;

static Dict null_dictval = { { &obj, 1 }, 0, null_dictval.u.val, { { { 0 } } }, NULL };

Obj *const null_dict = &null_dictval.v;

static Dict *new_dict(size_t ln) {
size_t ln1, ln2, ln3;
Dict *v;
Expand Down Expand Up @@ -279,6 +283,79 @@ static MUST_CHECK Obj *normalize(Dict *dict) {
return Obj(dict);
}

static MUST_CHECK Obj *dict_from_iterable(Obj *v1, linepos_t epoint) {
Obj *v;
struct iter_s iter;
iter.data = v1; v1->obj->getiter(&iter);

if (iter.len == 0) {
v = val_reference(null_dict);
} else {
Dict *dict = new_dict(iter.len);
if (dict == NULL) {
v = new_error_mem(epoint);
} else {
struct pair_s p;
size_t i;
dict->def = NULL;
for (i = 0; i < iter.len && (p.key = iter.next(&iter)) != NULL; i++) {
Obj *err;

if (p.key == none_value || p.key->obj == ERROR_OBJ) {
v = val_reference(p.key);
error:
val_destroy(Obj(dict));
iter_destroy(&iter);
return v;
}
if (p.key->obj != COLONLIST_OBJ) p.data = NULL;
else {
Colonlist *list = Colonlist(p.key);
if (list->len != 2 || (list->data[0] != default_value && list->data[1] == default_value)) {
v = new_error_obj(ERROR__NOT_KEYVALUE, p.key, epoint);
goto error;
}
p.key = list->data[0];
p.data = list->data[1];
}
if (p.key == default_value) {
if (dict->def != NULL) val_destroy(dict->def);
dict->def = (p.data == NULL || p.data == default_value) ? NULL : val_reference(p.data);
continue;
}
err = p.key->obj->hash(p.key, &p.hash, epoint);
if (err != NULL) {
v = err;
goto error;
}
dict_update(dict, &p);
}
v = normalize(dict);
}
}
iter_destroy(&iter);
return v;
}

static MUST_CHECK Obj *dict_from_obj(Obj *o1, linepos_t epoint) {
switch (o1->obj->type) {
case T_NONE:
case T_ERROR:
case T_DICT:
return val_reference(o1);
default:
if (o1->obj->iterable) {
return dict_from_iterable(o1, epoint);
}
break;
}
return new_error_conv(o1, DICT_OBJ, epoint);
}

static MUST_CHECK Obj *convert(oper_t op) {
return dict_from_obj(op->v2, op->epoint2);
}

static FAST_CALL bool same(const Obj *o1, const Obj *o2) {
const Dict *v1 = Dict(o1), *v2 = Dict(o2);
size_t n;
Expand Down Expand Up @@ -584,19 +661,25 @@ static MUST_CHECK Obj *slice(oper_t op, argcount_t indx) {
List *v;
Obj **vals;
iter.data = o2; o2->obj->getiter(&iter);
op->inplace = NULL;

if (iter.len == 0) {
iter_destroy(&iter);
return val_reference(null_list);
}
v = new_list();
v->data = vals = list_create_elements(v, iter.len);
for (i = 0; i < iter.len && (args->val[indx].val = iter.next(&iter)) != NULL; i++) {
vals[i] = slice(op, indx);
for (i = 0; i < iter.len && (o2 = iter.next(&iter)) != NULL; i++) {
vv = findit(v1, o2, epoint2);
if (vv->obj != ERROR_OBJ && more) {
Obj *result;
op->v1 = vv;
result = vv->obj->slice(op, indx + 1);
val_destroy(vv);
vv = result;
}
vals[i] = vv;
}
v->len = i;
args->val[indx].val = o2;
iter_destroy(&iter);
return Obj(v);
}
Expand All @@ -608,11 +691,11 @@ static MUST_CHECK Obj *slice(oper_t op, argcount_t indx) {
if (err != NULL) return err;

if (s.length == 0) {
return val_reference((v1->v.obj == TUPLE_OBJ) ? null_tuple : null_list);
return val_reference(null_dict);
}

if (s.step == 1 && s.length == v1->len && v1->def == NULL && !more) {
return val_reference(Obj(v1)); /* original tuple */
return val_reference(Obj(v1)); /* original dict */
}
v = new_dict(s.length);
if (v == NULL) return new_error_mem(epoint2); /* overflow */
Expand Down Expand Up @@ -829,6 +912,7 @@ void dictobj_init(void) {
type->iterable = true;
type->destroy = destroy;
type->garbage = garbage;
type->convert = convert;
type->same = same;
type->hash = hash;
type->len = len;
Expand All @@ -845,3 +929,8 @@ void dictobj_names(void) {
new_builtin("dict", val_reference(Obj(DICT_OBJ)));
}

void dictobj_destroy(void) {
#ifdef DEBUG
if (null_dict->refcount != 1) fprintf(stderr, "dict %" PRIuSIZE "\n", null_dict->refcount - 1);
#endif
}
5 changes: 4 additions & 1 deletion dictobj.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
$Id: dictobj.h 2651 2021-05-09 19:33:48Z soci $
$Id: dictobj.h 2774 2021-10-17 10:27:33Z soci $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -45,8 +45,11 @@ typedef struct Dict {

#define Dict(a) OBJ_CAST(Dict, a)

extern Obj *const null_dict;

extern void dictobj_init(void);
extern void dictobj_names(void);
extern void dictobj_destroy(void);

extern Obj *dictobj_parse(struct values_s *, size_t);
extern MUST_CHECK Obj *dict_sort(Dict *, const size_t *);
Expand Down
4 changes: 2 additions & 2 deletions eval.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
$Id: eval.c 2756 2021-10-11 23:59:10Z soci $
$Id: eval.c 2774 2021-10-17 10:27:33Z soci $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -1013,7 +1013,7 @@ static bool get_val2(struct eval_context_s *ev) {
v--;
}
args -= vsp;
v[0].val = dictobj_parse(v + 1, args);
v[0].val = (args == 0) ? val_reference(null_dict) : dictobj_parse(v + 1, args);
continue;
}
case O_COND:
Expand Down
Loading

0 comments on commit f707c0a

Please sign in to comment.