aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-10-01 13:40:29 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-10-01 13:40:29 -0400
commit597699243a6f935231ad83e63d22bf6ff9e4e547 (patch)
treeedd50fcdad4324680d9e2df7beeaaf93fb162938 /src
parent1b307918c9f0ee6cf3dd074e0b9d9db1ffd35fb8 (diff)
For structs and fixed-size ints, use `.has_value` instead of `.is_none`
Diffstat (limited to 'src')
-rw-r--r--src/compile/functions.c2
-rw-r--r--src/compile/optionals.c19
-rw-r--r--src/stdlib/bytes.c16
-rw-r--r--src/stdlib/cli.c20
-rw-r--r--src/stdlib/datatypes.h4
-rw-r--r--src/stdlib/integers.c26
-rw-r--r--src/stdlib/integers.h10
-rw-r--r--src/stdlib/optionals.c4
-rw-r--r--src/stdlib/types.h2
9 files changed, 51 insertions, 52 deletions
diff --git a/src/compile/functions.c b/src/compile/functions.c
index a1bc15ae..40e16e48 100644
--- a/src/compile/functions.c
+++ b/src/compile/functions.c
@@ -712,7 +712,7 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static
assert(args);
OptionalInt64_t cache_size = Int64$parse(Text$from_str(Match(cache, Int)->str), NULL);
Text_t pop_code = EMPTY_TEXT;
- if (cache->tag == Int && !cache_size.is_none && cache_size.value > 0) {
+ if (cache->tag == Int && cache_size.has_value && cache_size.value > 0) {
// FIXME: this currently just deletes the first entry, but this
// should be more like a least-recently-used cache eviction policy
// or least-frequently-used
diff --git a/src/compile/optionals.c b/src/compile/optionals.c
index 6ef83b5b..bd5f861d 100644
--- a/src/compile/optionals.c
+++ b/src/compile/optionals.c
@@ -28,18 +28,17 @@ Text_t promote_to_optional(type_t *t, Text_t code) {
return code;
} else if (t->tag == IntType) {
switch (Match(t, IntType)->bits) {
- case TYPE_IBITS8: return Texts("((OptionalInt8_t){.value=", code, "})");
- case TYPE_IBITS16: return Texts("((OptionalInt16_t){.value=", code, "})");
- case TYPE_IBITS32: return Texts("((OptionalInt32_t){.value=", code, "})");
- case TYPE_IBITS64: return Texts("((OptionalInt64_t){.value=", code, "})");
- default: errx(1, "Unsupported in type: %s", type_to_text(t));
+ case TYPE_IBITS8: return Texts("((OptionalInt8_t){.has_value=true, .value=", code, "})");
+ case TYPE_IBITS16: return Texts("((OptionalInt16_t){.has_value=true, .value=", code, "})");
+ case TYPE_IBITS32: return Texts("((OptionalInt32_t){.has_value=true, .value=", code, "})");
+ case TYPE_IBITS64: return Texts("((OptionalInt64_t){.has_value=true, .value=", code, "})");
+ default: errx(1, "Unsupported in type: %s", Text$as_c_string(type_to_text(t)));
}
return code;
} else if (t->tag == ByteType) {
- return Texts("((OptionalByte_t){.value=", code, "})");
+ return Texts("((OptionalByte_t){.has_value=true, .value=", code, "})");
} else if (t->tag == StructType) {
- return Texts("({ ", compile_type(Type(OptionalType, .type = t)), " nonnull = {.value=", code,
- "}; nonnull.is_none = false; nonnull; })");
+ return Texts("((", compile_type(Type(OptionalType, .type = t)), "){.has_value=true, .value=", code, "})");
} else {
return code;
}
@@ -77,7 +76,7 @@ Text_t compile_none(type_t *t) {
case PointerType: return Texts("((", compile_type(t), ")NULL)");
case ClosureType: return Text("NONE_CLOSURE");
case NumType: return Text("nan(\"none\")");
- case StructType: return Texts("((", compile_type(Type(OptionalType, .type = t)), "){.is_none=true})");
+ case StructType: return Texts("((", compile_type(Type(OptionalType, .type = t)), "){.has_value=false})");
case EnumType: {
env_t *enum_env = Match(t, EnumType)->env;
return Texts("((", compile_type(t), "){", namespace_name(enum_env, enum_env->namespace, Text("none")), "})");
@@ -103,7 +102,7 @@ Text_t check_none(type_t *t, Text_t value) {
else if (t->tag == TableType) return Texts("((", value, ").entries.data == NULL)");
else if (t->tag == BoolType) return Texts("((", value, ") == NONE_BOOL)");
else if (t->tag == TextType) return Texts("((", value, ").tag == TEXT_NONE)");
- else if (t->tag == IntType || t->tag == ByteType || t->tag == StructType) return Texts("(", value, ").is_none");
+ else if (t->tag == IntType || t->tag == ByteType || t->tag == StructType) return Texts("!(", value, ").has_value");
else if (t->tag == EnumType) {
if (enum_has_fields(t)) return Texts("((", value, ").$tag == 0)");
else return Texts("((", value, ") == 0)");
diff --git a/src/stdlib/bytes.c b/src/stdlib/bytes.c
index db12e501..ab689ae4 100644
--- a/src/stdlib/bytes.c
+++ b/src/stdlib/bytes.c
@@ -36,7 +36,7 @@ public
OptionalByte_t Byte$parse(Text_t text, Text_t *remainder) {
OptionalInt_t full_int = Int$parse(text, remainder);
if (full_int.small != 0L && Int$compare_value(full_int, I(0)) >= 0 && Int$compare_value(full_int, I(255)) <= 0) {
- return (OptionalByte_t){.value = Byte$from_int(full_int, true)};
+ return (OptionalByte_t){.has_value = true, .value = Byte$from_int(full_int, true)};
} else {
return NONE_BYTE;
}
@@ -86,12 +86,12 @@ typedef struct {
static OptionalByte_t _next_Byte(ByteRange_t *info) {
OptionalByte_t i = info->current;
- if (!i.is_none) {
+ if (i.has_value) {
Byte_t next;
bool overflow = __builtin_add_overflow(i.value, info->step, &next);
- if (overflow || (!info->last.is_none && (info->step >= 0 ? next > info->last.value : next < info->last.value)))
- info->current = (OptionalByte_t){.is_none = true};
- else info->current = (OptionalByte_t){.value = next};
+ if (overflow || (info->last.has_value && (info->step >= 0 ? next > info->last.value : next < info->last.value)))
+ info->current = (OptionalByte_t){.has_value = false};
+ else info->current = (OptionalByte_t){.has_value = true, .value = next};
}
return i;
}
@@ -99,9 +99,9 @@ static OptionalByte_t _next_Byte(ByteRange_t *info) {
public
CONSTFUNC Closure_t Byte$to(Byte_t first, Byte_t last, OptionalInt8_t step) {
ByteRange_t *range = GC_MALLOC(sizeof(ByteRange_t));
- range->current = (OptionalByte_t){.value = first};
- range->last = (OptionalByte_t){.value = last};
- range->step = step.is_none ? (last >= first ? 1 : -1) : step.value;
+ range->current = (OptionalByte_t){.has_value = true, .value = first};
+ range->last = (OptionalByte_t){.has_value = true, .value = last};
+ range->step = step.has_value ? step.value : (last >= first ? 1 : -1);
return (Closure_t){.fn = _next_Byte, .userdata = range};
}
diff --git a/src/stdlib/cli.c b/src/stdlib/cli.c
index 1e4324f9..d5bb0ea2 100644
--- a/src/stdlib/cli.c
+++ b/src/stdlib/cli.c
@@ -45,24 +45,24 @@ static bool parse_single_arg(const TypeInfo_t *info, char *arg, void *dest) {
return parsed.small != 0;
} else if (info == &Int64$info) {
OptionalInt64_t parsed = Int64$parse(Text$from_str(arg), NULL);
- if (!parsed.is_none) *(OptionalInt64_t *)dest = parsed;
- return !parsed.is_none;
+ if (parsed.has_value) *(OptionalInt64_t *)dest = parsed;
+ return parsed.has_value;
} else if (info == &Int32$info) {
OptionalInt32_t parsed = Int32$parse(Text$from_str(arg), NULL);
- if (!parsed.is_none) *(OptionalInt32_t *)dest = parsed;
- return !parsed.is_none;
+ if (parsed.has_value) *(OptionalInt32_t *)dest = parsed;
+ return parsed.has_value;
} else if (info == &Int16$info) {
OptionalInt16_t parsed = Int16$parse(Text$from_str(arg), NULL);
- if (!parsed.is_none) *(OptionalInt16_t *)dest = parsed;
- return !parsed.is_none;
+ if (parsed.has_value) *(OptionalInt16_t *)dest = parsed;
+ return parsed.has_value;
} else if (info == &Int8$info) {
OptionalInt8_t parsed = Int8$parse(Text$from_str(arg), NULL);
- if (!parsed.is_none) *(OptionalInt8_t *)dest = parsed;
- return !parsed.is_none;
+ if (parsed.has_value) *(OptionalInt8_t *)dest = parsed;
+ return parsed.has_value;
} else if (info == &Byte$info) {
OptionalByte_t parsed = Byte$parse(Text$from_str(arg), NULL);
- if (!parsed.is_none) *(OptionalByte_t *)dest = parsed;
- return !parsed.is_none;
+ if (parsed.has_value) *(OptionalByte_t *)dest = parsed;
+ return parsed.has_value;
} else if (info == &Bool$info) {
OptionalBool_t parsed = Bool$parse(Text$from_str(arg), NULL);
if (parsed != NONE_BOOL) *(OptionalBool_t *)dest = parsed;
diff --git a/src/stdlib/datatypes.h b/src/stdlib/datatypes.h
index cbf09519..fc665401 100644
--- a/src/stdlib/datatypes.h
+++ b/src/stdlib/datatypes.h
@@ -117,7 +117,7 @@ typedef struct {
typedef struct {
Byte_t value;
- bool is_none : 1;
+ bool has_value : 1;
} OptionalByte_t;
-#define NONE_BYTE ((OptionalByte_t){.is_none = true})
+#define NONE_BYTE ((OptionalByte_t){.has_value = false})
diff --git a/src/stdlib/integers.c b/src/stdlib/integers.c
index 863bb42d..e7a58ef3 100644
--- a/src/stdlib/integers.c
+++ b/src/stdlib/integers.c
@@ -674,43 +674,43 @@ void Int32$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_
} KindOfInt##Range_t; \
static Optional##KindOfInt##_t _next_##KindOfInt(KindOfInt##Range_t *info) { \
Optional##KindOfInt##_t i = info->current; \
- if (!i.is_none) { \
+ if (i.has_value) { \
KindOfInt##_t next; \
bool overflow = __builtin_add_overflow(i.value, info->step, &next); \
if (overflow \
- || (!info->last.is_none && (info->step >= 0 ? next > info->last.value : next < info->last.value))) \
- info->current = (Optional##KindOfInt##_t){.is_none = true}; \
- else info->current = (Optional##KindOfInt##_t){.value = next}; \
+ || (info->last.has_value && (info->step >= 0 ? next > info->last.value : next < info->last.value))) \
+ info->current = (Optional##KindOfInt##_t){.has_value = false}; \
+ else info->current = (Optional##KindOfInt##_t){.has_value = true, .value = next}; \
} \
return i; \
} \
public \
to_attr Closure_t KindOfInt##$to(c_type first, c_type last, Optional##KindOfInt##_t step) { \
KindOfInt##Range_t *range = GC_MALLOC(sizeof(KindOfInt##Range_t)); \
- range->current = (Optional##KindOfInt##_t){.value = first}; \
- range->last = (Optional##KindOfInt##_t){.value = last}; \
- range->step = step.is_none ? (last >= first ? 1 : -1) : step.value; \
+ range->current = (Optional##KindOfInt##_t){.has_value = true, .value = first}; \
+ range->last = (Optional##KindOfInt##_t){.has_value = true, .value = last}; \
+ range->step = step.has_value ? step.value : (last >= first ? 1 : -1); \
return (Closure_t){.fn = _next_##KindOfInt, .userdata = range}; \
} \
public \
to_attr Closure_t KindOfInt##$onward(c_type first, c_type step) { \
KindOfInt##Range_t *range = GC_MALLOC(sizeof(KindOfInt##Range_t)); \
- range->current = (Optional##KindOfInt##_t){.value = first}; \
- range->last = (Optional##KindOfInt##_t){.is_none = true}; \
+ range->current = (Optional##KindOfInt##_t){.has_value = true, .value = first}; \
+ range->last = (Optional##KindOfInt##_t){.has_value = false}; \
range->step = step; \
return (Closure_t){.fn = _next_##KindOfInt, .userdata = range}; \
} \
public \
PUREFUNC Optional##KindOfInt##_t KindOfInt##$parse(Text_t text, Text_t *remainder) { \
OptionalInt_t full_int = Int$parse(text, remainder); \
- if (full_int.small == 0L) return (Optional##KindOfInt##_t){.is_none = true}; \
+ if (full_int.small == 0L) return (Optional##KindOfInt##_t){.has_value = false}; \
if (Int$compare_value(full_int, I(min_val)) < 0) { \
- return (Optional##KindOfInt##_t){.is_none = true}; \
+ return (Optional##KindOfInt##_t){.has_value = false}; \
} \
if (Int$compare_value(full_int, I(max_val)) > 0) { \
- return (Optional##KindOfInt##_t){.is_none = true}; \
+ return (Optional##KindOfInt##_t){.has_value = false}; \
} \
- return (Optional##KindOfInt##_t){.value = KindOfInt##$from_int(full_int, true)}; \
+ return (Optional##KindOfInt##_t){.has_value = true, .value = KindOfInt##$from_int(full_int, true)}; \
} \
public \
CONSTFUNC c_type KindOfInt##$gcd(c_type x, c_type y) { \
diff --git a/src/stdlib/integers.h b/src/stdlib/integers.h
index 34195d23..7eafd134 100644
--- a/src/stdlib/integers.h
+++ b/src/stdlib/integers.h
@@ -19,7 +19,7 @@
#define DEFINE_INT_TYPE(c_type, type_name) \
typedef struct { \
c_type value; \
- bool is_none : 1; \
+ bool has_value : 1; \
} Optional##type_name##_t; \
Text_t type_name##$as_text(const void *i, bool colorize, const TypeInfo_t *type); \
Text_t type_name##$value_as_text(c_type i); \
@@ -69,10 +69,10 @@ DEFINE_INT_TYPE(int16_t, Int16)
DEFINE_INT_TYPE(int8_t, Int8)
#undef DEFINE_INT_TYPE
-#define NONE_INT64 ((OptionalInt64_t){.is_none = true})
-#define NONE_INT32 ((OptionalInt32_t){.is_none = true})
-#define NONE_INT16 ((OptionalInt16_t){.is_none = true})
-#define NONE_INT8 ((OptionalInt8_t){.is_none = true})
+#define NONE_INT64 ((OptionalInt64_t){.has_value = false})
+#define NONE_INT32 ((OptionalInt32_t){.has_value = false})
+#define NONE_INT16 ((OptionalInt16_t){.has_value = false})
+#define NONE_INT8 ((OptionalInt8_t){.has_value = false})
#define Int64$abs(...) I64(labs(__VA_ARGS__))
#define Int32$abs(...) I32(abs(__VA_ARGS__))
diff --git a/src/stdlib/optionals.c b/src/stdlib/optionals.c
index 41d38a19..3fe812b1 100644
--- a/src/stdlib/optionals.c
+++ b/src/stdlib/optionals.c
@@ -13,8 +13,8 @@ public
PUREFUNC bool is_none(const void *obj, const TypeInfo_t *non_optional_type) {
if (non_optional_type->metamethods.is_none) return non_optional_type->metamethods.is_none(obj, non_optional_type);
- const void *dest = (obj + non_optional_type->size);
- return *(bool *)dest;
+ const bool *has_value = (const bool *)(obj + non_optional_type->size);
+ return !(*has_value);
}
PUREFUNC public uint64_t Optional$hash(const void *obj, const TypeInfo_t *type) {
diff --git a/src/stdlib/types.h b/src/stdlib/types.h
index 2e358c6c..85567815 100644
--- a/src/stdlib/types.h
+++ b/src/stdlib/types.h
@@ -109,7 +109,7 @@ Text_t Type$as_text(const void *typeinfo, bool colorize, const TypeInfo_t *type)
t value; \
struct { \
char _padding[unpadded_size]; \
- Bool_t is_none; \
+ Bool_t has_value; \
}; \
}; \
} name