diff options
Diffstat (limited to 'stdlib')
| -rw-r--r-- | stdlib/README.md | 1 | ||||
| -rw-r--r-- | stdlib/datatypes.h | 4 | ||||
| -rw-r--r-- | stdlib/integers.c | 45 | ||||
| -rw-r--r-- | stdlib/integers.h | 14 | ||||
| -rw-r--r-- | stdlib/ranges.c | 74 | ||||
| -rw-r--r-- | stdlib/ranges.h | 10 | ||||
| -rw-r--r-- | stdlib/tomo.h | 1 |
7 files changed, 43 insertions, 106 deletions
diff --git a/stdlib/README.md b/stdlib/README.md index 9916c064..c3814114 100644 --- a/stdlib/README.md +++ b/stdlib/README.md @@ -29,7 +29,6 @@ some common functionality. - Paths: [header](stdlib/paths.h), [implementation](stdlib/paths.c) - Patterns: [header](stdlib/patterns.h), [implementation](stdlib/patterns.c) - Pointers: [header](stdlib/pointers.h), [implementation](stdlib/pointers.c) -- Ranges: [header](stdlib/ranges.h), [implementation](stdlib/ranges.c) - Shell: [header](stdlib/shell.h), [implementation](stdlib/shell.c) - Tables: [header](stdlib/tables.h), [implementation](stdlib/tables.c) - Text: [header](stdlib/text.h), [implementation](stdlib/text.c) diff --git a/stdlib/datatypes.h b/stdlib/datatypes.h index 0254060b..af37446a 100644 --- a/stdlib/datatypes.h +++ b/stdlib/datatypes.h @@ -62,10 +62,6 @@ typedef struct { void *fn, *userdata; } Closure_t; -typedef struct Range_s { - Int_t first, last, step; -} Range_t; - enum text_type { TEXT_ASCII, TEXT_GRAPHEMES, TEXT_CONCAT }; typedef struct Text_s { diff --git a/stdlib/integers.c b/stdlib/integers.c index e5344370..858025fa 100644 --- a/stdlib/integers.c +++ b/stdlib/integers.c @@ -32,6 +32,11 @@ public Text_t Int$as_text(const void *i, bool colorize, const TypeInfo_t*) { return text; } +static bool Int$is_none(const void *i, const TypeInfo_t*) +{ + return ((Int_t*)i)->small == 0; +} + public PUREFUNC int32_t Int$compare_value(const Int_t x, const Int_t y) { if (likely(x.small & y.small & 1)) return (x.small > y.small) - (x.small < y.small); @@ -330,8 +335,31 @@ public OptionalInt_t Int$sqrt(Int_t i) return Int$from_mpz(result); } -public PUREFUNC Range_t Int$to(Int_t from, Int_t to) { - return (Range_t){from, to, Int$compare_value(to, from) >= 0 ? (Int_t){.small=(1<<2)|1} : (Int_t){.small=(-1>>2)|1}}; +typedef struct { + OptionalInt_t current, last; + Int_t step; +} IntRange_t; + +static OptionalInt_t _next_int(IntRange_t *info) +{ + OptionalInt_t i = info->current; + if (!Int$is_none(&i, &Int$info)) { + Int_t next = Int$plus(i, info->step); + if (!Int$is_none(&info->last, &Int$info) && Int$compare_value(next, info->last) == Int$compare_value(info->step, I(0))) + next = NONE_INT; + info->current = next; + } + return i; +} + +public PUREFUNC Closure_t Int$to(Int_t first, Int_t last, OptionalInt_t step) { + IntRange_t *range = GC_MALLOC(sizeof(IntRange_t)); + range->current = first; + range->last = last; + range->step = Int$is_none(&step, &Int$info) ? + Int$compare_value(last, first) >= 0 ? (Int_t){.small=(1<<2)|1} : (Int_t){.small=(-1>>2)|1} + : step; + return (Closure_t){.fn=_next_int, .userdata=range}; } public Int_t Int$from_str(const char *str) { @@ -415,11 +443,6 @@ public Int_t Int$factorial(Int_t n) return Int$from_mpz(ret); } -static bool Int$is_none(const void *i, const TypeInfo_t*) -{ - return ((Int_t*)i)->small == 0; -} - static void Int$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t*) { Int_t i = *(Int_t*)obj; @@ -545,8 +568,12 @@ public void Int32$deserialize(FILE *in, void *outval, Array_t*, const TypeInfo_t } \ return bit_array; \ } \ - public to_attr Range_t KindOfInt ## $to(c_type from, c_type to) { \ - return (Range_t){Int64_to_Int(from), Int64_to_Int(to), to >= from ? I_small(1): I_small(-1)}; \ + public to_attr Closure_t KindOfInt ## $to(c_type first, c_type last, Optional ## KindOfInt ## _t step) { \ + IntRange_t *range = GC_MALLOC(sizeof(IntRange_t)); \ + range->current = KindOfInt##_to_Int(first); \ + range->last = KindOfInt##_to_Int(last); \ + range->step = step.is_none ? (last >= first ? I_small(1) : I_small(-1)) : KindOfInt##_to_Int(step.i); \ + return (Closure_t){.fn=_next_int, .userdata=range}; \ } \ public PUREFUNC Optional ## KindOfInt ## _t KindOfInt ## $parse(Text_t text) { \ OptionalInt_t full_int = Int$parse(text); \ diff --git a/stdlib/integers.h b/stdlib/integers.h index 033a6873..fce243a9 100644 --- a/stdlib/integers.h +++ b/stdlib/integers.h @@ -22,7 +22,7 @@ #define I16(x) ((int16_t)x) #define I8(x) ((int8_t)x) -#define DEFINE_INT_TYPE(c_type, type_name, to_attr) \ +#define DEFINE_INT_TYPE(c_type, type_name) \ typedef struct { \ c_type i; \ bool is_none:1; \ @@ -34,7 +34,7 @@ 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); \ Array_t type_name ## $bits(c_type x); \ - to_attr Range_t type_name ## $to(c_type from, c_type to); \ + Closure_t type_name ## $to(c_type first, c_type last, Optional ## type_name ## _t step); \ PUREFUNC Optional ## type_name ## _t type_name ## $parse(Text_t text); \ MACROLIKE PUREFUNC c_type type_name ## $clamped(c_type x, c_type min, c_type max) { \ return x < min ? min : (x > max ? max : x); \ @@ -68,10 +68,10 @@ return (c_type)((u##c_type)x >> y); \ } -DEFINE_INT_TYPE(int64_t, Int64, __attribute__(())) -DEFINE_INT_TYPE(int32_t, Int32, CONSTFUNC) -DEFINE_INT_TYPE(int16_t, Int16, CONSTFUNC) -DEFINE_INT_TYPE(int8_t, Int8, CONSTFUNC) +DEFINE_INT_TYPE(int64_t, Int64) +DEFINE_INT_TYPE(int32_t, Int32) +DEFINE_INT_TYPE(int16_t, Int16) +DEFINE_INT_TYPE(int8_t, Int8) #undef DEFINE_INT_TYPE #define NONE_INT64 ((OptionalInt64_t){.is_none=true}) @@ -101,7 +101,7 @@ 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); Text_t Int$octal(Int_t i, Int_t digits, bool prefix); -PUREFUNC Range_t Int$to(Int_t from, Int_t to); +PUREFUNC Closure_t Int$to(Int_t first, Int_t last, OptionalInt_t step); OptionalInt_t Int$from_str(const char *str); OptionalInt_t Int$parse(Text_t text); Int_t Int$abs(Int_t x); diff --git a/stdlib/ranges.c b/stdlib/ranges.c deleted file mode 100644 index dfb878ea..00000000 --- a/stdlib/ranges.c +++ /dev/null @@ -1,74 +0,0 @@ -// Functions that operate on numeric ranges - -#include <ctype.h> -#include <err.h> -#include <gc.h> -#include <math.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdlib.h> -#include <sys/param.h> - -#include "integers.h" -#include "text.h" -#include "types.h" -#include "util.h" - - -PUREFUNC static int32_t Range$compare(const void *vx, const void *vy, const TypeInfo_t *) -{ - if (vx == vy) return 0; - Range_t *x = (Range_t*)vx, *y = (Range_t*)vy; - int32_t diff = Int$compare(&x->first, &y->first, &Int$info); - if (diff != 0) return diff; - diff = Int$compare(&x->last, &y->last, &Int$info); - if (diff != 0) return diff; - return Int$compare(&x->step, &y->step, &Int$info); -} - -PUREFUNC static bool Range$equal(const void *vx, const void *vy, const TypeInfo_t*) -{ - if (vx == vy) return true; - Range_t *x = (Range_t*)vx, *y = (Range_t*)vy; - 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 void *obj, bool use_color, const TypeInfo_t *) -{ - if (!obj) return Text("Range"); - - Range_t *r = (Range_t*)obj; - Text_t first = Int$as_text(&r->first, use_color, &Int$info); - Text_t last = Int$as_text(&r->last, use_color, &Int$info); - Text_t step = Int$as_text(&r->step, use_color, &Int$info); - return Text$format(use_color ? "\x1b[0;1mRange\x1b[m(first=%k, last=%k, step=%k)" - : "Range(first=%k, last=%k, step=%k)", &first, &last, &step); -} - -PUREFUNC public Range_t Range$reversed(Range_t r) -{ - return (Range_t){r.last, r.first, Int$negative(r.step)}; -} - -PUREFUNC public Range_t Range$by(Range_t r, Int_t step) -{ - return (Range_t){r.first, r.last, Int$times(step, r.step)}; -} - -static bool Range$is_none(const void *obj, const TypeInfo_t*) -{ - return ((Range_t*)obj)->step.small == 0x1; -} - -public const TypeInfo_t Range$info = { - .size=sizeof(Range_t), - .align=__alignof(Range_t), - .metamethods={ - .as_text=Range$as_text, - .compare=Range$compare, - .equal=Range$equal, - .is_none=Range$is_none, - }, -}; - -// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/ranges.h b/stdlib/ranges.h deleted file mode 100644 index 1656bdaa..00000000 --- a/stdlib/ranges.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -// Ranges represent numeric ranges - -PUREFUNC Range_t Range$reversed(Range_t r); -PUREFUNC Range_t Range$by(Range_t r, Int_t step); - -extern const TypeInfo_t Range$info; - -// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 diff --git a/stdlib/tomo.h b/stdlib/tomo.h index 7ed25412..d3887af4 100644 --- a/stdlib/tomo.h +++ b/stdlib/tomo.h @@ -24,7 +24,6 @@ #include "paths.h" #include "patterns.h" #include "pointers.h" -#include "ranges.h" #include "rng.h" #include "shell.h" #include "siphash.h" |
