Edit

kc3-lang/kc3/libc3/tag_init.c

Branch :

  • libc3/tag_init.c
  • #include "alloc.h"
    #include "assert.h"
    #include "array.h"
    #include "buf.h"
    #include "buf_inspect.h"
    #include "buf_parse.h"
    #include "call.h"
    #include "cfn.h"
    #include "compare.h"
    #include "env.h"
    #include "fn.h"
    #include "frame.h"
    #include "hash.h"
    #include "ident.h"
    #include "integer.h"
    #include "list.h"
    #include "map.h"
    #include "ptr.h"
    #include "ptr_free.h"
    #include "quote.h"
    #include "ratio.h"
    #include "str.h"
    #include "struct.h"
    #include "struct_type.h"
    #include "tag.h"
    #include "tag_init.h"
    #include "time.h"
    #include "tuple.h"
    #include "unquote.h"
    #include "var.h"
    
    s_tag * tag_init_array (s_tag *tag, const s_sym *type, uw dimension,
                            const uw *dimensions)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_ARRAY;
      if (! array_init(&tmp.data.array, type, dimension, dimensions))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_array_copy (s_tag *tag, const s_array *a)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_ARRAY;
      if (! array_init_copy(&tmp.data.array, a))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_bool (s_tag *tag, bool b)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_BOOL;
      tmp.data.bool = b;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_call (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_CALL;
      if (! call_init(&tmp.data.call))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_character (s_tag *tag, character c)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_CHARACTER;
      tmp.data.character = c;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_complex (s_tag *tag, s_complex *c)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_COMPLEX;
      tmp.data.complex = c;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_f32 (s_tag *tag, f32 f)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_F32;
      tmp.data.f32 = f;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_f64 (s_tag *tag, f64 f)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_F64;
      tmp.data.f64 = f;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_f128 (s_tag *tag, f128 f)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_F128;
      tmp.data.f128 = f;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_fn_copy (s_tag *tag, const s_fn *fn)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_FN;
      if (! fn_init_copy(&tmp.data.fn, fn))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_ident (s_tag *tag, const s_ident *ident)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_IDENT;
      tmp.data.ident = *ident;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_ident_1 (s_tag *tag, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_IDENT;
      if (! ident_init_1(&tmp.data.ident, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_integer_1 (s_tag *tag, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_INTEGER;
      if (! integer_init_1(&tmp.data.integer, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_integer_copy (s_tag *tag, const s_integer *i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_INTEGER;
      if (! integer_init_copy(&tmp.data.integer, i))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_integer_zero (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_INTEGER;
      if (! integer_init_zero(&tmp.data.integer))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_list (s_tag *tag, s_list *list)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_LIST;
      tmp.data.list = list;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_map (s_tag *tag, uw count)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_MAP;
      if (! map_init(&tmp.data.map, count))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_map_1 (s_tag *tag, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_MAP;
      if (! map_init_1(&tmp.data.map, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_ptr (s_tag *tag, void *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_PTR;
      if (! ptr_init(&tmp.data.ptr, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_ptr_free (s_tag *tag, void *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_PTR_FREE;
      if (! ptr_free_init(&tmp.data.ptr_free, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_quote_copy (s_tag *tag, const s_quote *quote)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_QUOTE;
      if (! quote_init_copy(&tmp.data.quote, quote))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_ratio_1 (s_tag *tag, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_RATIO;
      if (! ratio_init_1(&tmp.data.ratio, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_ratio (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_RATIO;
      if (! ratio_init(&tmp.data.ratio))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_ratio_copy (s_tag *tag, const s_ratio *r)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_RATIO;
      if (! ratio_init_copy(&tmp.data.ratio, r))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_ratio_zero (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_RATIO;
      if (! ratio_init_zero(&tmp.data.ratio))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_s8 (s_tag *tag, s8 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_S8;
      tmp.data.s8 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_s16 (s_tag *tag, s16 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_S16;
      tmp.data.s16 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_s32 (s_tag *tag, s32 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_S32;
      tmp.data.s32 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_s64 (s_tag *tag, s64 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_S64;
      tmp.data.s64 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_str (s_tag *tag, char *p_free, uw size, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_STR;
      if (! str_init(&tmp.data.str, p_free, size, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_str_1 (s_tag *tag, char *p_free, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_STR;
      if (! str_init_1(&tmp.data.str, p_free, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_str_cat (s_tag *tag, const s_str *a, const s_str *b)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_STR;
      if (! str_init_cat(&tmp.data.str, a, b))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_str_empty (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_STR;
      if (! str_init_empty(&tmp.data.str))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_struct (s_tag *tag, const s_sym *module)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_STRUCT;
      if (! struct_init(&tmp.data.struct_, module))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_struct_with_data (s_tag *tag, const s_sym *module,
                                       void *data)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_STRUCT;
      if (! struct_init_with_data(&tmp.data.struct_, module, data))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_struct_type (s_tag *tag, const s_sym *module,
                                  const s_list *spec)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_STRUCT_TYPE;
      if (! struct_type_init(&tmp.data.struct_type, module, spec))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_struct_type_update_clean (s_tag *tag,
                                               const s_struct_type *st,
                                               const s_cfn *clean)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_STRUCT_TYPE;
      if (! struct_type_init_update_clean(&tmp.data.struct_type, st, clean))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_sw (s_tag *tag, sw i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_SW;
      tmp.data.sw = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_sym (s_tag *tag, const s_sym *sym)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_SYM;
      tmp.data.sym = sym;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_tuple (s_tag *tag, uw count)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_TUPLE;
      if (! tuple_init(&tmp.data.tuple, count))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_TUPLE;
      if (! tuple_init_2(&tmp.data.tuple, a, b))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_u8 (s_tag *tag, u8 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_U8;
      tmp.data.u8 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_u16 (s_tag *tag, u16 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_U16;
      tmp.data.u16 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_u32 (s_tag *tag, u32 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_U32;
      tmp.data.u32 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_u64 (s_tag *tag, u64 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_U64;
      tmp.data.u64 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_unquote_copy (s_tag *tag, const s_unquote *unquote)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_UNQUOTE;
      if (! unquote_init_copy(&tmp.data.unquote, unquote))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_uw (s_tag *tag, uw i)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_UW;
      tmp.data.uw = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_var (s_tag *tag, const s_sym *type)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_VAR;
      if (! var_init(&tmp.data.var, type))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_init_void (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tmp.type = TAG_VOID;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_new_array (const s_sym *type, uw dimension,
                           const uw *dimensions)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_ARRAY;
      if (! array_init(&tag->data.array, type, dimension, dimensions)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_array_copy (const s_array *a)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_ARRAY;
      if (! array_init_copy(&tag->data.array, a)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_bool (bool b)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_BOOL;
      tag->data.bool = b;
      return tag;
    }
    
    s_tag * tag_new_call (void)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_CALL;
      if (! call_init(&tag->data.call)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_character (character c)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_CHARACTER;
      tag->data.character = c;
      return tag;
    }
    
    s_tag * tag_new_complex (s_complex *c)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_COMPLEX;
      tag->data.complex = c;
      return tag;
    }
    
    s_tag * tag_new_f32 (f32 f)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_F32;
      tag->data.f32 = f;
      return tag;
    }
    
    s_tag * tag_new_f64 (f64 f)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_F64;
      tag->data.f64 = f;
      return tag;
    }
    
    s_tag * tag_new_f128 (f128 f)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_F128;
      tag->data.f128 = f;
      return tag;
    }
    
    s_tag * tag_new_fn_copy (const s_fn *fn)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_FN;
      if (! fn_init_copy(&tag->data.fn, fn)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_ident (const s_ident *ident)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_IDENT;
      tag->data.ident = *ident;
      return tag;
    }
    
    s_tag * tag_new_ident_1 (const char *p)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_IDENT;
      if (! ident_init_1(&tag->data.ident, p)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_integer_1 (const char *p)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_INTEGER;
      if (! integer_init_1(&tag->data.integer, p)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_integer_copy (const s_integer *i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_INTEGER;
      if (! integer_init_copy(&tag->data.integer, i)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_integer_zero (void)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_INTEGER;
      if (! integer_init_zero(&tag->data.integer)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_list (s_list *list)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_LIST;
      tag->data.list = list;
      return tag;
    }
    
    s_tag * tag_new_map (uw count)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_MAP;
      if (! map_init(&tag->data.map, count)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_map_1 (const char *p)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_MAP;
      if (! map_init_1(&tag->data.map, p)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_ptr (void *p)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_PTR;
      if (! ptr_init(&tag->data.ptr, p)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_ptr_free (void *p)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_PTR_FREE;
      if (! ptr_free_init(&tag->data.ptr_free, p)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_quote_copy (const s_quote *quote)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_QUOTE;
      if (! quote_init_copy(&tag->data.quote, quote)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_ratio_1 (const char *p)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_RATIO;
      if (! ratio_init_1(&tag->data.ratio, p)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_ratio (void)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_RATIO;
      if (! ratio_init(&tag->data.ratio)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_ratio_copy (const s_ratio *r)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_RATIO;
      if (! ratio_init_copy(&tag->data.ratio, r)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_ratio_zero (void)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_RATIO;
      if (! ratio_init_zero(&tag->data.ratio)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_s8 (s8 i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_S8;
      tag->data.s8 = i;
      return tag;
    }
    
    s_tag * tag_new_s16 (s16 i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_S16;
      tag->data.s16 = i;
      return tag;
    }
    
    s_tag * tag_new_s32 (s32 i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_S32;
      tag->data.s32 = i;
      return tag;
    }
    
    s_tag * tag_new_s64 (s64 i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_S64;
      tag->data.s64 = i;
      return tag;
    }
    
    s_tag * tag_new_str (char *p_free, uw size, const char *p)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_STR;
      if (! str_init(&tag->data.str, p_free, size, p)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_str_1 (char *p_free, const char *p)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_STR;
      if (! str_init_1(&tag->data.str, p_free, p)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_str_cat (const s_str *a, const s_str *b)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_STR;
      if (! str_init_cat(&tag->data.str, a, b)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_str_empty (void)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_STR;
      if (! str_init_empty(&tag->data.str)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_struct (const s_sym *module)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_STRUCT;
      if (! struct_init(&tag->data.struct_, module)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_struct_with_data (const s_sym *module, void *data)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_STRUCT;
      if (! struct_init_with_data(&tag->data.struct_, module, data)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_struct_type (const s_sym *module, const s_list *spec)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_STRUCT_TYPE;
      if (! struct_type_init(&tag->data.struct_type, module, spec)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_struct_type_update_clean (const s_struct_type *st,
                                              const s_cfn *clean)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_STRUCT_TYPE;
      if (! struct_type_init_update_clean(&tag->data.struct_type, st,
                                          clean)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_sw (sw i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_SW;
      tag->data.sw = i;
      return tag;
    }
    
    s_tag * tag_new_sym (const s_sym *sym)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_SYM;
      tag->data.sym = sym;
      return tag;
    }
    
    s_tag * tag_new_tuple (uw count)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_TUPLE;
      if (! tuple_init(&tag->data.tuple, count)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_tuple_2 (const s_tag *a, const s_tag *b)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_TUPLE;
      if (! tuple_init_2(&tag->data.tuple, a, b)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_u8 (u8 i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_U8;
      tag->data.u8 = i;
      return tag;
    }
    
    s_tag * tag_new_u16 (u16 i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_U16;
      tag->data.u16 = i;
      return tag;
    }
    
    s_tag * tag_new_u32 (u32 i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_U32;
      tag->data.u32 = i;
      return tag;
    }
    
    s_tag * tag_new_u64 (u64 i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_U64;
      tag->data.u64 = i;
      return tag;
    }
    
    s_tag * tag_new_unquote_copy (const s_unquote *unquote)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_UNQUOTE;
      if (! unquote_init_copy(&tag->data.unquote, unquote)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_uw (uw i)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_UW;
      tag->data.uw = i;
      return tag;
    }
    
    s_tag * tag_new_var (const s_sym *type)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_VAR;
      if (! var_init(&tag->data.var, type)) {
        free(tag);
        return NULL;
      }
      return tag;
    }
    
    s_tag * tag_new_void (void)
    {
      s_tag *tag;
      tag = alloc(sizeof(s_tag));
      if (! tag)
        return NULL;
      tag->type = TAG_VOID;
      return tag;
    }
    
    s_tag * tag_array (s_tag *tag, const s_sym *type, uw dimension,
                       const uw *dimensions)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_ARRAY;
      if (! array_init(&tmp.data.array, type, dimension, dimensions))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_array_copy (s_tag *tag, const s_array *a)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_ARRAY;
      if (! array_init_copy(&tmp.data.array, a))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_bool (s_tag *tag, bool b)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_BOOL;
      tmp.data.bool = b;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_call (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_CALL;
      if (! call_init(&tmp.data.call))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_character (s_tag *tag, character c)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_CHARACTER;
      tmp.data.character = c;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_complex (s_tag *tag, s_complex *c)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_COMPLEX;
      tmp.data.complex = c;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_f32 (s_tag *tag, f32 f)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_F32;
      tmp.data.f32 = f;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_f64 (s_tag *tag, f64 f)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_F64;
      tmp.data.f64 = f;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_f128 (s_tag *tag, f128 f)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_F128;
      tmp.data.f128 = f;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_fn_copy (s_tag *tag, const s_fn *fn)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_FN;
      if (! fn_init_copy(&tmp.data.fn, fn))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_ident (s_tag *tag, const s_ident *ident)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_IDENT;
      tmp.data.ident = *ident;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_ident_1 (s_tag *tag, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_IDENT;
      if (! ident_init_1(&tmp.data.ident, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_integer_1 (s_tag *tag, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_INTEGER;
      if (! integer_init_1(&tmp.data.integer, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_integer_copy (s_tag *tag, const s_integer *i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_INTEGER;
      if (! integer_init_copy(&tmp.data.integer, i))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_integer_zero (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_INTEGER;
      if (! integer_init_zero(&tmp.data.integer))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_list (s_tag *tag, s_list *list)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_LIST;
      tmp.data.list = list;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_map (s_tag *tag, uw count)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_MAP;
      if (! map_init(&tmp.data.map, count))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_map_1 (s_tag *tag, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_MAP;
      if (! map_init_1(&tmp.data.map, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_ptr (s_tag *tag, void *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_PTR;
      if (! ptr_init(&tmp.data.ptr, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_ptr_free (s_tag *tag, void *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_PTR_FREE;
      if (! ptr_free_init(&tmp.data.ptr_free, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_quote_copy (s_tag *tag, const s_quote *quote)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_QUOTE;
      if (! quote_init_copy(&tmp.data.quote, quote))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_ratio_1 (s_tag *tag, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_RATIO;
      if (! ratio_init_1(&tmp.data.ratio, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_ratio (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_RATIO;
      if (! ratio_init(&tmp.data.ratio))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_ratio_copy (s_tag *tag, const s_ratio *r)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_RATIO;
      if (! ratio_init_copy(&tmp.data.ratio, r))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_ratio_zero (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_RATIO;
      if (! ratio_init_zero(&tmp.data.ratio))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_s8 (s_tag *tag, s8 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_S8;
      tmp.data.s8 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_s16 (s_tag *tag, s16 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_S16;
      tmp.data.s16 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_s32 (s_tag *tag, s32 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_S32;
      tmp.data.s32 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_s64 (s_tag *tag, s64 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_S64;
      tmp.data.s64 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_str (s_tag *tag, char *p_free, uw size, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_STR;
      if (! str_init(&tmp.data.str, p_free, size, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_str_1 (s_tag *tag, char *p_free, const char *p)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_STR;
      if (! str_init_1(&tmp.data.str, p_free, p))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_str_cat (s_tag *tag, const s_str *a, const s_str *b)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_STR;
      if (! str_init_cat(&tmp.data.str, a, b))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_str_empty (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_STR;
      if (! str_init_empty(&tmp.data.str))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_struct (s_tag *tag, const s_sym *module)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_STRUCT;
      if (! struct_init(&tmp.data.struct_, module))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_struct_with_data (s_tag *tag, const s_sym *module,
                                  void *data)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_STRUCT;
      if (! struct_init_with_data(&tmp.data.struct_, module, data))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_struct_type (s_tag *tag, const s_sym *module,
                             const s_list *spec)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_STRUCT_TYPE;
      if (! struct_type_init(&tmp.data.struct_type, module, spec))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_struct_type_update_clean (s_tag *tag,
                                          const s_struct_type *st,
                                          const s_cfn *clean)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_STRUCT_TYPE;
      if (! struct_type_init_update_clean(&tmp.data.struct_type, st, clean))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_sw (s_tag *tag, sw i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_SW;
      tmp.data.sw = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_sym (s_tag *tag, const s_sym *sym)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_SYM;
      tmp.data.sym = sym;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_tuple (s_tag *tag, uw count)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_TUPLE;
      if (! tuple_init(&tmp.data.tuple, count))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_TUPLE;
      if (! tuple_init_2(&tmp.data.tuple, a, b))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_u8 (s_tag *tag, u8 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_U8;
      tmp.data.u8 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_u16 (s_tag *tag, u16 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_U16;
      tmp.data.u16 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_u32 (s_tag *tag, u32 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_U32;
      tmp.data.u32 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_u64 (s_tag *tag, u64 i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_U64;
      tmp.data.u64 = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_unquote_copy (s_tag *tag, const s_unquote *unquote)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_UNQUOTE;
      if (! unquote_init_copy(&tmp.data.unquote, unquote))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_uw (s_tag *tag, uw i)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_UW;
      tmp.data.uw = i;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_var (s_tag *tag, const s_sym *type)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_VAR;
      if (! var_init(&tmp.data.var, type))
        return NULL;
      *tag = tmp;
      return tag;
    }
    
    s_tag * tag_void (s_tag *tag)
    {
      s_tag tmp = {0};
      assert(tag);
      tag_clean(tag);
      tmp.type = TAG_VOID;
      *tag = tmp;
      return tag;
    }