diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-07-02 16:53:35 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-07-02 16:53:35 -0700 |
commit | db8aeddade93adde5c9e4e14888fb53a64bdc377 (patch) | |
tree | 6dfd4da1fe1b21f3e57053e19ebfe49a6d7bd0da /ffi.c | |
parent | 3d85925c3f209bed8703e4901ce3a28de89deea4 (diff) | |
download | txr-db8aeddade93adde5c9e4e14888fb53a64bdc377.tar.gz txr-db8aeddade93adde5c9e4e14888fb53a64bdc377.tar.bz2 txr-db8aeddade93adde5c9e4e14888fb53a64bdc377.zip |
ffi: new make-zstruct function and znew macro.
* ffi.c (make_zstruct): New function.
(ffi_init): Register make-zstruct instrinsic.
* ffi.h (make_zstruct): Declared.
* lisplib.c (ffi_set_entries): Add znew to autload list.
* share/txr/stdlib/ffi.tl (znew): New macro.
* txr.1: Documented make-zstruct and znew.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 45 |
1 files changed, 45 insertions, 0 deletions
@@ -5361,6 +5361,50 @@ val union_out(val uni, val memb, val memb_obj) return memb_obj; } +val make_zstruct(val type, struct args *args) +{ + val self = lit("make-zstruct"); + struct txr_ffi_type *tft = ffi_type_struct_checked(type); + val pairs = args_get_list(args); + args_decl(ms_args, 0); + val strct = make_struct(tft->lt, nil, ms_args); + mem_t *zbuf; + char *inited = coerce(char *, zalloca(tft->nelem)); + cnum i, largest; + + if (!tft->memb) + uw_throwf(error_s, lit("~a: ~s isn't a struct type"), self, type, nao); + + for (i = largest = 0; i < tft->nelem; i++) { + cnum size =tft->memb[i].mtft->size; + if (size > largest) + largest = size; + } + + zbuf = coerce(mem_t *, zalloca(largest)); + + while (pairs) { + val sym = pop(&pairs); + val initval = pop(&pairs); + + slotset(strct, sym, initval); + + for (i = 0; i < tft->nelem; i++) + if (tft->memb[i].mname == sym) + inited[i] = 1; + } + + for (i = 0; i < tft->nelem; i++) { + if (!inited[i]) { + struct smemb *m = &tft->memb[i]; + val slsym = m->mname; + val initval = m->mtft->get(m->mtft, zbuf, self); + slotset(strct, slsym, initval); + } + } + + return strct; +} void ffi_init(void) { @@ -5488,6 +5532,7 @@ void ffi_init(void) reg_fun(intern(lit("union-put"), user_package), func_n3(union_put)); reg_fun(intern(lit("union-in"), user_package), func_n3(union_in)); reg_fun(intern(lit("union-out"), user_package), func_n3(union_out)); + reg_fun(intern(lit("make-zstruct"), user_package), func_n1v(make_zstruct)); ffi_typedef_hash = make_hash(nil, nil, nil); ffi_init_types(); ffi_init_extra_types(); |