Rename TypeInfo -> TypeInfo_t and fix up some typeinfo code
This commit is contained in:
parent
2ba07c2cf5
commit
1a6ce0047b
10
compile.c
10
compile.c
@ -270,7 +270,7 @@ CORD compile_type(type_t *t)
|
||||
compiler_err(NULL, NULL, NULL, "Optional types are not supported for: %T", t);
|
||||
}
|
||||
}
|
||||
case TypeInfoType: return "TypeInfo";
|
||||
case TypeInfoType: return "TypeInfo_t";
|
||||
default: compiler_err(NULL, NULL, NULL, "Compiling type is not implemented for type with tag %d", t->tag);
|
||||
}
|
||||
}
|
||||
@ -751,7 +751,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
}
|
||||
case LangDef: {
|
||||
auto def = Match(ast, LangDef);
|
||||
CORD_appendf(&env->code->typeinfos, "public const TypeInfo %r%s = {%zu, %zu, {.tag=TextInfo, .TextInfo={%r}}};\n",
|
||||
CORD_appendf(&env->code->typeinfos, "public const TypeInfo_t %r%s = {%zu, %zu, {.tag=TextInfo, .TextInfo={%r}}};\n",
|
||||
namespace_prefix(env, env->namespace), def->name, sizeof(Text_t), __alignof__(Text_t),
|
||||
CORD_quoted(def->name));
|
||||
compile_namespace(env, def->name, def->namespace);
|
||||
@ -856,7 +856,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
is_private ? CORD_EMPTY : "public ", ret_type_code, " ", name, arg_signature, "{\n"
|
||||
"static Table_t cache = {};\n",
|
||||
compile_type(args_t), " args = {", all_args, "};\n"
|
||||
"const TypeInfo *table_type = Table$info(", compile_type_info(env, args_t), ", ", compile_type_info(env, ret_t), ");\n",
|
||||
"const TypeInfo_t *table_type = Table$info(", compile_type_info(env, args_t), ", ", compile_type_info(env, ret_t), ");\n",
|
||||
compile_declaration(Type(PointerType, .pointed=ret_t), "cached"), " = Table$get_raw(cache, &args, table_type);\n"
|
||||
"if (cached) return *cached;\n",
|
||||
compile_declaration(ret_t, "ret"), " = ", name, "$uncached(", all_args, ");\n",
|
||||
@ -3467,7 +3467,7 @@ CORD compile_type_info(env_t *env, type_t *t)
|
||||
case OptionalType: {
|
||||
return CORD_asprintf("Optional$info(%r)", compile_type_info(env, Match(t, OptionalType)->type));
|
||||
}
|
||||
case TypeInfoType: return "&TypeInfo$info";
|
||||
case TypeInfoType: return CORD_all("TypeInfo$info(", CORD_quoted(type_to_cord(Match(t, TypeInfoType)->type)), ")");
|
||||
case MemoryType: return "&Memory$info";
|
||||
case VoidType: return "&Void$info";
|
||||
default:
|
||||
@ -3723,7 +3723,7 @@ CORD compile_statement_header(env_t *env, ast_t *ast)
|
||||
"(text) ((", namespace_prefix(env, env->namespace), def->name, "_t){.length=sizeof(text)-1, .tag=TEXT_ASCII, .ascii=\"\" text})\n"
|
||||
"#define ", namespace_prefix(env, env->namespace), def->name,
|
||||
"s(...) ((", namespace_prefix(env, env->namespace), def->name, "_t)Texts(__VA_ARGS__))\n"
|
||||
"extern const TypeInfo ", full_name, ";\n",
|
||||
"extern const TypeInfo_t ", full_name, ";\n",
|
||||
compile_namespace_header(env, def->name, def->namespace)
|
||||
);
|
||||
}
|
||||
|
@ -3,25 +3,25 @@
|
||||
This language relies on a small set of "metamethods" which define special
|
||||
behavior that is required for all types:
|
||||
|
||||
- `as_text(obj:&(optional)T, colorize=no, type:&TypeInfo)->Text`: a method to
|
||||
- `as_text(obj:&(optional)T, colorize=no, type:&TypeInfo_t)->Text`: a method to
|
||||
convert the type to a string. If `colorize` is `yes`, then the method should
|
||||
include ANSI escape codes for syntax highlighting. If the `obj` pointer is
|
||||
`NULL`, a string representation of the type will be returned instead.
|
||||
|
||||
- `compare(x:&T, y:&T, type:&TypeInfo)->Int32`: Return an integer representing
|
||||
- `compare(x:&T, y:&T, type:&TypeInfo_t)->Int32`: Return an integer representing
|
||||
the result of comparing `x` and `y`, where negative numbers mean `x` is less
|
||||
than `y`, zero means `x` is equal to `y`, and positive numbers mean `x` is
|
||||
greater than `y`. For the purpose of floating point numbers, `NaN` is sorted
|
||||
as greater than any other number value and `NaN` values are compared bitwise
|
||||
between each other.
|
||||
|
||||
- `equals(x:&T, y:&T, type:&TypeInfo)->Bool`: This is the same as comparing two
|
||||
- `equals(x:&T, y:&T, type:&TypeInfo_t)->Bool`: This is the same as comparing two
|
||||
numbers to check for zero, except for some minor differences: floating point
|
||||
`NaN` values are _not_ equal to each other (IEEE 754) and the implementation
|
||||
of `equals` may be faster to compute than `compare` for certain types, such
|
||||
as tables.
|
||||
|
||||
- `hash(x:&T, type:&TypeInfo)->Int32`: Values are hashed when used as keys in a
|
||||
- `hash(x:&T, type:&TypeInfo_t)->Int32`: Values are hashed when used as keys in a
|
||||
table or set. Hashing is consistent with equality, so two values that are
|
||||
equal _must_ hash to the same hash value, ideally in a way that makes it
|
||||
unlikely that two different values will have the same hash value.
|
||||
|
@ -30,7 +30,7 @@ struct foo$Baz_s {
|
||||
};
|
||||
|
||||
extern Int_t foo$my_var;
|
||||
extern const TypeInfo foo$Baz;
|
||||
extern const TypeInfo_t foo$Baz;
|
||||
|
||||
extern Int_t foo$Baz$member;
|
||||
Int_t foo$Baz$frob(struct foo$Baz_s $b);
|
||||
|
18
enums.c
18
enums.c
@ -68,13 +68,13 @@ static CORD compile_compare_method(env_t *env, ast_t *ast)
|
||||
if (!has_extra_data(def->tags)) {
|
||||
// Comparisons are simpler if there is only a tag, no tagged data:
|
||||
return CORD_all("static int ", full_name, "$compare(const ", full_name, "_t *x, const ", full_name,
|
||||
"_t *y, const TypeInfo *info) {\n"
|
||||
"_t *y, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n"
|
||||
"return (x->tag - y->tag);\n"
|
||||
"}\n");
|
||||
}
|
||||
CORD cmp_func = CORD_all("static int ", full_name, "$compare(const ", full_name, "_t *x, const ", full_name,
|
||||
"_t *y, const TypeInfo *info) {\n"
|
||||
"_t *y, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n"
|
||||
"int diff = x->tag - y->tag;\n"
|
||||
"if (diff) return diff;\n"
|
||||
@ -99,13 +99,13 @@ static CORD compile_equals_method(env_t *env, ast_t *ast)
|
||||
if (!has_extra_data(def->tags)) {
|
||||
// Equality is simpler if there is only a tag, no tagged data:
|
||||
return CORD_all("static bool ", full_name, "$equal(const ", full_name, "_t *x, const ", full_name,
|
||||
"_t *y, const TypeInfo *info) {\n"
|
||||
"_t *y, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n"
|
||||
"return (x->tag == y->tag);\n"
|
||||
"}\n");
|
||||
}
|
||||
CORD eq_func = CORD_all("static bool ", full_name, "$equal(const ", full_name, "_t *x, const ", full_name,
|
||||
"_t *y, const TypeInfo *info) {\n"
|
||||
"_t *y, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n"
|
||||
"if (x->tag != y->tag) return no;\n"
|
||||
"switch (x->tag) {\n");
|
||||
@ -128,12 +128,12 @@ static CORD compile_hash_method(env_t *env, ast_t *ast)
|
||||
CORD full_name = CORD_cat(namespace_prefix(env, env->namespace), def->name);
|
||||
if (!has_extra_data(def->tags)) {
|
||||
// Hashing is simpler if there is only a tag, no tagged data:
|
||||
return CORD_all("static uint64_t ", full_name, "$hash(const ", full_name, "_t *obj, const TypeInfo *info) {\n"
|
||||
return CORD_all("static uint64_t ", full_name, "$hash(const ", full_name, "_t *obj, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n"
|
||||
"return siphash24((void*)&obj->tag, sizeof(obj->tag));\n"
|
||||
"\n}\n");
|
||||
}
|
||||
CORD hash_func = CORD_all("static uint64_t ", full_name, "$hash(const ", full_name, "_t *obj, const TypeInfo *info) {\n"
|
||||
CORD hash_func = CORD_all("static uint64_t ", full_name, "$hash(const ", full_name, "_t *obj, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n"
|
||||
"uint64_t hashes[2] = {(uint64_t)obj->tag, 0};\n"
|
||||
"switch (obj->tag) {\n");
|
||||
@ -178,7 +178,7 @@ void compile_enum_def(env_t *env, ast_t *ast)
|
||||
}
|
||||
|
||||
type_t *t = Table$str_get(*env->types, def->name);
|
||||
CORD typeinfo = CORD_asprintf("public const TypeInfo %s = {%zu, %zu, {.tag=EnumInfo, .CustomInfo={",
|
||||
CORD typeinfo = CORD_asprintf("public const TypeInfo_t %s = {%zu, %zu, {.tag=EnumInfo, .CustomInfo={",
|
||||
full_name, type_size(t), type_align(t));
|
||||
|
||||
env->code->funcs = CORD_all(env->code->funcs, compile_str_method(env, ast));
|
||||
@ -225,10 +225,10 @@ CORD compile_enum_header(env_t *env, ast_t *ast)
|
||||
enum_def = CORD_all(enum_def, "};\n};\n");
|
||||
all_defs = CORD_all(all_defs, enum_def);
|
||||
|
||||
all_defs = CORD_all(all_defs, "extern const TypeInfo ", full_name, ";\n");
|
||||
all_defs = CORD_all(all_defs, "extern const TypeInfo_t ", full_name, ";\n");
|
||||
for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
|
||||
all_defs = CORD_all(all_defs,
|
||||
"extern const TypeInfo ", namespace_prefix(env, env->namespace), def->name, "$", tag->name, ";\n");
|
||||
"extern const TypeInfo_t ", namespace_prefix(env, env->namespace), def->name, "$", tag->name, ";\n");
|
||||
if (tag->fields) { // Constructor macros:
|
||||
CORD arg_sig = CORD_EMPTY;
|
||||
for (arg_ast_t *field = tag->fields; field; field = field->next) {
|
||||
|
@ -82,7 +82,7 @@ env_t *new_compilation_unit(CORD libname)
|
||||
const char *name;
|
||||
type_t *type;
|
||||
CORD typename;
|
||||
CORD struct_val;
|
||||
CORD typeinfo;
|
||||
Array_t namespace;
|
||||
} global_types[] = {
|
||||
{"Void", Type(VoidType), "Void_t", "Void$info", {}},
|
||||
@ -385,7 +385,8 @@ env_t *new_compilation_unit(CORD libname)
|
||||
default: break;
|
||||
}
|
||||
if (ns_env == NULL) ns_env = namespace_env(env, global_types[i].name);
|
||||
binding_t *binding = new(binding_t, .type=Type(TypeInfoType, .name=global_types[i].name, .type=global_types[i].type, .env=ns_env));
|
||||
binding_t *binding = new(binding_t, .type=Type(TypeInfoType, .name=global_types[i].name, .type=global_types[i].type, .env=ns_env),
|
||||
.code=global_types[i].typeinfo);
|
||||
Table$str_set(env->globals, global_types[i].name, binding);
|
||||
Table$str_set(env->types, global_types[i].name, global_types[i].type);
|
||||
}
|
||||
|
32
repl.c
32
repl.c
@ -95,7 +95,7 @@ static void repl_err(ast_t *node, const char *fmt, ...)
|
||||
longjmp(on_err, 1);
|
||||
}
|
||||
|
||||
const TypeInfo *type_to_type_info(type_t *t)
|
||||
const TypeInfo_t *type_to_type_info(type_t *t)
|
||||
{
|
||||
switch (t->tag) {
|
||||
case AbortType: return &Abort$info;
|
||||
@ -120,27 +120,27 @@ const TypeInfo *type_to_type_info(type_t *t)
|
||||
}
|
||||
case TextType: return &Text$info;
|
||||
case ArrayType: {
|
||||
const TypeInfo *item_info = type_to_type_info(Match(t, ArrayType)->item_type);
|
||||
const TypeInfo array_info = {.size=sizeof(Array_t), .align=__alignof__(Array_t),
|
||||
const TypeInfo_t *item_info = type_to_type_info(Match(t, ArrayType)->item_type);
|
||||
const TypeInfo_t array_info = {.size=sizeof(Array_t), .align=__alignof__(Array_t),
|
||||
.tag=ArrayInfo, .ArrayInfo.item=item_info};
|
||||
return memcpy(GC_MALLOC(sizeof(TypeInfo)), &array_info, sizeof(TypeInfo));
|
||||
return memcpy(GC_MALLOC(sizeof(TypeInfo_t)), &array_info, sizeof(TypeInfo_t));
|
||||
}
|
||||
case TableType: {
|
||||
const TypeInfo *key_info = type_to_type_info(Match(t, TableType)->key_type);
|
||||
const TypeInfo *value_info = type_to_type_info(Match(t, TableType)->value_type);
|
||||
const TypeInfo table_info = {
|
||||
const TypeInfo_t *key_info = type_to_type_info(Match(t, TableType)->key_type);
|
||||
const TypeInfo_t *value_info = type_to_type_info(Match(t, TableType)->value_type);
|
||||
const TypeInfo_t table_info = {
|
||||
.size=sizeof(Table_t), .align=__alignof__(Table_t),
|
||||
.tag=TableInfo, .TableInfo.key=key_info, .TableInfo.value=value_info};
|
||||
return memcpy(GC_MALLOC(sizeof(TypeInfo)), &table_info, sizeof(TypeInfo));
|
||||
return memcpy(GC_MALLOC(sizeof(TypeInfo_t)), &table_info, sizeof(TypeInfo_t));
|
||||
}
|
||||
case PointerType: {
|
||||
auto ptr = Match(t, PointerType);
|
||||
CORD sigil = ptr->is_stack ? "&" : "@";
|
||||
if (ptr->is_readonly) sigil = CORD_cat(sigil, "%");
|
||||
const TypeInfo *pointed_info = type_to_type_info(ptr->pointed);
|
||||
const TypeInfo pointer_info = {.size=sizeof(void*), .align=__alignof__(void*),
|
||||
const TypeInfo_t *pointed_info = type_to_type_info(ptr->pointed);
|
||||
const TypeInfo_t pointer_info = {.size=sizeof(void*), .align=__alignof__(void*),
|
||||
.tag=PointerInfo, .PointerInfo={.sigil=sigil, .pointed=pointed_info}};
|
||||
return memcpy(GC_MALLOC(sizeof(TypeInfo)), &pointer_info, sizeof(TypeInfo));
|
||||
return memcpy(GC_MALLOC(sizeof(TypeInfo_t)), &pointer_info, sizeof(TypeInfo_t));
|
||||
}
|
||||
default: errx(1, "Unsupported type: %T", t);
|
||||
}
|
||||
@ -210,7 +210,7 @@ static double ast_to_num(env_t *env, ast_t *ast)
|
||||
|
||||
static Text_t obj_to_text(type_t *t, const void *obj, bool use_color)
|
||||
{
|
||||
const TypeInfo *info = type_to_type_info(t);
|
||||
const TypeInfo_t *info = type_to_type_info(t);
|
||||
return generic_as_text(obj, use_color, info);
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ void run(env_t *env, ast_t *ast)
|
||||
// case Index: {
|
||||
// auto index = Match(target->ast, Index);
|
||||
// type_t *obj_t = get_type(env, index->indexed);
|
||||
// TypeInfo *table_info = type_to_type_info(t);
|
||||
// TypeInfo_t *table_info = type_to_type_info(t);
|
||||
// }
|
||||
default: errx(1, "Assignment not implemented: %W", target->ast);
|
||||
}
|
||||
@ -442,7 +442,7 @@ void eval(env_t *env, ast_t *ast, void *dest)
|
||||
type_t *t_lhs = get_type(env, binop->lhs);
|
||||
if (!type_eq(t_lhs, get_type(env, binop->rhs)))
|
||||
repl_err(ast, "Comparisons between different types aren't supported");
|
||||
const TypeInfo *info = type_to_type_info(t_lhs);
|
||||
const TypeInfo_t *info = type_to_type_info(t_lhs);
|
||||
size_t value_size = type_size(t_lhs);
|
||||
char lhs[value_size], rhs[value_size];
|
||||
eval(env, binop->lhs, lhs);
|
||||
@ -488,7 +488,7 @@ void eval(env_t *env, ast_t *ast, void *dest)
|
||||
size_t key_size = type_size(key_type);
|
||||
char key_buf[key_size];
|
||||
eval(env, index->index, key_buf);
|
||||
const TypeInfo *table_info = type_to_type_info(indexed_t);
|
||||
const TypeInfo_t *table_info = type_to_type_info(indexed_t);
|
||||
memcpy(dest, Table$get(table, key_buf, table_info), key_size);
|
||||
break;
|
||||
}
|
||||
@ -524,7 +524,7 @@ void eval(env_t *env, ast_t *ast, void *dest)
|
||||
size_t value_size = type_size(Match(t, TableType)->value_type);
|
||||
char key_buf[key_size] = {};
|
||||
char value_buf[value_size] = {};
|
||||
const TypeInfo *table_info = type_to_type_info(t);
|
||||
const TypeInfo_t *table_info = type_to_type_info(t);
|
||||
assert(table_info->tag == TableInfo);
|
||||
for (ast_list_t *entry = table_ast->entries; entry; entry = entry->next) {
|
||||
auto e = Match(entry->ast, TableEntry);
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "siphash.h"
|
||||
#include "siphash-internals.h"
|
||||
|
||||
PUREFUNC static inline int64_t get_padded_item_size(const TypeInfo *info)
|
||||
PUREFUNC static inline int64_t get_padded_item_size(const TypeInfo_t *info)
|
||||
{
|
||||
int64_t size = info->ArrayInfo.item->size;
|
||||
if (info->ArrayInfo.item->align > 1 && size % info->ArrayInfo.item->align)
|
||||
@ -195,12 +195,12 @@ public void Array$remove_at(Array_t *arr, Int_t int_index, Int_t int_count, int6
|
||||
if (arr->length == 0) arr->data = NULL;
|
||||
}
|
||||
|
||||
public void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeInfo *type)
|
||||
public void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeInfo_t *type)
|
||||
{
|
||||
int64_t padded_item_size = get_padded_item_size(type);
|
||||
const Int_t ZERO = (Int_t){.small=(0<<2)|1};
|
||||
const Int_t ONE = (Int_t){.small=(1<<2)|1};
|
||||
const TypeInfo *item_type = type->ArrayInfo.item;
|
||||
const TypeInfo_t *item_type = type->ArrayInfo.item;
|
||||
for (int64_t i = 0; i < arr->length; ) {
|
||||
if (max_removals.small == ZERO.small) // zero
|
||||
break;
|
||||
@ -214,9 +214,9 @@ public void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, cons
|
||||
}
|
||||
}
|
||||
|
||||
public Int_t Array$find(Array_t arr, void *item, const TypeInfo *type)
|
||||
public Int_t Array$find(Array_t arr, void *item, const TypeInfo_t *type)
|
||||
{
|
||||
const TypeInfo *item_type = type->ArrayInfo.item;
|
||||
const TypeInfo_t *item_type = type->ArrayInfo.item;
|
||||
for (int64_t i = 0; i < arr.length; i++) {
|
||||
if (generic_equal(item, arr.data + i*arr.stride, item_type))
|
||||
return I(i+1);
|
||||
@ -279,10 +279,10 @@ public void *Array$random(Array_t arr)
|
||||
return arr.data + arr.stride*index;
|
||||
}
|
||||
|
||||
public Table_t Array$counts(Array_t arr, const TypeInfo *type)
|
||||
public Table_t Array$counts(Array_t arr, const TypeInfo_t *type)
|
||||
{
|
||||
Table_t counts = {};
|
||||
const TypeInfo count_type = {.size=sizeof(Table_t), .align=__alignof__(Table_t),
|
||||
const TypeInfo_t count_type = {.size=sizeof(Table_t), .align=__alignof__(Table_t),
|
||||
.tag=TableInfo, .TableInfo.key=type->ArrayInfo.item, .TableInfo.value=&Int$info};
|
||||
for (int64_t i = 0; i < arr.length; i++) {
|
||||
void *key = arr.data + i*arr.stride;
|
||||
@ -486,9 +486,9 @@ public Array_t Array$concat(Array_t x, Array_t y, int64_t padded_item_size)
|
||||
};
|
||||
}
|
||||
|
||||
public bool Array$has(Array_t array, void *item, const TypeInfo *type)
|
||||
public bool Array$has(Array_t array, void *item, const TypeInfo_t *type)
|
||||
{
|
||||
const TypeInfo *item_type = type->ArrayInfo.item;
|
||||
const TypeInfo_t *item_type = type->ArrayInfo.item;
|
||||
for (int64_t i = 0; i < array.length; i++) {
|
||||
if (generic_equal(array.data + i*array.stride, item, item_type))
|
||||
return true;
|
||||
@ -501,13 +501,13 @@ public void Array$clear(Array_t *array)
|
||||
*array = (Array_t){.data=0, .length=0};
|
||||
}
|
||||
|
||||
public int32_t Array$compare(const Array_t *x, const Array_t *y, const TypeInfo *type)
|
||||
public int32_t Array$compare(const Array_t *x, const Array_t *y, const TypeInfo_t *type)
|
||||
{
|
||||
// Early out for arrays with the same data, e.g. two copies of the same array:
|
||||
if (x->data == y->data && x->stride == y->stride)
|
||||
return (x->length > y->length) - (x->length < y->length);
|
||||
|
||||
const TypeInfo *item = type->ArrayInfo.item;
|
||||
const TypeInfo_t *item = type->ArrayInfo.item;
|
||||
if (item->tag == PointerInfo || (item->tag == CustomInfo && item->CustomInfo.compare == NULL)) { // data comparison
|
||||
int64_t item_padded_size = type->ArrayInfo.item->size;
|
||||
if (type->ArrayInfo.item->align > 1 && item_padded_size % type->ArrayInfo.item->align)
|
||||
@ -531,17 +531,17 @@ public int32_t Array$compare(const Array_t *x, const Array_t *y, const TypeInfo
|
||||
return (x->length > y->length) - (x->length < y->length);
|
||||
}
|
||||
|
||||
public bool Array$equal(const Array_t *x, const Array_t *y, const TypeInfo *type)
|
||||
public bool Array$equal(const Array_t *x, const Array_t *y, const TypeInfo_t *type)
|
||||
{
|
||||
return x == y || (x->length == y->length && Array$compare(x, y, type) == 0);
|
||||
}
|
||||
|
||||
public Text_t Array$as_text(const Array_t *arr, bool colorize, const TypeInfo *type)
|
||||
public Text_t Array$as_text(const Array_t *arr, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
if (!arr)
|
||||
return Text$concat(Text("["), generic_as_text(NULL, false, type->ArrayInfo.item), Text("]"));
|
||||
|
||||
const TypeInfo *item_type = type->ArrayInfo.item;
|
||||
const TypeInfo_t *item_type = type->ArrayInfo.item;
|
||||
Text_t text = Text("[");
|
||||
for (int64_t i = 0; i < arr->length; i++) {
|
||||
if (i > 0)
|
||||
@ -553,9 +553,9 @@ public Text_t Array$as_text(const Array_t *arr, bool colorize, const TypeInfo *t
|
||||
return text;
|
||||
}
|
||||
|
||||
public uint64_t Array$hash(const Array_t *arr, const TypeInfo *type)
|
||||
public uint64_t Array$hash(const Array_t *arr, const TypeInfo_t *type)
|
||||
{
|
||||
const TypeInfo *item = type->ArrayInfo.item;
|
||||
const TypeInfo_t *item = type->ArrayInfo.item;
|
||||
siphash sh;
|
||||
siphashinit(&sh, sizeof(uint64_t[arr->length]));
|
||||
if (item->tag == PointerInfo || (item->tag == CustomInfo && item->CustomInfo.hash == NULL && item->size == sizeof(void*))) { // Raw data hash
|
||||
|
@ -63,9 +63,9 @@
|
||||
void Array$insert(Array_t *arr, const void *item, Int_t index, int64_t padded_item_size);
|
||||
void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t index, int64_t padded_item_size);
|
||||
void Array$remove_at(Array_t *arr, Int_t index, Int_t count, int64_t padded_item_size);
|
||||
void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeInfo *type);
|
||||
void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeInfo_t *type);
|
||||
#define Array$remove_item_value(arr, item_expr, max, type) ({ __typeof(item_expr) item = item_expr; Array$remove_item(arr, &item, max, type); })
|
||||
Int_t Array$find(Array_t arr, void *item, const TypeInfo *type);
|
||||
Int_t Array$find(Array_t arr, void *item, const TypeInfo_t *type);
|
||||
#define Array$find_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; Array$find(arr, &item, type); })
|
||||
Int_t Array$first(Array_t arr, Closure_t predicate);
|
||||
void Array$sort(Array_t *arr, Closure_t comparison, int64_t padded_item_size);
|
||||
@ -75,20 +75,20 @@ Array_t Array$shuffled(Array_t arr, int64_t padded_item_size);
|
||||
void *Array$random(Array_t arr);
|
||||
#define Array$random_value(arr, t) ({ Array_t _arr = arr; if (_arr.length == 0) fail("Cannot get a random value from an empty array!"); *(t*)Array$random(_arr); })
|
||||
Array_t Array$sample(Array_t arr, Int_t n, Array_t weights, int64_t padded_item_size);
|
||||
Table_t Array$counts(Array_t arr, const TypeInfo *type);
|
||||
Table_t Array$counts(Array_t arr, const TypeInfo_t *type);
|
||||
void Array$clear(Array_t *array);
|
||||
void Array$compact(Array_t *arr, int64_t padded_item_size);
|
||||
PUREFUNC bool Array$has(Array_t array, void *item, const TypeInfo *type);
|
||||
PUREFUNC bool Array$has(Array_t array, void *item, const TypeInfo_t *type);
|
||||
#define Array$has_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; Array$has(arr, &item, type); })
|
||||
PUREFUNC Array_t Array$from(Array_t array, Int_t first);
|
||||
PUREFUNC Array_t Array$to(Array_t array, Int_t last);
|
||||
PUREFUNC Array_t Array$by(Array_t array, Int_t stride, int64_t padded_item_size);
|
||||
PUREFUNC Array_t Array$reversed(Array_t array, int64_t padded_item_size);
|
||||
Array_t Array$concat(Array_t x, Array_t y, int64_t padded_item_size);
|
||||
PUREFUNC uint64_t Array$hash(const Array_t *arr, const TypeInfo *type);
|
||||
PUREFUNC int32_t Array$compare(const Array_t *x, const Array_t *y, const TypeInfo *type);
|
||||
PUREFUNC bool Array$equal(const Array_t *x, const Array_t *y, const TypeInfo *type);
|
||||
Text_t Array$as_text(const Array_t *arr, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC uint64_t Array$hash(const Array_t *arr, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t Array$compare(const Array_t *x, const Array_t *y, const TypeInfo_t *type);
|
||||
PUREFUNC bool Array$equal(const Array_t *x, const Array_t *y, const TypeInfo_t *type);
|
||||
Text_t Array$as_text(const Array_t *arr, bool colorize, const TypeInfo_t *type);
|
||||
void Array$heapify(Array_t *heap, Closure_t comparison, int64_t padded_item_size);
|
||||
void Array$heap_push(Array_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size);
|
||||
#define Array$heap_push_value(heap, _value, comparison, padded_item_size) ({ __typeof(_value) value = _value; Array$heap_push(heap, &value, comparison, padded_item_size); })
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
|
||||
PUREFUNC public Text_t Bool$as_text(const bool *b, bool colorize, const TypeInfo *type)
|
||||
PUREFUNC public Text_t Bool$as_text(const bool *b, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
if (!b) return Text("Bool");
|
||||
@ -44,7 +44,7 @@ public Bool_t Bool$random(double p)
|
||||
return (drand48() < p);
|
||||
}
|
||||
|
||||
public const TypeInfo Bool$info = {
|
||||
public const TypeInfo_t Bool$info = {
|
||||
.size=sizeof(bool),
|
||||
.align=__alignof__(bool),
|
||||
.tag=CustomInfo,
|
||||
|
@ -13,10 +13,10 @@
|
||||
#define yes (Bool_t)true
|
||||
#define no (Bool_t)false
|
||||
|
||||
PUREFUNC Text_t Bool$as_text(const bool *b, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC Text_t Bool$as_text(const bool *b, bool colorize, const TypeInfo_t *type);
|
||||
OptionalBool_t Bool$from_text(Text_t text);
|
||||
Bool_t Bool$random(double p);
|
||||
|
||||
extern const TypeInfo Bool$info;
|
||||
extern const TypeInfo_t Bool$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -10,7 +10,7 @@
|
||||
public const Byte_t Byte$min = 0;
|
||||
public const Byte_t Byte$max = UINT8_MAX;
|
||||
|
||||
PUREFUNC public Text_t Byte$as_text(const Byte_t *b, bool colorize, const TypeInfo *type)
|
||||
PUREFUNC public Text_t Byte$as_text(const Byte_t *b, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
if (!b) return Text("Byte");
|
||||
@ -28,7 +28,7 @@ public Byte_t Byte$random(Byte_t min, Byte_t max)
|
||||
return (Byte_t)(min + r);
|
||||
}
|
||||
|
||||
public const TypeInfo Byte$info = {
|
||||
public const TypeInfo_t Byte$info = {
|
||||
.size=sizeof(Byte_t),
|
||||
.align=__alignof__(Byte_t),
|
||||
.tag=CustomInfo,
|
||||
|
@ -11,13 +11,13 @@
|
||||
#define Byte_t uint8_t
|
||||
#define Byte(b) ((Byte_t)(b))
|
||||
|
||||
PUREFUNC Text_t Byte$as_text(const Byte_t *b, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC Text_t Byte$as_text(const Byte_t *b, bool colorize, const TypeInfo_t *type);
|
||||
Byte_t Byte$random(Byte_t min, Byte_t max);
|
||||
|
||||
extern const Byte_t Byte$min;
|
||||
extern const Byte_t Byte$max;
|
||||
|
||||
extern const TypeInfo Byte$info;
|
||||
extern const TypeInfo_t Byte$info;
|
||||
|
||||
typedef struct {
|
||||
Byte_t value;
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "siphash.h"
|
||||
#include "util.h"
|
||||
|
||||
public Text_t CString$as_text(const char **c_string, bool colorize, const TypeInfo *info)
|
||||
public Text_t CString$as_text(const char **c_string, bool colorize, const TypeInfo_t *info)
|
||||
{
|
||||
(void)info;
|
||||
if (!c_string) return Text("CString");
|
||||
@ -45,7 +45,7 @@ PUREFUNC public uint64_t CString$hash(const char **c_str)
|
||||
return siphash24((void*)*c_str, strlen(*c_str));
|
||||
}
|
||||
|
||||
public const TypeInfo CString$info = {
|
||||
public const TypeInfo_t CString$info = {
|
||||
.size=sizeof(char*),
|
||||
.align=__alignof__(char*),
|
||||
.tag=CStringInfo,
|
||||
|
@ -7,12 +7,12 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
Text_t CString$as_text(char **str, bool colorize, const TypeInfo *info);
|
||||
Text_t CString$as_text(char **str, bool colorize, const TypeInfo_t *info);
|
||||
Text_t CString$as_text_simple(const char *str);
|
||||
PUREFUNC int CString$compare(const char **x, const char **y);
|
||||
PUREFUNC bool CString$equal(const char **x, const char **y);
|
||||
PUREFUNC uint64_t CString$hash(const char **str);
|
||||
|
||||
extern const TypeInfo CString$info;
|
||||
extern const TypeInfo_t CString$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -99,27 +99,27 @@ public void Channel$clear(Channel_t *channel)
|
||||
(void)pthread_cond_signal(&channel->cond);
|
||||
}
|
||||
|
||||
PUREFUNC public uint64_t Channel$hash(Channel_t **channel, const TypeInfo *type)
|
||||
PUREFUNC public uint64_t Channel$hash(Channel_t **channel, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
return siphash24((void*)*channel, sizeof(Channel_t*));
|
||||
}
|
||||
|
||||
PUREFUNC public int32_t Channel$compare(Channel_t **x, Channel_t **y, const TypeInfo *type)
|
||||
PUREFUNC public int32_t Channel$compare(Channel_t **x, Channel_t **y, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
return (*x > *y) - (*x < *y);
|
||||
}
|
||||
|
||||
PUREFUNC public bool Channel$equal(Channel_t **x, Channel_t **y, const TypeInfo *type)
|
||||
PUREFUNC public bool Channel$equal(Channel_t **x, Channel_t **y, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
return (*x == *y);
|
||||
}
|
||||
|
||||
public Text_t Channel$as_text(Channel_t **channel, bool colorize, const TypeInfo *type)
|
||||
public Text_t Channel$as_text(Channel_t **channel, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
const TypeInfo *item_type = type->ChannelInfo.item;
|
||||
const TypeInfo_t *item_type = type->ChannelInfo.item;
|
||||
if (!channel) {
|
||||
Text_t typename = generic_as_text(NULL, false, item_type);
|
||||
return Text$concat(colorize ? Text("\x1b[34;1m|:") : Text("|:"), typename, colorize ? Text("|\x1b[m") : Text("|"));
|
||||
|
@ -20,9 +20,9 @@ void Channel$peek(Channel_t *channel, void *out, bool front, int64_t item_size);
|
||||
#define Channel$peek_value(channel, front, t) ({ t _val; Channel$peek(channel, &_val, front, sizeof(t)); _val; })
|
||||
void Channel$clear(Channel_t *channel);
|
||||
Array_t Channel$view(Channel_t *channel);
|
||||
PUREFUNC uint64_t Channel$hash(Channel_t **channel, const TypeInfo *type);
|
||||
PUREFUNC int32_t Channel$compare(Channel_t **x, Channel_t **y, const TypeInfo *type);
|
||||
PUREFUNC bool Channel$equal(Channel_t **x, Channel_t **y, const TypeInfo *type);
|
||||
Text_t Channel$as_text(Channel_t **channel, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC uint64_t Channel$hash(Channel_t **channel, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t Channel$compare(Channel_t **x, Channel_t **y, const TypeInfo_t *type);
|
||||
PUREFUNC bool Channel$equal(Channel_t **x, Channel_t **y, const TypeInfo_t *type);
|
||||
Text_t Channel$as_text(Channel_t **channel, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -25,7 +25,7 @@ static OptionalText_t _local_timezone = NULL_TEXT;
|
||||
body; \
|
||||
}})
|
||||
|
||||
public Text_t DateTime$as_text(const DateTime_t *dt, bool colorize, const TypeInfo *type)
|
||||
public Text_t DateTime$as_text(const DateTime_t *dt, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
if (!dt)
|
||||
@ -41,7 +41,7 @@ public Text_t DateTime$as_text(const DateTime_t *dt, bool colorize, const TypeIn
|
||||
return text;
|
||||
}
|
||||
|
||||
PUREFUNC public int32_t DateTime$compare(const DateTime_t *a, const DateTime_t *b, const TypeInfo *type)
|
||||
PUREFUNC public int32_t DateTime$compare(const DateTime_t *a, const DateTime_t *b, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
if (a->tv_sec != b->tv_sec)
|
||||
@ -242,7 +242,7 @@ public Text_t DateTime$get_local_timezone(void)
|
||||
return _local_timezone;
|
||||
}
|
||||
|
||||
public const TypeInfo DateTime$info = {
|
||||
public const TypeInfo_t DateTime$info = {
|
||||
.size=sizeof(DateTime_t),
|
||||
.align=__alignof__(DateTime_t),
|
||||
.tag=CustomInfo,
|
||||
|
@ -10,8 +10,8 @@
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
||||
Text_t DateTime$as_text(const DateTime_t *dt, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC int32_t DateTime$compare(const DateTime_t *a, const DateTime_t *b, const TypeInfo *type);
|
||||
Text_t DateTime$as_text(const DateTime_t *dt, bool colorize, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t DateTime$compare(const DateTime_t *a, const DateTime_t *b, const TypeInfo_t *type);
|
||||
DateTime_t DateTime$now(void);
|
||||
DateTime_t DateTime$new(Int_t year, Int_t month, Int_t day, Int_t hour, Int_t minute, double second, OptionalText_t timezone);
|
||||
DateTime_t DateTime$after(DateTime_t dt, double seconds, double minutes, double hours, Int_t days, Int_t weeks, Int_t months, Int_t years, OptionalText_t timezone);
|
||||
@ -29,7 +29,7 @@ CONSTFUNC DateTime_t DateTime$from_unix_timestamp(Int64_t timestamp);
|
||||
void DateTime$set_local_timezone(OptionalText_t timezone);
|
||||
Text_t DateTime$get_local_timezone(void);
|
||||
|
||||
extern const TypeInfo DateTime$info;
|
||||
extern const TypeInfo_t DateTime$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
||||
|
@ -18,7 +18,7 @@ public Text_t *get_function_name(void *fn)
|
||||
return Table$get(function_names, &fn, Table$info(Function$info("???"), &Text$info));
|
||||
}
|
||||
|
||||
public Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo *type)
|
||||
public Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
(void)fn;
|
||||
Text_t text = Text$from_str(type->FunctionInfo.type_str);
|
||||
|
@ -4,6 +4,6 @@
|
||||
|
||||
void register_function(void *fn, Text_t name);
|
||||
Text_t *get_function_name(void *fn);
|
||||
Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo *type);
|
||||
Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -30,7 +30,7 @@ public Text_t Int$value_as_text(Int_t i) {
|
||||
}
|
||||
}
|
||||
|
||||
public Text_t Int$as_text(const Int_t *i, bool colorize, const TypeInfo *type) {
|
||||
public Text_t Int$as_text(const Int_t *i, bool colorize, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
if (!i) return Text("Int");
|
||||
|
||||
@ -39,7 +39,7 @@ public Text_t Int$as_text(const Int_t *i, bool colorize, const TypeInfo *type) {
|
||||
return text;
|
||||
}
|
||||
|
||||
public PUREFUNC int32_t Int$compare(const Int_t *x, const Int_t *y, const TypeInfo *type) {
|
||||
public PUREFUNC int32_t Int$compare(const Int_t *x, const Int_t *y, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
if (__builtin_expect(((x->small | y->small) & 1) == 0, 0))
|
||||
return x->big == y->big ? 0 : mpz_cmp(*x->big, *y->big);
|
||||
@ -52,7 +52,7 @@ public PUREFUNC int32_t Int$compare_value(const Int_t x, const Int_t y) {
|
||||
return (x.small > y.small) - (x.small < y.small);
|
||||
}
|
||||
|
||||
public PUREFUNC bool Int$equal(const Int_t *x, const Int_t *y, const TypeInfo *type) {
|
||||
public PUREFUNC bool Int$equal(const Int_t *x, const Int_t *y, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
return x->small == y->small || (__builtin_expect(((x->small | y->small) & 1) == 0, 0) && mpz_cmp(*x->big, *y->big) == 0);
|
||||
}
|
||||
@ -61,7 +61,7 @@ public PUREFUNC bool Int$equal_value(const Int_t x, const Int_t y) {
|
||||
return x.small == y.small || (__builtin_expect(((x.small | y.small) & 1) == 0, 0) && mpz_cmp(*x.big, *y.big) == 0);
|
||||
}
|
||||
|
||||
public PUREFUNC uint64_t Int$hash(const Int_t *x, const TypeInfo *type) {
|
||||
public PUREFUNC uint64_t Int$hash(const Int_t *x, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
if (__builtin_expect(x->small & 1, 1)) {
|
||||
int64_t i = (x->small>>2);
|
||||
@ -393,7 +393,7 @@ public Int_t Int$prev_prime(Int_t x)
|
||||
return Int$from_mpz(p);
|
||||
}
|
||||
|
||||
public const TypeInfo Int$info = {
|
||||
public const TypeInfo_t Int$info = {
|
||||
.size=sizeof(Int_t),
|
||||
.align=__alignof__(Int_t),
|
||||
.tag=CustomInfo,
|
||||
@ -407,16 +407,16 @@ public const TypeInfo Int$info = {
|
||||
|
||||
|
||||
#define DEFINE_INT_TYPE(c_type, KindOfInt, fmt, min_val, max_val)\
|
||||
public Text_t KindOfInt ## $as_text(const c_type *i, bool colorize, const TypeInfo *type) { \
|
||||
public Text_t KindOfInt ## $as_text(const c_type *i, bool colorize, const TypeInfo_t *type) { \
|
||||
(void)type; \
|
||||
if (!i) return Text(#KindOfInt); \
|
||||
return Text$format(colorize ? "\x1b[35m%" fmt "\x1b[m" : "%" fmt, *i); \
|
||||
} \
|
||||
public PUREFUNC int32_t KindOfInt ## $compare(const c_type *x, const c_type *y, const TypeInfo *type) { \
|
||||
public PUREFUNC int32_t KindOfInt ## $compare(const c_type *x, const c_type *y, const TypeInfo_t *type) { \
|
||||
(void)type; \
|
||||
return (*x > *y) - (*x < *y); \
|
||||
} \
|
||||
public PUREFUNC bool KindOfInt ## $equal(const c_type *x, const c_type *y, const TypeInfo *type) { \
|
||||
public PUREFUNC bool KindOfInt ## $equal(const c_type *x, const c_type *y, const TypeInfo_t *type) { \
|
||||
(void)type; \
|
||||
return *x == *y; \
|
||||
} \
|
||||
@ -474,7 +474,7 @@ public const TypeInfo Int$info = {
|
||||
} \
|
||||
public const c_type KindOfInt##$min = min_val; \
|
||||
public const c_type KindOfInt##$max = max_val; \
|
||||
public const TypeInfo KindOfInt##$info = { \
|
||||
public const TypeInfo_t KindOfInt##$info = { \
|
||||
.size=sizeof(c_type), \
|
||||
.align=__alignof__(c_type), \
|
||||
.tag=CustomInfo, \
|
||||
|
@ -27,9 +27,9 @@
|
||||
c_type i; \
|
||||
bool is_null:1; \
|
||||
} Optional ## type_name ## _t; \
|
||||
Text_t type_name ## $as_text(const c_type *i, bool colorize, const TypeInfo *type); \
|
||||
PUREFUNC int32_t type_name ## $compare(const c_type *x, const c_type *y, const TypeInfo *type); \
|
||||
PUREFUNC bool type_name ## $equal(const c_type *x, const c_type *y, const TypeInfo *type); \
|
||||
Text_t type_name ## $as_text(const c_type *i, bool colorize, const TypeInfo_t *type); \
|
||||
PUREFUNC int32_t type_name ## $compare(const c_type *x, const c_type *y, const TypeInfo_t *type); \
|
||||
PUREFUNC bool type_name ## $equal(const c_type *x, const c_type *y, const TypeInfo_t *type); \
|
||||
Text_t type_name ## $format(c_type i, Int_t digits); \
|
||||
Text_t type_name ## $hex(c_type i, Int_t digits, bool uppercase, bool prefix); \
|
||||
Text_t type_name ## $octal(c_type i, Int_t digits, bool prefix); \
|
||||
@ -41,7 +41,7 @@
|
||||
return x < min ? min : (x > max ? max : x); \
|
||||
} \
|
||||
extern const c_type type_name ## $min, type_name##$max; \
|
||||
extern const TypeInfo type_name ## $info; \
|
||||
extern const TypeInfo_t type_name ## $info; \
|
||||
static inline c_type type_name ## $divided_by(c_type D, c_type d) { \
|
||||
c_type q = D/d, r = D%d; \
|
||||
if (r < 0) { \
|
||||
@ -80,12 +80,12 @@ DEFINE_INT_TYPE(int8_t, Int8)
|
||||
|
||||
#define OptionalInt_t Int_t
|
||||
|
||||
Text_t Int$as_text(const Int_t *i, bool colorize, const TypeInfo *type);
|
||||
Text_t Int$as_text(const Int_t *i, bool colorize, const TypeInfo_t *type);
|
||||
Text_t Int$value_as_text(Int_t i);
|
||||
PUREFUNC uint64_t Int$hash(const Int_t *x, const TypeInfo *type);
|
||||
PUREFUNC int32_t Int$compare(const Int_t *x, const Int_t *y, const TypeInfo *type);
|
||||
PUREFUNC uint64_t Int$hash(const Int_t *x, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t Int$compare(const Int_t *x, const Int_t *y, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t Int$compare_value(const Int_t x, const Int_t y);
|
||||
PUREFUNC bool Int$equal(const Int_t *x, const Int_t *y, const TypeInfo *type);
|
||||
PUREFUNC bool Int$equal(const Int_t *x, const Int_t *y, const TypeInfo_t *type);
|
||||
PUREFUNC bool Int$equal_value(const Int_t x, const Int_t y);
|
||||
Text_t Int$format(Int_t i, Int_t digits);
|
||||
Text_t Int$hex(Int_t i, Int_t digits, bool uppercase, bool prefix);
|
||||
@ -134,7 +134,7 @@ bool Int$is_prime(Int_t x, Int_t reps);
|
||||
Int_t Int$next_prime(Int_t x);
|
||||
Int_t Int$prev_prime(Int_t x);
|
||||
|
||||
extern const TypeInfo Int$info;
|
||||
extern const TypeInfo_t Int$info;
|
||||
|
||||
static inline Int_t Int$clamped(Int_t x, Int_t low, Int_t high)
|
||||
{
|
||||
|
@ -12,13 +12,13 @@
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
||||
public Text_t Memory__as_text(const void *p, bool colorize, const TypeInfo *type) {
|
||||
public Text_t Memory__as_text(const void *p, bool colorize, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
if (!p) return Text("Memory");
|
||||
return Text$format(colorize ? "\x1b[0;34;1mMemory<%p>\x1b[m" : "Memory<%p>", p);
|
||||
}
|
||||
|
||||
public const TypeInfo Memory$info = {
|
||||
public const TypeInfo_t Memory$info = {
|
||||
.size=0,
|
||||
.align=0,
|
||||
.tag=CustomInfo,
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern const TypeInfo Memory$info;
|
||||
Text_t Memory$as_text(const void *p, bool colorize, const TypeInfo *type);
|
||||
extern const TypeInfo_t Memory$info;
|
||||
Text_t Memory$as_text(const void *p, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "util.h"
|
||||
|
||||
|
||||
PUREFUNC public uint64_t generic_hash(const void *obj, const TypeInfo *type)
|
||||
PUREFUNC public uint64_t generic_hash(const void *obj, const TypeInfo_t *type)
|
||||
{
|
||||
switch (type->tag) {
|
||||
case TextInfo: return Text$hash((void*)obj);
|
||||
@ -35,7 +35,7 @@ PUREFUNC public uint64_t generic_hash(const void *obj, const TypeInfo *type)
|
||||
}
|
||||
}
|
||||
|
||||
PUREFUNC public int32_t generic_compare(const void *x, const void *y, const TypeInfo *type)
|
||||
PUREFUNC public int32_t generic_compare(const void *x, const void *y, const TypeInfo_t *type)
|
||||
{
|
||||
if (x == y) return 0;
|
||||
|
||||
@ -63,7 +63,7 @@ PUREFUNC public int32_t generic_compare(const void *x, const void *y, const Type
|
||||
}
|
||||
}
|
||||
|
||||
PUREFUNC public bool generic_equal(const void *x, const void *y, const TypeInfo *type)
|
||||
PUREFUNC public bool generic_equal(const void *x, const void *y, const TypeInfo_t *type)
|
||||
{
|
||||
if (x == y) return true;
|
||||
|
||||
@ -91,7 +91,7 @@ PUREFUNC public bool generic_equal(const void *x, const void *y, const TypeInfo
|
||||
}
|
||||
}
|
||||
|
||||
public Text_t generic_as_text(const void *obj, bool colorize, const TypeInfo *type)
|
||||
public Text_t generic_as_text(const void *obj, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
switch (type->tag) {
|
||||
case PointerInfo: return Pointer$as_text(obj, colorize, type);
|
||||
@ -114,7 +114,7 @@ public Text_t generic_as_text(const void *obj, bool colorize, const TypeInfo *ty
|
||||
}
|
||||
}
|
||||
|
||||
public int generic_print(const void *obj, bool colorize, const TypeInfo *type)
|
||||
public int generic_print(const void *obj, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
Text_t text = generic_as_text(obj, colorize, type);
|
||||
return Text$print(stdout, text) + printf("\n");
|
||||
|
@ -6,10 +6,10 @@
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
||||
PUREFUNC uint64_t generic_hash(const void *obj, const TypeInfo *type);
|
||||
PUREFUNC int32_t generic_compare(const void *x, const void *y, const TypeInfo *type);
|
||||
PUREFUNC bool generic_equal(const void *x, const void *y, const TypeInfo *type);
|
||||
Text_t generic_as_text(const void *obj, bool colorize, const TypeInfo *type);
|
||||
int generic_print(const void *obj, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC uint64_t generic_hash(const void *obj, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t generic_compare(const void *x, const void *y, const TypeInfo_t *type);
|
||||
PUREFUNC bool generic_equal(const void *x, const void *y, const TypeInfo_t *type);
|
||||
Text_t generic_as_text(const void *obj, bool colorize, const TypeInfo_t *type);
|
||||
int generic_print(const void *obj, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -13,18 +13,18 @@
|
||||
#include "text.h"
|
||||
#include "types.h"
|
||||
|
||||
public PUREFUNC Text_t Num$as_text(const double *f, bool colorize, const TypeInfo *type) {
|
||||
public PUREFUNC Text_t Num$as_text(const double *f, bool colorize, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
if (!f) return Text("Num");
|
||||
return Text$format(colorize ? "\x1b[35m%.16g\x1b[33;2m\x1b[m" : "%.16g", *f);
|
||||
}
|
||||
|
||||
public PUREFUNC int32_t Num$compare(const double *x, const double *y, const TypeInfo *type) {
|
||||
public PUREFUNC int32_t Num$compare(const double *x, const double *y, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
return (*x > *y) - (*x < *y);
|
||||
}
|
||||
|
||||
public PUREFUNC bool Num$equal(const double *x, const double *y, const TypeInfo *type) {
|
||||
public PUREFUNC bool Num$equal(const double *x, const double *y, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
return *x == *y;
|
||||
}
|
||||
@ -83,7 +83,7 @@ public CONSTFUNC bool Num$isinf(double n) { return !!isinf(n); }
|
||||
public CONSTFUNC bool Num$finite(double n) { return !!finite(n); }
|
||||
public CONSTFUNC bool Num$isnan(double n) { return !!isnan(n); }
|
||||
|
||||
public const TypeInfo Num$info = {
|
||||
public const TypeInfo_t Num$info = {
|
||||
.size=sizeof(double),
|
||||
.align=__alignof__(double),
|
||||
.tag=CustomInfo,
|
||||
@ -94,18 +94,18 @@ public const TypeInfo Num$info = {
|
||||
},
|
||||
};
|
||||
|
||||
public PUREFUNC Text_t Num32$as_text(const float *f, bool colorize, const TypeInfo *type) {
|
||||
public PUREFUNC Text_t Num32$as_text(const float *f, bool colorize, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
if (!f) return Text("Num32");
|
||||
return Text$format(colorize ? "\x1b[35m%.8g_f32\x1b[33;2m\x1b[m" : "%.8g_f32", (double)*f);
|
||||
}
|
||||
|
||||
public PUREFUNC int32_t Num32$compare(const float *x, const float *y, const TypeInfo *type) {
|
||||
public PUREFUNC int32_t Num32$compare(const float *x, const float *y, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
return (*x > *y) - (*x < *y);
|
||||
}
|
||||
|
||||
public PUREFUNC bool Num32$equal(const float *x, const float *y, const TypeInfo *type) {
|
||||
public PUREFUNC bool Num32$equal(const float *x, const float *y, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
return *x == *y;
|
||||
}
|
||||
@ -164,7 +164,7 @@ public CONSTFUNC bool Num32$isinf(float n) { return isinf(n); }
|
||||
public CONSTFUNC bool Num32$finite(float n) { return finite(n); }
|
||||
public CONSTFUNC bool Num32$isnan(float n) { return isnan(n); }
|
||||
|
||||
public const TypeInfo Num32$info = {
|
||||
public const TypeInfo_t Num32$info = {
|
||||
.size=sizeof(float),
|
||||
.align=__alignof__(float),
|
||||
.tag=CustomInfo,
|
||||
|
@ -16,9 +16,9 @@
|
||||
#define N32(n) ((float)n)
|
||||
#define N64(n) ((double)n)
|
||||
|
||||
Text_t Num$as_text(const double *f, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC int32_t Num$compare(const double *x, const double *y, const TypeInfo *type);
|
||||
PUREFUNC bool Num$equal(const double *x, const double *y, const TypeInfo *type);
|
||||
Text_t Num$as_text(const double *f, bool colorize, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t Num$compare(const double *x, const double *y, const TypeInfo_t *type);
|
||||
PUREFUNC bool Num$equal(const double *x, const double *y, const TypeInfo_t *type);
|
||||
CONSTFUNC bool Num$near(double a, double b, double ratio, double absolute);
|
||||
Text_t Num$format(double f, Int_t precision);
|
||||
Text_t Num$scientific(double f, Int_t precision);
|
||||
@ -33,11 +33,11 @@ OptionalNum_t Num$from_text(Text_t text);
|
||||
CONSTFUNC static inline double Num$clamped(double x, double low, double high) {
|
||||
return (x <= low) ? low : (x >= high ? high : x);
|
||||
}
|
||||
extern const TypeInfo Num$info;
|
||||
extern const TypeInfo_t Num$info;
|
||||
|
||||
Text_t Num32$as_text(const float *f, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC int32_t Num32$compare(const float *x, const float *y, const TypeInfo *type);
|
||||
PUREFUNC bool Num32$equal(const float *x, const float *y, const TypeInfo *type);
|
||||
Text_t Num32$as_text(const float *f, bool colorize, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t Num32$compare(const float *x, const float *y, const TypeInfo_t *type);
|
||||
PUREFUNC bool Num32$equal(const float *x, const float *y, const TypeInfo_t *type);
|
||||
CONSTFUNC bool Num32$near(float a, float b, float ratio, float absolute);
|
||||
Text_t Num32$format(float f, Int_t precision);
|
||||
Text_t Num32$scientific(float f, Int_t precision);
|
||||
@ -52,7 +52,7 @@ float Num32$nan(Text_t tag);
|
||||
CONSTFUNC static inline float Num32$clamped(float x, float low, float high) {
|
||||
return (x <= low) ? low : (x >= high ? high : x);
|
||||
}
|
||||
extern const TypeInfo Num32$info;
|
||||
extern const TypeInfo_t Num32$info;
|
||||
|
||||
#define Num_to_Num32(n) ((Num32_t)(n))
|
||||
#define Num32_to_Num(n) ((Num_t)(n))
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "threads.h"
|
||||
#include "util.h"
|
||||
|
||||
public PUREFUNC bool is_null(const void *obj, const TypeInfo *non_optional_type)
|
||||
public PUREFUNC bool is_null(const void *obj, const TypeInfo_t *non_optional_type)
|
||||
{
|
||||
if (non_optional_type == &Int$info)
|
||||
return ((Int_t*)obj)->small == 0;
|
||||
@ -58,7 +58,7 @@ public PUREFUNC bool is_null(const void *obj, const TypeInfo *non_optional_type)
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wstack-protector"
|
||||
public Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo *type)
|
||||
public Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
if (!obj)
|
||||
return Text$concat(generic_as_text(obj, colorize, type->OptionalInfo.type), Text("?"));
|
||||
|
@ -24,7 +24,7 @@
|
||||
#define NULL_TEXT ((OptionalText_t){.length=-1})
|
||||
#define NULL_DATETIME ((OptionalDateTime_t){.tv_usec=-1})
|
||||
|
||||
PUREFUNC bool is_null(const void *obj, const TypeInfo *non_optional_type);
|
||||
Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC bool is_null(const void *obj, const TypeInfo_t *non_optional_type);
|
||||
Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -533,7 +533,7 @@ public OptionalClosure_t Path$by_line(Path_t path)
|
||||
return (Closure_t){.fn=(void*)_next_line, .userdata=wrapper};
|
||||
}
|
||||
|
||||
public const TypeInfo Path$info = {
|
||||
public const TypeInfo_t Path$info = {
|
||||
.size=sizeof(Path_t),
|
||||
.align=__alignof__(Path_t),
|
||||
.tag=TextInfo,
|
||||
|
@ -52,7 +52,7 @@ Closure_t Path$by_line(Path_t path);
|
||||
#define Path$compare Text$compare
|
||||
#define Path$equal Text$equal
|
||||
|
||||
extern const TypeInfo Path$info;
|
||||
extern const TypeInfo_t Path$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
||||
|
@ -28,6 +28,6 @@ Text_t Text$map(Text_t text, Pattern_t pattern, Closure_t fn);
|
||||
#define Pattern$compare Text$compare
|
||||
#define Pattern$equal Text$equal
|
||||
|
||||
extern const TypeInfo Pattern$info;
|
||||
extern const TypeInfo_t Pattern$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -17,7 +17,7 @@ typedef struct recursion_s {
|
||||
struct recursion_s *next;
|
||||
} recursion_t;
|
||||
|
||||
public Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo *type) {
|
||||
public Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo_t *type) {
|
||||
auto ptr_info = type->PointerInfo;
|
||||
if (!x) {
|
||||
Text_t typename = generic_as_text(NULL, false, ptr_info.pointed);
|
||||
@ -69,13 +69,13 @@ public Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo *type
|
||||
return text;
|
||||
}
|
||||
|
||||
PUREFUNC public int32_t Pointer$compare(const void *x, const void *y, const TypeInfo *type) {
|
||||
PUREFUNC public int32_t Pointer$compare(const void *x, const void *y, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
const void *xp = *(const void**)x, *yp = *(const void**)y;
|
||||
return (xp > yp) - (xp < yp);
|
||||
}
|
||||
|
||||
PUREFUNC public bool Pointer$equal(const void *x, const void *y, const TypeInfo *type) {
|
||||
PUREFUNC public bool Pointer$equal(const void *x, const void *y, const TypeInfo_t *type) {
|
||||
(void)type;
|
||||
const void *xp = *(const void**)x, *yp = *(const void**)y;
|
||||
return xp == yp;
|
||||
|
@ -8,12 +8,12 @@
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
||||
Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC int32_t Pointer$compare(const void *x, const void *y, const TypeInfo *type);
|
||||
PUREFUNC bool Pointer$equal(const void *x, const void *y, const TypeInfo *type);
|
||||
Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo_t *type);
|
||||
PUREFUNC int32_t Pointer$compare(const void *x, const void *y, const TypeInfo_t *type);
|
||||
PUREFUNC bool Pointer$equal(const void *x, const void *y, const TypeInfo_t *type);
|
||||
|
||||
#define Null(t) (t*)NULL
|
||||
#define POINTER_TYPE(_sigil, _pointed) (&(TypeInfo){\
|
||||
#define POINTER_TYPE(_sigil, _pointed) (&(TypeInfo_t){\
|
||||
.size=sizeof(void*), .align=alignof(void*), .tag=PointerInfo, .PointerInfo.sigil=_sigil, .PointerInfo.pointed=_pointed})
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "util.h"
|
||||
|
||||
|
||||
PUREFUNC static int32_t Range$compare(const Range_t *x, const Range_t *y, const TypeInfo *type)
|
||||
PUREFUNC static int32_t Range$compare(const Range_t *x, const Range_t *y, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
if (x == y) return 0;
|
||||
@ -26,14 +26,14 @@ PUREFUNC static int32_t Range$compare(const Range_t *x, const Range_t *y, const
|
||||
return Int$compare(&x->step, &y->step, &Int$info);
|
||||
}
|
||||
|
||||
PUREFUNC static bool Range$equal(const Range_t *x, const Range_t *y, const TypeInfo *type)
|
||||
PUREFUNC static bool Range$equal(const Range_t *x, const Range_t *y, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
if (x == y) return true;
|
||||
return Int$equal(&x->first, &y->first, &Int$info) && Int$equal(&x->last, &y->last, &Int$info) && Int$equal(&x->step, &y->step, &Int$info);
|
||||
}
|
||||
|
||||
static Text_t Range$as_text(const Range_t *r, bool use_color, const TypeInfo *type)
|
||||
static Text_t Range$as_text(const Range_t *r, bool use_color, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
if (!r) return Text("Range");
|
||||
@ -54,7 +54,7 @@ PUREFUNC public Range_t Range$by(Range_t r, Int_t step)
|
||||
return (Range_t){r.first, r.last, Int$times(step, r.step)};
|
||||
}
|
||||
|
||||
public const TypeInfo Range$info = {sizeof(Range_t), __alignof(Range_t), {.tag=CustomInfo, .CustomInfo={
|
||||
public const TypeInfo_t Range$info = {sizeof(Range_t), __alignof(Range_t), {.tag=CustomInfo, .CustomInfo={
|
||||
.as_text=(void*)Range$as_text,
|
||||
.compare=(void*)Range$compare,
|
||||
.equal=(void*)Range$equal,
|
||||
|
@ -5,6 +5,6 @@
|
||||
PUREFUNC Range_t Range$reversed(Range_t r);
|
||||
PUREFUNC Range_t Range$by(Range_t r, Int_t step);
|
||||
|
||||
extern const TypeInfo Range$info;
|
||||
extern const TypeInfo_t Range$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1
|
||||
|
@ -135,7 +135,7 @@ public OptionalClosure_t Shell$by_line(Shell_t command)
|
||||
return (Closure_t){.fn=(void*)_next_line, .userdata=wrapper};
|
||||
}
|
||||
|
||||
public const TypeInfo Shell$info = {
|
||||
public const TypeInfo_t Shell$info = {
|
||||
.size=sizeof(Shell_t),
|
||||
.align=__alignof__(Shell_t),
|
||||
.tag=TextInfo,
|
||||
|
@ -26,7 +26,7 @@ OptionalText_t Shell$run(Shell_t command);
|
||||
#define Shell$compare Text$compare
|
||||
#define Shell$equal Text$equal
|
||||
|
||||
extern const TypeInfo Shell$info;
|
||||
extern const TypeInfo_t Shell$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
||||
|
@ -40,7 +40,7 @@ public void tomo_init(void)
|
||||
errx(1, "Couldn't set printf specifier");
|
||||
}
|
||||
|
||||
static bool parse_single_arg(const TypeInfo *info, char *arg, void *dest)
|
||||
static bool parse_single_arg(const TypeInfo_t *info, char *arg, void *dest)
|
||||
{
|
||||
while (info->tag == OptionalInfo)
|
||||
info = info->OptionalInfo.type;
|
||||
@ -110,7 +110,7 @@ static bool parse_single_arg(const TypeInfo *info, char *arg, void *dest)
|
||||
}
|
||||
}
|
||||
|
||||
static Array_t parse_array(const TypeInfo *item_info, int n, char *args[])
|
||||
static Array_t parse_array(const TypeInfo_t *item_info, int n, char *args[])
|
||||
{
|
||||
int64_t padded_size = item_info->size;
|
||||
if ((padded_size % item_info->align) > 0)
|
||||
@ -143,7 +143,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
|
||||
}
|
||||
|
||||
for (int s = 0; s < spec_len; s++) {
|
||||
const TypeInfo *non_opt_type = spec[s].type;
|
||||
const TypeInfo_t *non_opt_type = spec[s].type;
|
||||
while (non_opt_type->tag == OptionalInfo)
|
||||
non_opt_type = non_opt_type->OptionalInfo.type;
|
||||
|
||||
@ -171,7 +171,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
|
||||
num_args += 1;
|
||||
}
|
||||
populated_args[s] = true;
|
||||
const TypeInfo *item_type = non_opt_type->tag == ArrayInfo ? non_opt_type->ArrayInfo.item : non_opt_type->TableInfo.key;
|
||||
const TypeInfo_t *item_type = non_opt_type->tag == ArrayInfo ? non_opt_type->ArrayInfo.item : non_opt_type->TableInfo.key;
|
||||
Array_t items = parse_array(item_type, num_args, &argv[i+1]);
|
||||
if (non_opt_type->tag == ArrayInfo) {
|
||||
*(OptionalArray_t*)spec[s].dest = items;
|
||||
@ -211,7 +211,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
|
||||
if (spec[s].name[0] != *f || strlen(spec[s].name) > 1)
|
||||
continue;
|
||||
|
||||
const TypeInfo *non_opt_type = spec[s].type;
|
||||
const TypeInfo_t *non_opt_type = spec[s].type;
|
||||
while (non_opt_type->tag == OptionalInfo)
|
||||
non_opt_type = non_opt_type->OptionalInfo.type;
|
||||
|
||||
@ -225,7 +225,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
|
||||
num_args += 1;
|
||||
}
|
||||
populated_args[s] = true;
|
||||
const TypeInfo *item_type = non_opt_type->tag == ArrayInfo ? non_opt_type->ArrayInfo.item : non_opt_type->TableInfo.key;
|
||||
const TypeInfo_t *item_type = non_opt_type->tag == ArrayInfo ? non_opt_type->ArrayInfo.item : non_opt_type->TableInfo.key;
|
||||
Array_t items = parse_array(item_type, num_args, &argv[i+1]);
|
||||
if (non_opt_type->tag == ArrayInfo) {
|
||||
*(OptionalArray_t*)spec[s].dest = items;
|
||||
@ -279,7 +279,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
|
||||
errx(1, "Extra argument: %s\n%k", argv[i], &usage);
|
||||
}
|
||||
|
||||
const TypeInfo *non_opt_type = spec[s].type;
|
||||
const TypeInfo_t *non_opt_type = spec[s].type;
|
||||
while (non_opt_type->tag == OptionalInfo)
|
||||
non_opt_type = non_opt_type->OptionalInfo.type;
|
||||
|
||||
@ -296,7 +296,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help,
|
||||
num_args += 1;
|
||||
}
|
||||
populated_args[s] = true;
|
||||
const TypeInfo *item_type = non_opt_type->tag == ArrayInfo ? non_opt_type->ArrayInfo.item : non_opt_type->TableInfo.key;
|
||||
const TypeInfo_t *item_type = non_opt_type->tag == ArrayInfo ? non_opt_type->ArrayInfo.item : non_opt_type->TableInfo.key;
|
||||
Array_t items = parse_array(item_type, num_args, &argv[i]);
|
||||
if (non_opt_type->tag == ArrayInfo) {
|
||||
*(OptionalArray_t*)spec[s].dest = items;
|
||||
@ -423,7 +423,7 @@ public void start_test(const char *filename, int64_t start, int64_t end)
|
||||
++TEST_DEPTH;
|
||||
}
|
||||
|
||||
public void end_test(const void *expr, const TypeInfo *type, const char *expected, const char *filename, int64_t start, int64_t end)
|
||||
public void end_test(const void *expr, const TypeInfo_t *type, const char *expected, const char *filename, int64_t start, int64_t end)
|
||||
{
|
||||
(void)filename;
|
||||
(void)start;
|
||||
|
@ -15,7 +15,7 @@ extern bool USE_COLOR;
|
||||
typedef struct {
|
||||
const char *name;
|
||||
bool required;
|
||||
const TypeInfo *type;
|
||||
const TypeInfo_t *type;
|
||||
void *dest;
|
||||
} cli_arg_t;
|
||||
|
||||
@ -29,7 +29,7 @@ __attribute__((format(printf, 4, 5)))
|
||||
_Noreturn void fail_source(const char *filename, int64_t start, int64_t end, const char *fmt, ...);
|
||||
Text_t builtin_last_err();
|
||||
void start_test(const char *filename, int64_t start, int64_t end);
|
||||
void end_test(const void *expr, const TypeInfo *type, const char *expected, const char *filename, int64_t start, int64_t end);
|
||||
void end_test(const void *expr, const TypeInfo_t *type, const char *expected, const char *filename, int64_t start, int64_t end);
|
||||
#define test(expr, typeinfo, expected, start, end) {\
|
||||
start_test(__SOURCE_FILE__, start, end); \
|
||||
auto _expr = expr; \
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
#define GET_ENTRY(t, i) ((t).entries.data + (t).entries.stride*(i))
|
||||
|
||||
static const TypeInfo MemoryPointer = {
|
||||
static const TypeInfo_t MemoryPointer = {
|
||||
.size=sizeof(void*),
|
||||
.align=__alignof__(void*),
|
||||
.tag=PointerInfo,
|
||||
@ -52,14 +52,14 @@ static const TypeInfo MemoryPointer = {
|
||||
},
|
||||
};
|
||||
|
||||
const TypeInfo CStrToVoidStarTable = {
|
||||
const TypeInfo_t CStrToVoidStarTable = {
|
||||
.size=sizeof(Table_t),
|
||||
.align=__alignof__(Table_t),
|
||||
.tag=TableInfo,
|
||||
.TableInfo={.key=&CString$info, .value=&MemoryPointer},
|
||||
};
|
||||
|
||||
PUREFUNC static inline size_t entry_size(const TypeInfo *info)
|
||||
PUREFUNC static inline size_t entry_size(const TypeInfo_t *info)
|
||||
{
|
||||
size_t size = (size_t)info->TableInfo.key->size;
|
||||
if (info->TableInfo.value->align > 1 && size % (size_t)info->TableInfo.value->align)
|
||||
@ -70,12 +70,12 @@ PUREFUNC static inline size_t entry_size(const TypeInfo *info)
|
||||
return size;
|
||||
}
|
||||
|
||||
PUREFUNC static inline size_t entry_align(const TypeInfo *info)
|
||||
PUREFUNC static inline size_t entry_align(const TypeInfo_t *info)
|
||||
{
|
||||
return (size_t)MAX(info->TableInfo.key->align, info->TableInfo.value->align);
|
||||
}
|
||||
|
||||
PUREFUNC static inline size_t value_offset(const TypeInfo *info)
|
||||
PUREFUNC static inline size_t value_offset(const TypeInfo_t *info)
|
||||
{
|
||||
size_t offset = (size_t)info->TableInfo.key->size;
|
||||
if ((size_t)info->TableInfo.value->align > 1 && offset % (size_t)info->TableInfo.value->align)
|
||||
@ -96,7 +96,7 @@ static inline void hshow(const Table_t *t)
|
||||
hdebug("}\n");
|
||||
}
|
||||
|
||||
static void maybe_copy_on_write(Table_t *t, const TypeInfo *type)
|
||||
static void maybe_copy_on_write(Table_t *t, const TypeInfo_t *type)
|
||||
{
|
||||
if (t->entries.data_refcount != 0)
|
||||
Array$compact(&t->entries, (int64_t)entry_size(type));
|
||||
@ -109,7 +109,7 @@ static void maybe_copy_on_write(Table_t *t, const TypeInfo *type)
|
||||
}
|
||||
|
||||
// Return address of value or NULL
|
||||
PUREFUNC public void *Table$get_raw(Table_t t, const void *key, const TypeInfo *type)
|
||||
PUREFUNC public void *Table$get_raw(Table_t t, const void *key, const TypeInfo_t *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
if (!key || !t.bucket_info) return NULL;
|
||||
@ -131,7 +131,7 @@ PUREFUNC public void *Table$get_raw(Table_t t, const void *key, const TypeInfo *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PUREFUNC public void *Table$get(Table_t t, const void *key, const TypeInfo *type)
|
||||
PUREFUNC public void *Table$get(Table_t t, const void *key, const TypeInfo_t *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
for (const Table_t *iter = &t; iter; iter = iter->fallback) {
|
||||
@ -141,7 +141,7 @@ PUREFUNC public void *Table$get(Table_t t, const void *key, const TypeInfo *type
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void Table$set_bucket(Table_t *t, const void *entry, int32_t index, const TypeInfo *type)
|
||||
static void Table$set_bucket(Table_t *t, const void *entry, int32_t index, const TypeInfo_t *type)
|
||||
{
|
||||
assert(t->bucket_info);
|
||||
hshow(t);
|
||||
@ -195,7 +195,7 @@ static void Table$set_bucket(Table_t *t, const void *entry, int32_t index, const
|
||||
hshow(t);
|
||||
}
|
||||
|
||||
static void hashmap_resize_buckets(Table_t *t, uint32_t new_capacity, const TypeInfo *type)
|
||||
static void hashmap_resize_buckets(Table_t *t, uint32_t new_capacity, const TypeInfo_t *type)
|
||||
{
|
||||
if (__builtin_expect(new_capacity > TABLE_MAX_BUCKETS, 0))
|
||||
fail("Table has exceeded the maximum table size (2^31) and cannot grow further!");
|
||||
@ -218,7 +218,7 @@ static void hashmap_resize_buckets(Table_t *t, uint32_t new_capacity, const Type
|
||||
|
||||
// Return address of value
|
||||
#pragma GCC diagnostic ignored "-Wstack-protector"
|
||||
public void *Table$reserve(Table_t *t, const void *key, const void *value, const TypeInfo *type)
|
||||
public void *Table$reserve(Table_t *t, const void *key, const void *value, const TypeInfo_t *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
if (!t || !key) return NULL;
|
||||
@ -277,13 +277,13 @@ public void *Table$reserve(Table_t *t, const void *key, const void *value, const
|
||||
return entry + value_offset(type);
|
||||
}
|
||||
|
||||
public void Table$set(Table_t *t, const void *key, const void *value, const TypeInfo *type)
|
||||
public void Table$set(Table_t *t, const void *key, const void *value, const TypeInfo_t *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
(void)Table$reserve(t, key, value, type);
|
||||
}
|
||||
|
||||
public void Table$remove(Table_t *t, const void *key, const TypeInfo *type)
|
||||
public void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
if (!t || Table$length(*t) == 0) return;
|
||||
@ -387,14 +387,14 @@ public void Table$clear(Table_t *t)
|
||||
memset(t, 0, sizeof(Table_t));
|
||||
}
|
||||
|
||||
public Table_t Table$sorted(Table_t t, const TypeInfo *type)
|
||||
public Table_t Table$sorted(Table_t t, const TypeInfo_t *type)
|
||||
{
|
||||
Closure_t cmp = (Closure_t){.fn=generic_compare, .userdata=(void*)type->TableInfo.key};
|
||||
Array_t entries = Array$sorted(t.entries, cmp, (int64_t)entry_size(type));
|
||||
return Table$from_entries(entries, type);
|
||||
}
|
||||
|
||||
PUREFUNC public bool Table$equal(const Table_t *x, const Table_t *y, const TypeInfo *type)
|
||||
PUREFUNC public bool Table$equal(const Table_t *x, const Table_t *y, const TypeInfo_t *type)
|
||||
{
|
||||
if (x == y) return true;
|
||||
|
||||
@ -408,7 +408,7 @@ PUREFUNC public bool Table$equal(const Table_t *x, const Table_t *y, const TypeI
|
||||
return (Table$compare(x, y, type) == 0);
|
||||
}
|
||||
|
||||
PUREFUNC public int32_t Table$compare(const Table_t *x, const Table_t *y, const TypeInfo *type)
|
||||
PUREFUNC public int32_t Table$compare(const Table_t *x, const Table_t *y, const TypeInfo_t *type)
|
||||
{
|
||||
if (x == y) return 0;
|
||||
|
||||
@ -439,7 +439,7 @@ PUREFUNC public int32_t Table$compare(const Table_t *x, const Table_t *y, const
|
||||
return 0;
|
||||
}
|
||||
|
||||
PUREFUNC public uint64_t Table$hash(const Table_t *t, const TypeInfo *type)
|
||||
PUREFUNC public uint64_t Table$hash(const Table_t *t, const TypeInfo_t *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
// Table hashes are computed as:
|
||||
@ -454,7 +454,7 @@ PUREFUNC public uint64_t Table$hash(const Table_t *t, const TypeInfo *type)
|
||||
return siphash24((void*)&components, sizeof(components));
|
||||
}
|
||||
|
||||
public Text_t Table$as_text(const Table_t *t, bool colorize, const TypeInfo *type)
|
||||
public Text_t Table$as_text(const Table_t *t, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
auto table = type->TableInfo;
|
||||
@ -493,7 +493,7 @@ public Text_t Table$as_text(const Table_t *t, bool colorize, const TypeInfo *typ
|
||||
return text;
|
||||
}
|
||||
|
||||
public Table_t Table$from_entries(Array_t entries, const TypeInfo *type)
|
||||
public Table_t Table$from_entries(Array_t entries, const TypeInfo_t *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
if (entries.length == 0)
|
||||
@ -516,7 +516,7 @@ public Table_t Table$from_entries(Array_t entries, const TypeInfo *type)
|
||||
}
|
||||
|
||||
// Overlap is "set intersection" in formal terms
|
||||
public Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo *type)
|
||||
public Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type)
|
||||
{
|
||||
// Return a table such that t[k]==a[k] for all k such that a:has(k), b:has(k), and a[k]==b[k]
|
||||
Table_t result = {};
|
||||
@ -538,7 +538,7 @@ public Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo *type)
|
||||
}
|
||||
|
||||
// With is "set union" in formal terms
|
||||
public Table_t Table$with(Table_t a, Table_t b, const TypeInfo *type)
|
||||
public Table_t Table$with(Table_t a, Table_t b, const TypeInfo_t *type)
|
||||
{
|
||||
// return a table such that t[k]==b[k] for all k such that b:has(k), and t[k]==a[k] for all k such that a:has(k) and not b:has(k)
|
||||
Table_t result = {};
|
||||
@ -563,7 +563,7 @@ public Table_t Table$with(Table_t a, Table_t b, const TypeInfo *type)
|
||||
}
|
||||
|
||||
// Without is "set difference" in formal terms
|
||||
public Table_t Table$without(Table_t a, Table_t b, const TypeInfo *type)
|
||||
public Table_t Table$without(Table_t a, Table_t b, const TypeInfo_t *type)
|
||||
{
|
||||
// Return a table such that t[k]==a[k] for all k such that not b:has(k) or b[k] != a[k]
|
||||
Table_t result = {};
|
||||
@ -584,7 +584,7 @@ public Table_t Table$without(Table_t a, Table_t b, const TypeInfo *type)
|
||||
return result;
|
||||
}
|
||||
|
||||
PUREFUNC public bool Table$is_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo *type)
|
||||
PUREFUNC public bool Table$is_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type)
|
||||
{
|
||||
if (a.entries.length > b.entries.length || (strict && a.entries.length == b.entries.length))
|
||||
return false;
|
||||
@ -596,7 +596,7 @@ PUREFUNC public bool Table$is_subset_of(Table_t a, Table_t b, bool strict, const
|
||||
return true;
|
||||
}
|
||||
|
||||
PUREFUNC public bool Table$is_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo *type)
|
||||
PUREFUNC public bool Table$is_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type)
|
||||
{
|
||||
return Table$is_subset_of(b, a, strict, type);
|
||||
}
|
||||
|
@ -29,8 +29,8 @@
|
||||
}, Set$info(item_info)); \
|
||||
set; })
|
||||
|
||||
Table_t Table$from_entries(Array_t entries, const TypeInfo *type);
|
||||
void *Table$get(Table_t t, const void *key, const TypeInfo *type);
|
||||
Table_t Table$from_entries(Array_t entries, const TypeInfo_t *type);
|
||||
void *Table$get(Table_t t, const void *key, const TypeInfo_t *type);
|
||||
#define Table$get_optional(table_expr, key_t, val_t, key_expr, nonnull_var, nonnull_expr, null_expr, info_expr) ({ \
|
||||
const Table_t t = table_expr; const key_t k = key_expr; \
|
||||
val_t *nonnull_var = Table$get(t, &k, info_expr); \
|
||||
@ -38,10 +38,10 @@ void *Table$get(Table_t t, const void *key, const TypeInfo *type);
|
||||
#define Table$has_value(table_expr, key_expr, info_expr) ({ \
|
||||
const Table_t t = table_expr; __typeof(key_expr) k = key_expr; \
|
||||
(Table$get(t, &k, info_expr) != NULL); })
|
||||
PUREFUNC void *Table$get_raw(Table_t t, const void *key, const TypeInfo *type);
|
||||
PUREFUNC void *Table$get_raw(Table_t t, const void *key, const TypeInfo_t *type);
|
||||
CONSTFUNC void *Table$entry(Table_t t, int64_t n);
|
||||
void *Table$reserve(Table_t *t, const void *key, const void *value, const TypeInfo *type);
|
||||
void Table$set(Table_t *t, const void *key, const void *value, const TypeInfo *type);
|
||||
void *Table$reserve(Table_t *t, const void *key, const void *value, const TypeInfo_t *type);
|
||||
void Table$set(Table_t *t, const void *key, const void *value, const TypeInfo_t *type);
|
||||
#define Table$set_value(t, key_expr, value_expr, type) ({ __typeof(key_expr) k = key_expr; __typeof(value_expr) v = value_expr; \
|
||||
Table$set(t, &k, &v, type); })
|
||||
#define Table$reserve_value(t, key_expr, type) ({ __typeof(key_expr) k = key_expr; Table$reserve(t, &k, NULL, type); })
|
||||
@ -51,24 +51,24 @@ void Table$set(Table_t *t, const void *key, const void *value, const TypeInfo *t
|
||||
if (val) *val += amount_expr; \
|
||||
else { __typeof(amount_expr) init = amount_expr; Table$set(t, &key, &init, type); } (void)0; })
|
||||
|
||||
void Table$remove(Table_t *t, const void *key, const TypeInfo *type);
|
||||
void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type);
|
||||
#define Table$remove_value(t, key_expr, type) ({ __typeof(key_expr) k = key_expr; Table$remove(t, &k, type); })
|
||||
|
||||
Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo *type);
|
||||
Table_t Table$with(Table_t a, Table_t b, const TypeInfo *type);
|
||||
Table_t Table$without(Table_t a, Table_t b, const TypeInfo *type);
|
||||
PUREFUNC bool Table$is_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo *type);
|
||||
PUREFUNC bool Table$is_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo *type);
|
||||
Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type);
|
||||
Table_t Table$with(Table_t a, Table_t b, const TypeInfo_t *type);
|
||||
Table_t Table$without(Table_t a, Table_t b, const TypeInfo_t *type);
|
||||
PUREFUNC bool Table$is_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type);
|
||||
PUREFUNC bool Table$is_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type);
|
||||
|
||||
void Table$clear(Table_t *t);
|
||||
Table_t Table$sorted(Table_t t, const TypeInfo *type);
|
||||
Table_t Table$sorted(Table_t t, const TypeInfo_t *type);
|
||||
void Table$mark_copy_on_write(Table_t *t);
|
||||
#define TABLE_INCREF(t) ({ ARRAY_INCREF((t).entries); if ((t).bucket_info) (t).bucket_info->data_refcount += ((t).bucket_info->data_refcount < TABLE_MAX_DATA_REFCOUNT); })
|
||||
#define TABLE_COPY(t) ({ TABLE_INCREF(t); t; })
|
||||
PUREFUNC int32_t Table$compare(const Table_t *x, const Table_t *y, const TypeInfo *type);
|
||||
PUREFUNC bool Table$equal(const Table_t *x, const Table_t *y, const TypeInfo *type);
|
||||
PUREFUNC uint64_t Table$hash(const Table_t *t, const TypeInfo *type);
|
||||
Text_t Table$as_text(const Table_t *t, bool colorize, const TypeInfo *type);
|
||||
PUREFUNC int32_t Table$compare(const Table_t *x, const Table_t *y, const TypeInfo_t *type);
|
||||
PUREFUNC bool Table$equal(const Table_t *x, const Table_t *y, const TypeInfo_t *type);
|
||||
PUREFUNC uint64_t Table$hash(const Table_t *t, const TypeInfo_t *type);
|
||||
Text_t Table$as_text(const Table_t *t, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
CONSTFUNC void *Table$str_entry(Table_t t, int64_t n);
|
||||
PUREFUNC void *Table$str_get(Table_t t, const char *key);
|
||||
@ -79,6 +79,6 @@ void Table$str_remove(Table_t *t, const char *key);
|
||||
|
||||
#define Table$length(t) ((t).entries.length)
|
||||
|
||||
extern const TypeInfo CStrToVoidStarTable;
|
||||
extern const TypeInfo_t CStrToVoidStarTable;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1
|
||||
|
@ -104,14 +104,14 @@ PUREFUNC static uint64_t grapheme_hash(ucs4_t **g) {
|
||||
return siphash24((void*)&cluster[1], sizeof(ucs4_t[cluster[0]]));
|
||||
}
|
||||
|
||||
static const TypeInfo GraphemeClusterInfo = {
|
||||
static const TypeInfo_t GraphemeClusterInfo = {
|
||||
.size=sizeof(ucs4_t*),
|
||||
.align=__alignof__(ucs4_t*),
|
||||
.tag=CustomInfo,
|
||||
.CustomInfo={.equal=(void*)graphemes_equal, .hash=(void*)grapheme_hash},
|
||||
};
|
||||
|
||||
static const TypeInfo GraphemeIDLookupTableInfo = {
|
||||
static const TypeInfo_t GraphemeIDLookupTableInfo = {
|
||||
.size=sizeof(Table_t), .align=__alignof__(Table_t),
|
||||
.tag=TableInfo, .TableInfo={.key=&GraphemeClusterInfo, .value=&Int32$info},
|
||||
};
|
||||
@ -1097,7 +1097,7 @@ static inline Text_t _quoted(Text_t text, bool colorize, char quote_char)
|
||||
#undef add_escaped
|
||||
}
|
||||
|
||||
public Text_t Text$as_text(const void *text, bool colorize, const TypeInfo *info)
|
||||
public Text_t Text$as_text(const void *text, bool colorize, const TypeInfo_t *info)
|
||||
{
|
||||
(void)info;
|
||||
if (info->TextInfo.lang && streq(info->TextInfo.lang, "Path")) {
|
||||
@ -1313,7 +1313,7 @@ public Array_t Text$lines(Text_t text)
|
||||
return lines;
|
||||
}
|
||||
|
||||
public const TypeInfo Text$info = {
|
||||
public const TypeInfo_t Text$info = {
|
||||
.size=sizeof(Text_t),
|
||||
.align=__alignof__(Text_t),
|
||||
.tag=TextInfo,
|
||||
@ -1350,7 +1350,7 @@ public Pattern_t Pattern$escape_text(Text_t text)
|
||||
#undef add_escaped
|
||||
}
|
||||
|
||||
public const TypeInfo Pattern$info = {
|
||||
public const TypeInfo_t Pattern$info = {
|
||||
.size=sizeof(Pattern_t),
|
||||
.align=__alignof__(Pattern_t),
|
||||
.tag=TextInfo,
|
||||
|
@ -37,7 +37,7 @@ PUREFUNC bool Text$equal_ignoring_case(Text_t a, Text_t b);
|
||||
Text_t Text$upper(Text_t text);
|
||||
Text_t Text$lower(Text_t text);
|
||||
Text_t Text$title(Text_t text);
|
||||
Text_t Text$as_text(const void *text, bool colorize, const TypeInfo *info);
|
||||
Text_t Text$as_text(const void *text, bool colorize, const TypeInfo_t *info);
|
||||
Text_t Text$quoted(Text_t str, bool colorize);
|
||||
PUREFUNC bool Text$starts_with(Text_t text, Text_t prefix);
|
||||
PUREFUNC bool Text$ends_with(Text_t text, Text_t suffix);
|
||||
@ -63,6 +63,6 @@ static inline int32_t Text$get_grapheme(Text_t text, int64_t index)
|
||||
return Text$get_grapheme_fast(&state, index);
|
||||
}
|
||||
|
||||
extern const TypeInfo Text$info;
|
||||
extern const TypeInfo_t Text$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -38,7 +38,7 @@ public void Thread$detach(Thread_t thread)
|
||||
pthread_detach(*thread);
|
||||
}
|
||||
|
||||
Text_t Thread$as_text(const Thread_t *thread, bool colorize, const TypeInfo *type)
|
||||
Text_t Thread$as_text(const Thread_t *thread, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
(void)type;
|
||||
if (!thread) {
|
||||
@ -47,7 +47,7 @@ Text_t Thread$as_text(const Thread_t *thread, bool colorize, const TypeInfo *typ
|
||||
return Text$format(colorize ? "\x1b[34;1mThread(%p)\x1b[m" : "Thread(%p)", *thread);
|
||||
}
|
||||
|
||||
public const TypeInfo Thread$info = {
|
||||
public const TypeInfo_t Thread$info = {
|
||||
.size=sizeof(Thread_t), .align=__alignof(Thread_t),
|
||||
.tag=CustomInfo,
|
||||
.CustomInfo={.as_text=(void*)Thread$as_text},
|
||||
|
@ -15,8 +15,8 @@ Thread_t Thread$new(Closure_t fn);
|
||||
void Thread$cancel(Thread_t thread);
|
||||
void Thread$join(Thread_t thread);
|
||||
void Thread$detach(Thread_t thread);
|
||||
Text_t Thread$as_text(const Thread_t *thread, bool colorize, const TypeInfo *type);
|
||||
Text_t Thread$as_text(const Thread_t *thread, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
extern const TypeInfo Thread$info;
|
||||
extern const TypeInfo_t Thread$info;
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -12,9 +12,9 @@
|
||||
#include "text.h"
|
||||
#include "types.h"
|
||||
|
||||
public Text_t Type$as_text(const void *typeinfo, bool colorize, const TypeInfo *type)
|
||||
public Text_t Type$as_text(const void *typeinfo, bool colorize, const TypeInfo_t *type)
|
||||
{
|
||||
if (!typeinfo) return Text("TypeInfo");
|
||||
if (!typeinfo) return Text("TypeInfo_t");
|
||||
|
||||
if (colorize)
|
||||
return Text$concat(
|
||||
@ -25,14 +25,7 @@ public Text_t Type$as_text(const void *typeinfo, bool colorize, const TypeInfo *
|
||||
return Text$from_str(type->TypeInfoInfo.type_str);
|
||||
}
|
||||
|
||||
public const TypeInfo TypeInfo$info = {
|
||||
.size=sizeof(TypeInfo),
|
||||
.align=__alignof__(TypeInfo),
|
||||
.tag=CustomInfo,
|
||||
.TypeInfoInfo.type_str="TypeInfo",
|
||||
};
|
||||
|
||||
public const TypeInfo Void$info = {.size=0, .align=0, .tag=EmptyStructInfo};
|
||||
public const TypeInfo Abort$info = {.size=0, .align=0, .tag=EmptyStructInfo};
|
||||
public const TypeInfo_t Void$info = {.size=0, .align=0, .tag=EmptyStructInfo};
|
||||
public const TypeInfo_t Abort$info = {.size=0, .align=0, .tag=EmptyStructInfo};
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -7,14 +7,14 @@
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
struct TypeInfo;
|
||||
struct TypeInfo_t;
|
||||
|
||||
typedef uint64_t (*hash_fn_t)(const void*, const struct TypeInfo*);
|
||||
typedef int32_t (*compare_fn_t)(const void*, const void*, const struct TypeInfo*);
|
||||
typedef bool (*equal_fn_t)(const void*, const void*, const struct TypeInfo*);
|
||||
typedef Text_t (*text_fn_t)(const void*, bool, const struct TypeInfo*);
|
||||
typedef uint64_t (*hash_fn_t)(const void*, const struct TypeInfo_t*);
|
||||
typedef int32_t (*compare_fn_t)(const void*, const void*, const struct TypeInfo_t*);
|
||||
typedef bool (*equal_fn_t)(const void*, const void*, const struct TypeInfo_t*);
|
||||
typedef Text_t (*text_fn_t)(const void*, bool, const struct TypeInfo_t*);
|
||||
|
||||
typedef struct TypeInfo {
|
||||
typedef struct TypeInfo_t {
|
||||
int64_t size, align;
|
||||
struct { // Anonymous tagged union for convenience
|
||||
enum { CustomInfo, StructInfo, EnumInfo, PointerInfo, TextInfo, ArrayInfo, ChannelInfo, TableInfo, FunctionInfo,
|
||||
@ -28,16 +28,16 @@ typedef struct TypeInfo {
|
||||
} CustomInfo;
|
||||
struct {
|
||||
const char *sigil;
|
||||
const struct TypeInfo *pointed;
|
||||
const struct TypeInfo_t *pointed;
|
||||
} PointerInfo;
|
||||
struct {
|
||||
const char *lang;
|
||||
} TextInfo;
|
||||
struct {
|
||||
const struct TypeInfo *item;
|
||||
const struct TypeInfo_t *item;
|
||||
} ArrayInfo, ChannelInfo;
|
||||
struct {
|
||||
const struct TypeInfo *key, *value;
|
||||
const struct TypeInfo_t *key, *value;
|
||||
} TableInfo;
|
||||
struct {
|
||||
const char *type_str;
|
||||
@ -46,7 +46,7 @@ typedef struct TypeInfo {
|
||||
const char *type_str;
|
||||
} TypeInfoInfo;
|
||||
struct {
|
||||
const struct TypeInfo *type;
|
||||
const struct TypeInfo_t *type;
|
||||
} OptionalInfo;
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
struct {} OpaqueInfo;
|
||||
@ -55,32 +55,31 @@ typedef struct TypeInfo {
|
||||
} EmptyStructInfo;
|
||||
};
|
||||
};
|
||||
} TypeInfo;
|
||||
} TypeInfo_t;
|
||||
|
||||
#define Pointer$info(sigil_expr, pointed_info) &((TypeInfo){.size=sizeof(void*), .align=__alignof__(void*), \
|
||||
#define Pointer$info(sigil_expr, pointed_info) &((TypeInfo_t){.size=sizeof(void*), .align=__alignof__(void*), \
|
||||
.tag=PointerInfo, .PointerInfo={.sigil=sigil_expr, .pointed=pointed_info}})
|
||||
#define Array$info(item_info) &((TypeInfo){.size=sizeof(Array_t), .align=__alignof__(Array_t), \
|
||||
#define Array$info(item_info) &((TypeInfo_t){.size=sizeof(Array_t), .align=__alignof__(Array_t), \
|
||||
.tag=ArrayInfo, .ArrayInfo.item=item_info})
|
||||
#define Set$info(item_info) &((TypeInfo){.size=sizeof(Table_t), .align=__alignof__(Table_t), \
|
||||
#define Set$info(item_info) &((TypeInfo_t){.size=sizeof(Table_t), .align=__alignof__(Table_t), \
|
||||
.tag=TableInfo, .TableInfo.key=item_info, .TableInfo.value=&Void$info})
|
||||
#define Channel$info(item_info) &((TypeInfo){.size=sizeof(Channel_t), .align=__alignof__(Channel_t), \
|
||||
#define Channel$info(item_info) &((TypeInfo_t){.size=sizeof(Channel_t), .align=__alignof__(Channel_t), \
|
||||
.tag=ChannelInfo, .ChannelInfo.item=item_info})
|
||||
#define Table$info(key_expr, value_expr) &((TypeInfo){.size=sizeof(Table_t), .align=__alignof__(Table_t), \
|
||||
#define Table$info(key_expr, value_expr) &((TypeInfo_t){.size=sizeof(Table_t), .align=__alignof__(Table_t), \
|
||||
.tag=TableInfo, .TableInfo.key=key_expr, .TableInfo.value=value_expr})
|
||||
#define Function$info(typestr) &((TypeInfo){.size=sizeof(void*), .align=__alignof__(void*), \
|
||||
#define Function$info(typestr) &((TypeInfo_t){.size=sizeof(void*), .align=__alignof__(void*), \
|
||||
.tag=FunctionInfo, .FunctionInfo.type_str=typestr})
|
||||
#define Closure$info(typestr) &((TypeInfo){.size=sizeof(void*[2]), .align=__alignof__(void*), \
|
||||
#define Closure$info(typestr) &((TypeInfo_t){.size=sizeof(void*[2]), .align=__alignof__(void*), \
|
||||
.tag=FunctionInfo, .FunctionInfo.type_str=typestr})
|
||||
#define TypeInfo$info(typestr) &((TypeInfo){.size=sizeof(TypeInfo), .align=__alignof__(TypeInfo), \
|
||||
.tag=TypeInfoInfo, .TypeInfoInfo.type_str=typestr})
|
||||
#define Optional$info(t) &((TypeInfo){.size=(t)->size, .align=(t)->align, \
|
||||
#define Type$info(typestr) &((TypeInfo_t){.size=sizeof(TypeInfo_t), .align=__alignof__(TypeInfo_t), \
|
||||
.tag=TypeInfoInfo, .TypeInfoInfo.type_str=typestr})
|
||||
#define Optional$info(t) &((TypeInfo_t){.size=(t)->size, .align=(t)->align, \
|
||||
.tag=OptionalInfo, .OptionalInfo.type=t})
|
||||
|
||||
extern const TypeInfo TypeInfo$info;
|
||||
extern const TypeInfo Void$info;
|
||||
extern const TypeInfo Abort$info;
|
||||
extern const TypeInfo_t Void$info;
|
||||
extern const TypeInfo_t Abort$info;
|
||||
#define Void_t void
|
||||
|
||||
Text_t Type$as_text(const void *typeinfo, bool colorize, const TypeInfo *type);
|
||||
Text_t Type$as_text(const void *typeinfo, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
12
structs.c
12
structs.c
@ -47,7 +47,7 @@ static CORD compile_compare_method(env_t *env, ast_t *ast)
|
||||
auto def = Match(ast, StructDef);
|
||||
CORD full_name = CORD_cat(namespace_prefix(env, env->namespace), def->name);
|
||||
CORD cmp_func = CORD_all("static int ", full_name, "$compare(const ", full_name, "_t *x, const ", full_name,
|
||||
"_t *y, const TypeInfo *info) {\n"
|
||||
"_t *y, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n",
|
||||
"int diff;\n");
|
||||
for (arg_ast_t *field = def->fields; field; field = field->next) {
|
||||
@ -75,7 +75,7 @@ static CORD compile_equals_method(env_t *env, ast_t *ast)
|
||||
auto def = Match(ast, StructDef);
|
||||
CORD full_name = CORD_cat(namespace_prefix(env, env->namespace), def->name);
|
||||
CORD eq_func = CORD_all("static bool ", full_name, "$equal(const ", full_name, "_t *x, const ", full_name,
|
||||
"_t *y, const TypeInfo *info) {\n"
|
||||
"_t *y, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n");
|
||||
CORD condition = CORD_EMPTY;
|
||||
for (arg_ast_t *field = def->fields; field; field = field->next) {
|
||||
@ -103,7 +103,7 @@ static CORD compile_hash_method(env_t *env, ast_t *ast)
|
||||
{
|
||||
auto def = Match(ast, StructDef);
|
||||
CORD full_name = CORD_cat(namespace_prefix(env, env->namespace), def->name);
|
||||
CORD hash_func = CORD_all("static uint64_t ", full_name, "$hash(const ", full_name, "_t *obj, const TypeInfo *info) {\n"
|
||||
CORD hash_func = CORD_all("static uint64_t ", full_name, "$hash(const ", full_name, "_t *obj, const TypeInfo_t *info) {\n"
|
||||
"(void)info;\n"
|
||||
"uint64_t field_hashes[] = {");
|
||||
for (arg_ast_t *field = def->fields; field; field = field->next) {
|
||||
@ -127,7 +127,7 @@ void compile_struct_def(env_t *env, ast_t *ast)
|
||||
assert(t && t->tag == StructType);
|
||||
auto struct_ = Match(t, StructType);
|
||||
if (def->fields) {
|
||||
CORD typeinfo = CORD_asprintf("public const TypeInfo %r = {%zu, %zu, {.tag=StructInfo, .CustomInfo={",
|
||||
CORD typeinfo = CORD_asprintf("public const TypeInfo_t %r = {%zu, %zu, {.tag=StructInfo, .CustomInfo={",
|
||||
full_name, type_size(t), type_align(t));
|
||||
|
||||
typeinfo = CORD_all(typeinfo, ".as_text=(void*)", full_name, "$as_text, ");
|
||||
@ -163,7 +163,7 @@ void compile_struct_def(env_t *env, ast_t *ast)
|
||||
env->code->typeinfos = CORD_all(env->code->typeinfos, typeinfo);
|
||||
} else {
|
||||
// If there are no fields, we can use an EmptyStructInfo typeinfo, which generates less code:
|
||||
CORD typeinfo = CORD_asprintf("public const TypeInfo %r = {%zu, %zu, {.tag=EmptyStructInfo, .EmptyStructInfo.name=%r}};\n",
|
||||
CORD typeinfo = CORD_asprintf("public const TypeInfo_t %r = {%zu, %zu, {.tag=EmptyStructInfo, .EmptyStructInfo.name=%r}};\n",
|
||||
full_name, type_size(t), type_align(t), CORD_quoted(def->name));
|
||||
env->code->typeinfos = CORD_all(env->code->typeinfos, typeinfo);
|
||||
}
|
||||
@ -193,7 +193,7 @@ CORD compile_struct_header(env_t *env, ast_t *ast)
|
||||
full_name, "_t value;\n"
|
||||
"Bool_t is_null:1;\n"
|
||||
"} ", namespace_prefix(env, env->namespace), "$Optional", def->name, "_t;\n"
|
||||
"extern const TypeInfo ", full_name, ";\n",
|
||||
"extern const TypeInfo_t ", full_name, ";\n",
|
||||
compile_namespace_header(env, def->name, def->namespace));
|
||||
}
|
||||
|
||||
|
4
tomo.c
4
tomo.c
@ -95,6 +95,8 @@ int main(int argc, char *argv[])
|
||||
{"c", false, &Bool$info, &stop_at_obj_compilation},
|
||||
{"compile-exe", false, &Bool$info, &stop_at_exe_compilation},
|
||||
{"e", false, &Bool$info, &stop_at_exe_compilation},
|
||||
{"uninstall", false, &Bool$info, &uninstall},
|
||||
{"u", false, &Bool$info, &uninstall},
|
||||
{"library", false, &Bool$info, &library_mode},
|
||||
{"L", false, &Bool$info, &library_mode},
|
||||
{"show-codegen", false, &Bool$info, &show_codegen},
|
||||
@ -333,7 +335,7 @@ void build_library(Text_t lib_dir_name)
|
||||
|
||||
void compile_files(env_t *env, Array_t to_compile, bool only_compile_arguments, Array_t *object_files, Array_t *extra_ldlibs)
|
||||
{
|
||||
TypeInfo *path_table_info = Table$info(&Path$info, &Path$info);
|
||||
TypeInfo_t *path_table_info = Table$info(&Path$info, &Path$info);
|
||||
Table_t to_link = {};
|
||||
Table_t argument_files = {};
|
||||
Table_t dependency_files = {};
|
||||
|
6
types.c
6
types.c
@ -80,7 +80,7 @@ CORD type_to_cord(type_t *t) {
|
||||
return CORD_all(type_to_cord(Match(t, OptionalType)->type), "?");
|
||||
}
|
||||
case TypeInfoType: {
|
||||
return CORD_all("TypeInfo(", Match(t, TypeInfoType)->name, ")");
|
||||
return CORD_all("Type$info(", Match(t, TypeInfoType)->name, ")");
|
||||
}
|
||||
case ModuleType: {
|
||||
return CORD_all("Module(", Match(t, ModuleType)->name, ")");
|
||||
@ -472,7 +472,7 @@ PUREFUNC size_t type_size(type_t *t)
|
||||
size += max_size;
|
||||
return size;
|
||||
}
|
||||
case TypeInfoType: return sizeof(TypeInfo);
|
||||
case TypeInfoType: return sizeof(TypeInfo_t);
|
||||
case ModuleType: return 0;
|
||||
}
|
||||
errx(1, "This should not be reachable");
|
||||
@ -538,7 +538,7 @@ PUREFUNC size_t type_align(type_t *t)
|
||||
}
|
||||
return align;
|
||||
}
|
||||
case TypeInfoType: return __alignof__(TypeInfo);
|
||||
case TypeInfoType: return __alignof__(TypeInfo_t);
|
||||
case ModuleType: return 0;
|
||||
}
|
||||
errx(1, "This should not be reachable");
|
||||
|
Loading…
Reference in New Issue
Block a user