diff options
Diffstat (limited to 'builtins')
| -rw-r--r-- | builtins/integers.c | 15 | ||||
| -rw-r--r-- | builtins/integers.h | 7 | ||||
| -rw-r--r-- | builtins/text.c | 36 | ||||
| -rw-r--r-- | builtins/text.h | 1 |
4 files changed, 51 insertions, 8 deletions
diff --git a/builtins/integers.c b/builtins/integers.c index bf55d0ae..d9361cf4 100644 --- a/builtins/integers.c +++ b/builtins/integers.c @@ -92,7 +92,7 @@ public Text_t Int$format(Int_t i, Int_t digits_int) } public Text_t Int$hex(Int_t i, Int_t digits_int, bool uppercase, bool prefix) { - if (Int$compare(&i, (Int_t[1]){I_small(0)}, &$Int) < 0) + if (Int$is_negative(i)) return Text$concat(Text("-"), Int$hex(Int$negative(i), digits_int, uppercase, prefix)); int64_t digits = Int_to_Int64(digits_int, false); @@ -119,8 +119,7 @@ public Text_t Int$hex(Int_t i, Int_t digits_int, bool uppercase, bool prefix) { } public Text_t Int$octal(Int_t i, Int_t digits_int, bool prefix) { - Int_t zero = I_small(0); - if (Int$compare(&i, &zero, &$Int) < 0) + if (Int$is_negative(i)) return Text$concat(Text("-"), Int$octal(Int$negative(i), digits_int, prefix)); int64_t digits = Int_to_Int64(digits_int, false); @@ -317,7 +316,7 @@ public Int_t Int$sqrt(Int_t i) } public Int_t Int$random(Int_t min, Int_t max) { - int32_t cmp = Int$compare(&min, &max, &$Int); + int32_t cmp = Int$compare_value(min, max); if (cmp > 0) { Text_t min_text = Int$as_text(&min, false, &$Int), max_text = Int$as_text(&max, false, &$Int); fail("Random minimum value (%k) is larger than the maximum value (%k)", @@ -342,7 +341,7 @@ public Int_t Int$random(Int_t min, Int_t max) { } public Range_t Int$to(Int_t from, Int_t to) { - return (Range_t){from, to, Int$compare(&to, &from, &$Int) >= 0 ? (Int_t){.small=(1<<2)|1} : (Int_t){.small=(-1>>2)|1}}; + return (Range_t){from, to, Int$compare_value(to, from) >= 0 ? (Int_t){.small=(1<<2)|1} : (Int_t){.small=(-1>>2)|1}}; } public Int_t Int$from_str(const char *str, bool *success) { @@ -369,7 +368,7 @@ public bool Int$is_prime(Int_t x, Int_t reps) { mpz_t p; mpz_init_set_int(p, x); - if (Int$compare(&reps, (Int_t[1]){I_small(9999)}, &$Int) > 0) + if (Int$compare_value(reps, I(9999)) > 0) fail("Number of prime-test repetitions should not be above 9999"); int reps_int = Int_to_Int32(reps, false); return (mpz_probab_prime_p(p, reps_int) != 0); @@ -464,11 +463,11 @@ public const TypeInfo $Int = { bool parsed_int = false; \ Int_t full_int = Int$from_text(text, &parsed_int); \ if (!parsed_int && success) *success = false; \ - if (Int$compare(&full_int, (Int_t[1]){I(min_val)}, &$Int) < 0) { \ + if (Int$compare_value(full_int, I(min_val)) < 0) { \ if (success) *success = false; \ return min_val; \ } \ - if (Int$compare(&full_int, (Int_t[1]){I(max_val)}, &$Int) > 0) { \ + if (Int$compare_value(full_int, I(max_val)) > 0) { \ if (success) *success = false; \ return max_val; \ } \ diff --git a/builtins/integers.h b/builtins/integers.h index e24b7869..4ff862fc 100644 --- a/builtins/integers.h +++ b/builtins/integers.h @@ -257,6 +257,13 @@ static inline Int_t Int$negative(Int_t x) return Int$slow_negative(x); } +static inline bool Int$is_negative(Int_t x) +{ + if (__builtin_expect((x.small & 1), 1)) + return x.small < 0; + return Int$compare_value(x, I_small(0)) < 0; +} + // Conversion functions: static inline Int_t Int64_to_Int(int64_t i) diff --git a/builtins/text.c b/builtins/text.c index 97b50a40..b3fe25eb 100644 --- a/builtins/text.c +++ b/builtins/text.c @@ -268,6 +268,42 @@ public Text_t Text$_concat(int n, Text_t items[n]) return ret; } +public Text_t Text$repeat(Text_t text, Int_t count) +{ + if (text.length == 0 || Int$is_negative(count)) + return Text(""); + + Int_t result_len = Int$times(count, I(text.length)); + if (Int$compare_value(result_len, I(1l<<40)) > 0) + fail("Text repeating would produce too big of an result!"); + + int64_t count64 = Int_to_Int64(count, false); + if (text.tag == TEXT_SUBTEXT) { + int64_t subtexts = num_subtexts(text); + Text_t ret = { + .length=text.length * count64, + .tag=TEXT_SUBTEXT, + .subtexts=GC_MALLOC(sizeof(Text_t[subtexts * count64])), + }; + for (int64_t c = 0; c < count64; c++) { + for (int64_t i = 0; i < subtexts; i++) { + if (text.subtexts[i].length > 0) + ret.subtexts[c*subtexts + i] = text.subtexts[i]; + } + } + return ret; + } else { + Text_t ret = { + .length=text.length * count64, + .tag=TEXT_SUBTEXT, + .subtexts=GC_MALLOC(sizeof(Text_t[count64])), + }; + for (int64_t i = 0; i < count64; i++) + ret.subtexts[i] = text; + return ret; + } +} + public Text_t Text$slice(Text_t text, Int_t first_int, Int_t last_int) { int64_t first = Int_to_Int64(first_int, false); diff --git a/builtins/text.h b/builtins/text.h index c93c6266..747f82a0 100644 --- a/builtins/text.h +++ b/builtins/text.h @@ -52,6 +52,7 @@ Text_t Text$from_bytes(array_t bytes); array_t Text$lines(Text_t text); Text_t Text$join(Text_t glue, array_t pieces); Text_t Text$map(Text_t text, Pattern_t pattern, closure_t fn); +Text_t Text$repeat(Text_t text, Int_t count); extern const TypeInfo $Text; |
