Skip to content
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v1.10.3-alpha0

* Add `int.of_type(..)` to convert an ID to a stored intance, pr #466.

# v1.10.2

* Fixed `export()` with wse shortcut (`!`) syntax, issue #465.
Expand Down
1 change: 1 addition & 0 deletions inc/doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@
#define DOC_FUTURE_ELSE DOC_SEE("data-types/future/else")
#define DOC_FUTURE_THEN DOC_SEE("data-types/future/then")
#define DOC_INT_BIT_COUNT DOC_SEE("data-types/int/bit_count")
#define DOC_INT_OF_TYPE DOC_SEE("data-types/int/of_type")
#define DOC_LIST_CHOICE DOC_SEE("data-types/list/choice")
#define DOC_LIST_CLEAR DOC_SEE("data-types/list/clear")
#define DOC_LIST_COPY DOC_SEE("data-types/list/copy")
Expand Down
49 changes: 49 additions & 0 deletions inc/ti/fn/fnoftype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <ti/fn/fn.h>


static int do__f_of_type(ti_query_t * query, cleri_node_t * nd, ex_t * e)
{
const int nargs = fn_get_nargs(nd);
ti_thing_t * thing;
ti_type_t * type;
uint64_t id;

if (!ti_val_is_int(query->rval))
return fn_call_try("of_type", query, nd, e);

if (fn_nargs("of_type", DOC_INT_OF_TYPE, 1, nargs, e))
return e->nr;

id = VINT(query->rval);
ti_val_unsafe_drop(query->rval);
query->rval = NULL;

if (ti_do_statement(query, nd->children, e) ||
fn_arg_str("of_type", DOC_INT_OF_TYPE, 1, query->rval, e))
return e->nr;

type = query->collection
? ti_types_by_raw(query->collection->types, (ti_raw_t *) query->rval)
: NULL;
if (!type)
{
(void) ti_raw_err_not_found((ti_raw_t *) query->rval, "type", e);
return e->nr;
}

if (!(thing = ti_query_thing_from_id(query, id, e)))
return e->nr;

if (thing->type_id != type->type_id)
{
ex_set(e, EX_TYPE_ERROR,
TI_THING_ID" is of type `%s`, not `%s`",
thing->id, ti_val_str((ti_val_t *) thing), type->name);
ti_decref(thing);
return e->nr;
}

ti_val_unsafe_drop(query->rval);
query->rval = (ti_val_t *) thing;
return e->nr;
}
4 changes: 2 additions & 2 deletions inc/ti/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#define TI_VERSION_MAJOR 1
#define TI_VERSION_MINOR 10
#define TI_VERSION_PATCH 2
#define TI_VERSION_PATCH 3

/* The syntax version is used to test compatibility with functions
* using the `ti_nodes_check_syntax()` function */
Expand All @@ -25,7 +25,7 @@
* "-rc0"
* ""
*/
#define TI_VERSION_PRE_RELEASE ""
#define TI_VERSION_PRE_RELEASE "-alpha0"

#define TI_MAINTAINER \
"Jeroen van der Heijden <jeroen@cesbit.com>"
Expand Down
77 changes: 77 additions & 0 deletions itest/test_collection_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6021,6 +6021,83 @@ async def test_bit_count(self, client):
""")
self.assertEqual(res, 42)

async def test_of_type(self, client):
with self.assertRaisesRegex(
LookupError,
'type `nil` has no function `of_type`'):
await client.query('nil.of_type("T");')

with self.assertRaisesRegex(
LookupError,
'function `of_type` is undefined'):
await client.query('of_type("T");')

with self.assertRaisesRegex(
NumArgumentsError,
'function `of_type` takes 1 argument '
'but 0 were given'):
await client.query('(4).of_type();')

with self.assertRaisesRegex(
TypeError,
r'function `of_type` expects argument 1 to be of '
r'type `str` but got type `nil` instead'):
await client.query('(4).of_type(nil);')

with self.assertRaisesRegex(
ValueError,
'type name must follow the naming rules'):
await client.query('(4).of_type("");')

with self.assertRaisesRegex(
LookupError,
'type `T` not found'):
await client.query('(4).of_type("T");')

with self.assertRaisesRegex(
LookupError,
'type `T` not found'):
await client.query('(4).of_type("T");', scope='/t')

t_id, o_id, f_id = await client.query("""//ti
set_type('T', {name: 'str<::unknown>'});
set_type('F', {name: 'str<::unknown>'});
.t = T{};
.o = {};
.f = F{};
[.t.id(), .o.id(), .f.id()];
""")

with self.assertRaisesRegex(
TypeError,
f'#{o_id}` is of type `thing`, not `T`'):
await client.query("""//ti
o_id.of_type(kind);
""", o_id=o_id, kind='T')

with self.assertRaisesRegex(
TypeError,
f'`#{f_id}` is of type `F`, not `T`'):
await client.query("""//ti
f_id.of_type(kind);
""", f_id=f_id, kind='T')

with self.assertRaisesRegex(
LookupError,
'collection `stuff` has no `thing` with id 123456'):
await client.query("""//ti
t_id.of_type(kind);
""", t_id=123456, kind='T')

res = await client.query("""//ti
t_id.of_type(kind);
""", t_id=t_id, kind='T')

self.assertEqual(res, {
"#": t_id,
"name": "unknown",
})

async def test_type_all(self, client):
q = client.query

Expand Down
56 changes: 29 additions & 27 deletions src/ti/qbind.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
#include <ti/fn/fnnodesinfo.h>
#include <ti/fn/fnnow.h>
#include <ti/fn/fnnse.h>
#include <ti/fn/fnoftype.h>
#include <ti/fn/fnone.h>
#include <ti/fn/fnowner.h>
#include <ti/fn/fnpop.h>
Expand Down Expand Up @@ -313,11 +314,11 @@ static void qbind__statement(ti_qbind_t * qbind, cleri_node_t * nd);
*/
enum
{
TOTAL_KEYWORDS = 288,
TOTAL_KEYWORDS = 289,
MIN_WORD_LENGTH = 2,
MAX_WORD_LENGTH = 17,
MIN_HASH_VALUE = 42,
MAX_HASH_VALUE = 831
MAX_HASH_VALUE = 781
};

/*
Expand All @@ -329,32 +330,32 @@ static inline unsigned int qbind__hash(
{
static unsigned short asso_values[] =
{
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 18, 17,
17, 832, 17, 832, 17, 832, 17, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 17, 832, 22, 67, 123,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 18, 17,
17, 782, 18, 782, 18, 782, 17, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 17, 782, 22, 118, 123,
26, 19, 171, 217, 229, 17, 19, 66, 19, 61,
22, 24, 78, 82, 18, 17, 18, 26, 283, 189,
339, 182, 25, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832, 832, 832, 832, 832,
832, 832, 832, 832, 832, 832
22, 24, 78, 82, 18, 17, 18, 26, 233, 189,
339, 182, 25, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
782, 782, 782, 782, 782, 782
};

register unsigned int hval = n;
Expand Down Expand Up @@ -676,6 +677,7 @@ qbind__fmap_t qbind__fn_mapping[TOTAL_KEYWORDS] = {
{.name="now", .fn=do__f_now, ROOT_NE},
{.name="nse", .fn=do__f_nse, XROOT_NSE},
{.name="num_arguments_err", .fn=do__f_num_arguments_err, ROOT_NE},
{.name="of_type", .fn=do__f_of_type, CHAIN_NE},
{.name="one", .fn=do__f_one, CHAIN_NE},
{.name="operation_err", .fn=do__f_operation_err, ROOT_NE},
{.name="overflow_err", .fn=do__f_overflow_err, ROOT_NE},
Expand Down
Loading