indexing of strings and lists can now be done from outside of expression parser.

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@305 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-10-23 21:48:06 +00:00
parent 1048e12fc7
commit cc82e17cda
4 changed files with 76 additions and 12 deletions

View File

@ -595,3 +595,6 @@ StrangeInputMode
StrangeOperator
The expression parser found a non-existing operator.
TriedToIndexNumber
The "index" operator was applied to a number type.

View File

@ -1280,6 +1280,21 @@ inline static void float_to_int(struct object *self)
self->u.number.val.intval = self->u.number.val.fpval;
}
// list:
// replace with item at index
static void list_to_item(struct object *self, int index)
{
struct listitem *item;
item = self->u.listhead->next;
while (index) {
item = item->next;
--index;
}
self->u.listhead->u.listinfo.refs--; // FIXME - call some fn for this (and do _after_ next line)
*self = item->u.payload; // FIXME - if item is a list, it would gain a ref by this...
}
// string:
// replace with char at index
static void string_to_byte(struct object *self, int index)
@ -2178,14 +2193,8 @@ static void list_handle_dyadic_operator(struct object *self, const struct op *op
if (get_valid_index(&index, length, self, op, other))
return; // error has been thrown
item = self->u.listhead->next;
while (index) {
item = item->next;
--index;
}
self->u.listhead->u.listinfo.refs--; // FIXME - call some fn for this (and do _after_ next line)
*self = item->u.payload; // FIXME - if item is a list, it would gain a ref by this...
return;
list_to_item(self, index);
return; // ok
case OPID_ADD:
if (other->type != &type_list)
@ -2350,6 +2359,50 @@ static void string_print(const struct object *self, struct dynabuf *db)
DynaBuf_add_string(db, self->u.string->payload); // there is a terminator after the actual payload, so this works
}
// number:
// is not iterable
static int has_no_length(const struct object *self)
{
return -1; // not iterable
}
// list:
// return length
static int list_get_length(const struct object *self)
{
return self->u.listhead->u.listinfo.length;
}
// string:
// return length
static int string_get_length(const struct object *self)
{
return self->u.string->length;
}
// number:
// cannot be indexed
static void cannot_be_indexed(const struct object *self, struct object *target, int index)
{
Bug_found("TriedToIndexNumber", index);
}
// list:
// return item at index
static void list_at(const struct object *self, struct object *target, int index)
{
*target = *self;
list_to_item(target, index);
}
// string:
// return char at index
static void string_at(const struct object *self, struct object *target, int index)
{
*target = *self;
string_to_byte(target, index);
}
// "class" definitions
struct type type_number = {
"number",
@ -2359,7 +2412,9 @@ struct type type_number = {
number_handle_monadic_operator,
number_handle_dyadic_operator,
number_fix_result,
number_print
number_print,
has_no_length,
cannot_be_indexed
};
struct type type_list = {
"list",
@ -2369,7 +2424,9 @@ struct type type_list = {
list_handle_monadic_operator,
list_handle_dyadic_operator,
object_no_op, // no need to fix list results
list_print
list_print,
list_get_length,
list_at
};
struct type type_string = {
"string",
@ -2379,7 +2436,9 @@ struct type type_string = {
string_handle_monadic_operator,
string_handle_dyadic_operator,
object_no_op, // no need to fix string results
string_print
string_print,
string_get_length,
string_at
};

View File

@ -21,6 +21,8 @@ struct type {
void (*dyadic_op)(struct object *self, const struct op *op, struct object *other);
void (*fix_result)(struct object *self);
void (*print)(const struct object *self, struct dynabuf *db);
int (*length)(const struct object *self); // returns -1 if not iterable
void (*at)(const struct object *self, struct object *target, int index);
};
extern struct type type_number;
extern struct type type_list;

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release
#define CHANGE_DATE "22 Oct" // update before release FIXME
#define CHANGE_DATE "23 Oct" // update before release FIXME
#define CHANGE_YEAR "2020" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME