Hash :
157b92d6
Author :
Thomas de Grivel
Date :
2025-03-07T16:27:26
wip ops / pstruct refcount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
/* kc3
* Copyright from 2022 to 2025 kmx.io <contact@kmx.io>
*
* Permission is hereby granted to use this software granted the above
* copyright notice and this permission paragraph are included in all
* copies and substantial portions of this software.
*
* THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
* PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
#include <stdlib.h>
#include "alloc.h"
#include "assert.h"
#include "callable.h"
#include "compare.h"
#include "hash.h"
#include "ht.h"
#include "op.h"
#include "ops.h"
#include "sym.h"
/* Returns true if op was added or is already present. */
s_op * ops_add (s_ops *ops, s_tag *op)
{
assert(ops);
assert(op);
assert(op->sym);
assert(op->arity);
assert(op->associativity == 1 || op->associativity == 2);
assert(op->callable);
assert(op->ref_count > 0);
if (op->special)
callable_set_special(op->callable, true);
return ht_add(&ops->ht, op);
}
void ops_clean (s_ops *ops)
{
assert(ops);
ht_clean(&ops->ht);
}
s8 ops_compare_tag (const s_tag *a, const s_tag *b)
{
s8 r;
if (a == b)
return 0;
if (! a)
return -1;
if (! b)
return 1;
if (a->type != TAG_PSTRUCT ||
a->data.pstruct->type.module != &g_sym_KC3_Op ||
b->type != TAG_PSTRUCT ||
b->data.pstruct->type.module != &g_sym_KC3_Op) {
err_puts("ops_compare_tag: argument is not a %KC3.Op{}");
assert(! "ops_compare_tag: argument is not a %KC3.Op{}");
abort();
}
r = compare_sym(a->sym, b->sym);
if (! r)
r = compare_u8(a->arity, b->arity);
return r;
}
void ops_delete (s_ops *ops)
{
assert(ops);
ops_clean(ops);
free(ops);
}
s_tag * ops_get (s_ops *ops, const s_sym *sym, u8 arity, s_tag *dest)
{
s_op op = {0};
s_tag op_tag = {0};
assert(ops);
if (! sym || ! arity)
return NULL;
op.sym = sym;
op.arity = arity;
if (! tag_init_pstruct_with_data(op_tag, &g_sym_KC3_Op, &op, false))
return NULL;
ht_get(&ops->ht, &);
}
uw ops_hash_op (const s_op *op)
{
t_hash h;
uw u;
hash_init(&h);
hash_update_sym(&h, &op->sym);
hash_update_u8(&h, op->arity);
u = hash_to_uw(&h);
hash_clean(&h);
return u;
}
s_ops * ops_init (s_ops *ops)
{
s_ops tmp = {0};
assert(ops);
if (! ht_init(&tmp.ht, &g_sym_KC3_Op, 256))
return NULL;
tmp.ht.compare = ops_compare_tag;
tmp.ht.hash = ops_hash_tag;
*ops = tmp;
return ops;
}
s_ops * ops_new (void)
{
s_ops *ops;
if (! (ops = alloc(sizeof(s_ops))))
return NULL;
if (! ops_init(ops)) {
free(ops);
return NULL;
}
return ops;
}