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
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# v1.8.2
# v1.8.2-alpha3

* Allow converting `mpdata` to `bytes, issue #427.
* Allow converting `mpdata` to `bytes`, issue #427.
* Fixed: map cache for nested structure not cleared, issue #428.
* Add global `enum` definition, issue #429.
* Add _anonymous_ wrap only type syntax (`&{..}`), pr #430.
* Added `ano()` function, pr #430.
* Definition `*str` now exposes enumerator keys, issue #431.

# v1.8.1

Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ set(SOURCES
src/cleri/tokens.c
src/cleri/version.c
src/ti/access.c
src/ti/ano.c
src/ti/api.c
src/ti/archfile.c
src/ti/archive.c
Expand Down Expand Up @@ -226,6 +227,7 @@ set(SOURCES
src/ti/vint.c
src/ti/vset.c
src/ti/vtask.c
src/ti/wano.c
src/ti/warn.c
src/ti/watch.c
src/ti/web.c
Expand Down
3 changes: 3 additions & 0 deletions grammar/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class LangDef(Grammar):
x_preopr = Regex(r'(\s*~)*(\s*!|\s*[\-+](?=[^0-9]))*')
x_ternary = Token('?')
x_thing = Token('{')
x_ano = Token('&{')
x_template = Token('`')

template = Sequence(
Expand Down Expand Up @@ -81,6 +82,7 @@ class LangDef(Grammar):
chain = Ref()

closure = Sequence(x_closure, List(var), '|', THIS)
t_ano = Sequence(x_ano, List(Sequence(name, ':', Optional(THIS))), '}')

thing = Sequence(x_thing, List(Sequence(name, ':', Optional(THIS))), '}')
array = Sequence(x_array, List(THIS), ']')
Expand Down Expand Up @@ -184,6 +186,7 @@ class LangDef(Grammar):
t_int,
t_string,
t_regex,
t_ano,
# end immutable values
template,
var_opt_more,
Expand Down
1 change: 1 addition & 0 deletions inc/doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

/* Collection API */
#define DOC_ALT_RAISE DOC_SEE("collection-api/alt_raise")
#define DOC_ANO DOC_SEE("collection-api/ano")
#define DOC_ASSERT DOC_SEE("collection-api/assert")
#define DOC_BASE64_DECODE DOC_SEE("collection-api/base64_decode")
#define DOC_BASE64_ENCODE DOC_SEE("collection-api/base64_encode")
Expand Down
2 changes: 2 additions & 0 deletions inc/doc.inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ static inline const char * doc_copy(ti_val_t * val)
case TI_VAL_WRAP: return DOC_WTYPE_COPY;
case TI_VAL_ARR: return DOC_LIST_COPY;
case TI_VAL_SET: return DOC_SET_COPY;
case TI_VAL_WANO: return DOC_WTYPE_COPY;
default: return NULL;
}
}
Expand All @@ -157,6 +158,7 @@ static inline const char * doc_dup(ti_val_t * val)
case TI_VAL_WRAP: return DOC_WTYPE_DUP;
case TI_VAL_ARR: return DOC_LIST_DUP;
case TI_VAL_SET: return DOC_SET_DUP;
case TI_VAL_WANO: return DOC_WTYPE_DUP;
default: return NULL;
}
}
Expand Down
4 changes: 3 additions & 1 deletion inc/langdef/langdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* should be used with the libcleri module.
*
* Source class: LangDef
* Created at: 2024-02-11 20:55:25
* Created at: 2025-11-07 13:13:19
*/
#ifndef CLERI_EXPORT_LANGDEF_H_
#define CLERI_EXPORT_LANGDEF_H_
Expand Down Expand Up @@ -58,6 +58,7 @@ enum cleri_grammar_ids {
CLERI_GID_STATEMENT,
CLERI_GID_TEMPLATE,
CLERI_GID_THING,
CLERI_GID_T_ANO,
CLERI_GID_T_FALSE,
CLERI_GID_T_FLOAT,
CLERI_GID_T_INT,
Expand All @@ -67,6 +68,7 @@ enum cleri_grammar_ids {
CLERI_GID_T_TRUE,
CLERI_GID_VAR,
CLERI_GID_VAR_OPT_MORE,
CLERI_GID_X_ANO,
CLERI_GID_X_ARRAY,
CLERI_GID_X_ASSIGN,
CLERI_GID_X_BLOCK,
Expand Down
55 changes: 55 additions & 0 deletions inc/ti/ano.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* ti/ano.h
*/
#ifndef TI_ANO_H_
#define TI_ANO_H_

#include <ti/ano.t.h>
#include <ti/val.t.h>
#include <ti/collection.t.h>
#include <util/mpack.h>
#include <ex.h>

#define ANO_T(__x) ((ti_ano_t *) (__x))->type

ti_ano_t * ti_ano_new(void);
int ti_ano_init(
ti_ano_t * ano,
ti_collection_t * collection,
ti_raw_t * spec_raw,
ex_t * e);
ti_ano_t * ti_ano_from_raw(
ti_collection_t * collection,
ti_raw_t * spec_raw,
ex_t * e);
ti_ano_t * ti_ano_create(
ti_collection_t * collection,
const unsigned char * bin,
size_t n,
ex_t * e);
void ti_ano_destroy(ti_ano_t * ano);

static inline int ti_ano_to_client_pk(
ti_ano_t * ano,
msgpack_packer * pk)
{
return mp_pack_append(pk, ano->spec_raw->data, ano->spec_raw->n);
}

static inline _Bool ti_ano_uninitialized(ti_ano_t * ano)
{
return !ano->spec_raw;
}

static inline int ti_ano_to_store_pk(
ti_ano_t * ano,
msgpack_packer * pk)
{
return mp_pack_ext(
pk,
MPACK_EXT_ANO,
ano->spec_raw->data,
ano->spec_raw->n);
}

#endif /* TI_ANO_H_ */
21 changes: 21 additions & 0 deletions inc/ti/ano.t.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* ti/ano.t.h
*/
#ifndef TI_ANO_T_H_
#define TI_ANO_T_H_

typedef struct ti_ano_s ti_ano_t;

#include <ti/type.t.h>
#include <ti/val.t.h>

struct ti_ano_s
{
uint32_t ref;
uint8_t tp;
int:24;
ti_raw_t * spec_raw; /* mpdata, in log use <anonymous> */
ti_type_t * type;
};

#endif /* TI_ANO_T_H_ */
1 change: 1 addition & 0 deletions inc/ti/collection.t.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct ti_collection_s
vec_t * access; /* ti_auth_t */
smap_t * procedures; /* ti_procedure_t */
smap_t * named_rooms; /* weak map for ti_room_t (only named rooms) */
smap_t * ano_types; /* weak map for ti_ano_t */
ti_thing_t * root; /* without extra reference */
ti_types_t * types;
ti_enums_t * enums;
Expand Down
1 change: 1 addition & 0 deletions inc/ti/do.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ int ti_do_prepare_for_loop(ti_query_t * query, cleri_node_t * vars_nd);
int ti_do_init(void);
void ti_do_drop(void);


static inline int ti_do_statement(
ti_query_t * query,
cleri_node_t * nd,
Expand Down
89 changes: 89 additions & 0 deletions inc/ti/fn/fn.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdlib.h>
#include <ti.h>
#include <ti/access.h>
#include <ti/ano.h>
#include <ti/async.h>
#include <ti/auth.h>
#include <ti/closure.h>
Expand Down Expand Up @@ -246,6 +247,23 @@ static inline int fn_arg_str(
return e->nr;
}

static inline int fn_arg_str_ano(
const char * name,
const char * doc,
int argn,
ti_val_t * val,
ex_t * e)
{
if (!ti_val_is_str_ano(val))
ex_set(e, EX_TYPE_ERROR,
"function `%s` expects argument %d to be of "
"type `"TI_VAL_STR_S"` or `"TI_VAL_ANO_S"` "
"but got type `%s` instead%s",
name, argn, ti_val_str(val), doc);
return e->nr;
}


static inline int fn_arg_bytes(
const char * name,
const char * doc,
Expand Down Expand Up @@ -662,6 +680,71 @@ static int fn_call_w_try_n(
return e->nr;
}

static int fn_call_wa_try_n(
const char * name,
size_t n,
ti_query_t * query,
cleri_node_t * nd,
ex_t * e)
{
ti_name_t * name_;
ti_method_t * method;
ti_wano_t * wano = (ti_wano_t *) query->rval;
ti_thing_t * thing = wano->thing;

name_ = ti_names_weak_get_strn(name, n);
if (!name_)
goto no_method_err;

method = ti_type_get_method(wano->ano->type, name_);
if (!method)
goto no_method_err;

ti_incref(thing);
ti_val_unsafe_drop(query->rval);
query->rval = (ti_val_t *) thing;

return ti_method_call(method, wano->ano->type, query, nd, e);

no_method_err:
ex_set(e, EX_LOOKUP_ERROR,
"type `%s` has no method `%.*s`",
wano->ano->type->name, (int) n, name);
return e->nr;
}

static int fn_call_a_try_n(
const char * name,
size_t n,
ti_query_t * query,
cleri_node_t * nd,
ex_t * e)
{
ti_name_t * name_;
ti_method_t * method;
ti_ano_t * ano = (ti_ano_t *) query->rval;

name_ = ti_names_weak_get_strn(name, n);
if (!name_)
goto no_method_err;

method = ti_type_get_method(ano->type, name_);
if (!method)
goto no_method_err;


ti_incref(method->closure);
ti_val_unsafe_drop(query->rval);
query->rval = (ti_val_t *) method->closure;
return fn_call(query, nd, e);

no_method_err:
ex_set(e, EX_LOOKUP_ERROR,
"type `%s` has no method `%.*s`",
ano->type->name, (int) n, name);
return e->nr;
}

static int fn_call_f_try_n(
const char * name,
size_t n,
Expand Down Expand Up @@ -729,6 +812,12 @@ static int fn_call_try_n(
if (ti_val_is_wrap(query->rval))
return fn_call_w_try_n(name, n, query, nd, e);

if (ti_val_is_wano(query->rval))
return fn_call_wa_try_n(name, n, query, nd, e);

if (ti_val_is_ano(query->rval))
return fn_call_a_try_n(name, n, query, nd, e);

if (ti_val_is_module(query->rval))
return fn_call_f_try_n(name, n, query, nd, e);

Expand Down
40 changes: 40 additions & 0 deletions inc/ti/fn/fnano.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <ti/fn/fn.h>

static int do__f_ano(ti_query_t * query, cleri_node_t * nd, ex_t * e)
{
const int nargs = fn_get_nargs(nd);
ti_raw_t * spec_raw;

if (fn_not_collection_scope("ano", query, e) ||
fn_nargs("ano", DOC_ANO, 1, nargs, e) ||
ti_do_statement(query, nd->children, e) ||
fn_arg_thing("ano", DOC_ANO, 1, query->rval, e))
return e->nr;

spec_raw = ti_type_spec_raw_from_thing(
(ti_thing_t *) query->rval,
query->rval,
e);
if (!spec_raw)
return e->nr;

ti_val_unsafe_drop(query->rval);

/* first try cache for equal ano */
query->rval = smap_getn(
query->collection->ano_types,
(const char *) spec_raw->data,
spec_raw->n);

/* if no success, try new one */
if (query->rval)
ti_incref(query->rval);
else
query->rval = (ti_val_t *) ti_ano_from_raw(
query->collection,
spec_raw,
e);

ti_val_unsafe_drop((ti_val_t *) spec_raw);
return e->nr;
}
2 changes: 2 additions & 0 deletions inc/ti/fn/fnclosure.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ static int do__f_closure_new(ti_query_t * query, cleri_node_t * nd, ex_t * e)
case TI_VAL_ERROR:
case TI_VAL_MEMBER:
case TI_VAL_MPDATA:
case TI_VAL_ANO:
case TI_VAL_WANO:
case TI_VAL_FUTURE:
case TI_VAL_MODULE:
ex_set(e, EX_TYPE_ERROR,
Expand Down
2 changes: 1 addition & 1 deletion inc/ti/fn/fncopy.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static int do__f_copy(ti_query_t * query, cleri_node_t * nd, ex_t * e)
query->rval = val;
}

if (ti_val_is_wrap(query->rval) && ti_wrap_cp(query, deep, e))
if (ti_val_is_wrap_wano(query->rval) && ti_wrap_cp(query, deep, e))
return e->nr; /* quit without fail0, e is set*/
else if (ti_val_copy(&query->rval, NULL, NULL, deep))
ex_set_mem(e);
Expand Down
Loading