From bf5a7253458ec5b3f4fe054b3b2f5f80211c1892 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 3 Mar 2024 13:37:05 -0500 Subject: [PATCH] Definitively go with "Int" and "Num" over "Int64" and "Num64", plus add Int__bits() --- builtins/array.h | 2 +- builtins/integers.c | 14 ++++++++++++-- builtins/integers.h | 16 ++++------------ builtins/nums.c | 30 +++++++++++++++--------------- builtins/nums.h | 43 +++++++++++++++++++++---------------------- compile.c | 20 ++++++++++++-------- environment.c | 18 +++++++++++++++--- test/integers.tm | 15 ++++++++++++++- test/tables.tm | 4 ++-- types.c | 4 ++-- 10 files changed, 98 insertions(+), 68 deletions(-) diff --git a/builtins/array.h b/builtins/array.h index 76ab29f..021166b 100644 --- a/builtins/array.h +++ b/builtins/array.h @@ -12,7 +12,7 @@ const array_t $arr = x; int64_t $index = (int64_t)(i); \ int64_t $off = $index + ($index < 0) * ($arr.length + 1) - 1; \ if (__builtin_expect($off < 0 || $off >= $arr.length, 0)) \ - fail_source(filename, start, end, "Invalid array index: %r (array has length %ld)\n", Int64__as_str(&$index, USE_COLOR, NULL), $arr.length); \ + fail_source(filename, start, end, "Invalid array index: %r (array has length %ld)\n", Int__as_str(&$index, USE_COLOR, NULL), $arr.length); \ (type*)($arr.data + $arr.stride * $off);}) #define $Array_get_unchecked(type, x, i) *({ const array_t $arr = x; int64_t $index = (int64_t)(i); \ int64_t $off = $index + ($index < 0) * ($arr.length + 1) - 1; \ diff --git a/builtins/integers.c b/builtins/integers.c index ab61b3b..65046ad 100644 --- a/builtins/integers.c +++ b/builtins/integers.c @@ -6,9 +6,10 @@ #include "../SipHash/halfsiphash.h" #include "array.h" +#include "datatypes.h" #include "integers.h" -#include "types.h" #include "string.h" +#include "types.h" #define xstr(a) str(a) #define str(a) #a @@ -37,6 +38,15 @@ const char *octal_fmt = prefix ? "0o%0.*lo" : "%0.*lo"; \ return CORD_asprintf(octal_fmt, (int)digits, (uint64_t)i); \ } \ + public array_t KindOfInt ## __bits(c_type x) { \ + array_t bit_array = (array_t){.data=GC_MALLOC_ATOMIC(sizeof(bool)*8*sizeof(c_type)), .atomic=1, .stride=sizeof(bool), .length=8*sizeof(c_type)}; \ + bool *bits = bit_array.data + sizeof(c_type)*8; \ + for (size_t i = 0; i < 8*sizeof(c_type); i++) { \ + *(bits--) = x & 1; \ + x >>= 1; \ + } \ + return bit_array; \ + } \ public c_type KindOfInt ## __random(int64_t min, int64_t max) { \ if (min > max) fail("Random min (%ld) is larger than max (%ld)", min, max); \ if (min < (int64_t)min_val) fail("Random min (%ld) is smaller than the minimum "#KindOfInt" value", min); \ @@ -55,7 +65,7 @@ .CustomInfo={.compare=(void*)KindOfInt##__compare, .as_str=(void*)KindOfInt##__as_str}, \ }; -DEFINE_INT_TYPE(int64_t, Int64, "ld", INT64_MIN, INT64_MAX); +DEFINE_INT_TYPE(int64_t, Int, "ld", INT64_MIN, INT64_MAX); DEFINE_INT_TYPE(int32_t, Int32, "d_i32", INT32_MIN, INT32_MAX); DEFINE_INT_TYPE(int16_t, Int16, "d_i16", INT16_MIN, INT16_MAX); DEFINE_INT_TYPE(int8_t, Int8, "d_i8", INT8_MIN, INT8_MAX); diff --git a/builtins/integers.h b/builtins/integers.h index 65a52a5..1b42ee1 100644 --- a/builtins/integers.h +++ b/builtins/integers.h @@ -3,13 +3,13 @@ #include #include +#include "datatypes.h" #include "types.h" -#define Int64_t int64_t +#define Int_t int64_t #define Int32_t int32_t #define Int16_t int16_t #define Int8_t int8_t -#define Int_t int64_t #define I64(x) ((int64_t)x) #define I32(x) ((int32_t)x) #define I16(x) ((int16_t)x) @@ -21,28 +21,20 @@ CORD type_name ## __format(c_type i, int64_t digits); \ CORD type_name ## __hex(c_type i, int64_t digits, bool uppercase, bool prefix); \ CORD type_name ## __octal(c_type i, int64_t digits, bool prefix); \ + array_t type_name ## __bits(c_type x); \ c_type type_name ## __random(int64_t min, int64_t max); \ extern const c_type type_name ## __min, type_name##__max; \ extern const TypeInfo type_name; -DEFINE_INT_TYPE(int64_t, Int64); +DEFINE_INT_TYPE(int64_t, Int); DEFINE_INT_TYPE(int32_t, Int32); DEFINE_INT_TYPE(int16_t, Int16); DEFINE_INT_TYPE(int8_t, Int8); #undef DEFINE_INT_TYPE #define Int__abs(...) I64(labs(__VA_ARGS__)) -#define Int64__abs(...) I64(labs(__VA_ARGS__)) #define Int32__abs(...) I32(abs(__VA_ARGS__)) #define Int16__abs(...) I16(abs(__VA_ARGS__)) #define Int8__abs(...) I8(abs(__VA_ARGS__)) -#define Int__as_str Int64__as_str -#define Int__compare Int64__compare -#define Int__format Int64__format -#define Int__hex Int64__hex -#define Int__octal Int64__octal -#define Int__random Int64__random -#define Int Int64 - // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/builtins/nums.c b/builtins/nums.c index 419a366..456da93 100644 --- a/builtins/nums.c +++ b/builtins/nums.c @@ -14,54 +14,54 @@ #include "string.h" #include "types.h" -public CORD Num64__as_str(const double *f, bool colorize, const TypeInfo *type) { +public CORD Num__as_str(const double *f, bool colorize, const TypeInfo *type) { (void)type; - if (!f) return "Num64"; + if (!f) return "Num"; CORD c; if (colorize) CORD_sprintf(&c, "\x1b[35m%g\x1b[33;2m\x1b[m", *f); else CORD_sprintf(&c, "%g", *f); return c; } -public int32_t Num64__compare(const double *x, const double *y, const TypeInfo *type) { +public int32_t Num__compare(const double *x, const double *y, const TypeInfo *type) { (void)type; return (*x > *y) - (*x < *y); } -public bool Num64__equal(const double *x, const double *y, const TypeInfo *type) { +public bool Num__equal(const double *x, const double *y, const TypeInfo *type) { (void)type; return *x == *y; } -public CORD Num64__format(double f, int64_t precision) { +public CORD Num__format(double f, int64_t precision) { return CORD_asprintf("%.*f", (int)precision, f); } -public CORD Num64__scientific(double f, int64_t precision) { +public CORD Num__scientific(double f, int64_t precision) { return CORD_asprintf("%.*e", (int)precision, f); } -public double Num64__mod(double num, double modulus) { +public double Num__mod(double num, double modulus) { double result = fmod(num, modulus); return (result < 0) != (modulus < 0) ? result + modulus : result; } -public double Num64__nan(CORD tag) { +public double Num__nan(CORD tag) { return nan(CORD_to_const_char_star(tag)); } -public bool Num64__isinf(double n) { return isinf(n); } -public bool Num64__finite(double n) { return finite(n); } -public bool Num64__isnan(double n) { return isnan(n); } +public bool Num__isinf(double n) { return isinf(n); } +public bool Num__finite(double n) { return finite(n); } +public bool Num__isnan(double n) { return isnan(n); } -public const TypeInfo Num64 = { +public const TypeInfo Num = { .size=sizeof(double), .align=__alignof__(double), .tag=CustomInfo, .CustomInfo={ - .compare=(void*)Num64__compare, - .equal=(void*)Num64__equal, - .as_str=(void*)Num64__as_str, + .compare=(void*)Num__compare, + .equal=(void*)Num__equal, + .as_str=(void*)Num__as_str, }, }; diff --git a/builtins/nums.h b/builtins/nums.h index aeeeaa8..e8fdcea 100644 --- a/builtins/nums.h +++ b/builtins/nums.h @@ -6,40 +6,39 @@ #include "types.h" -#define Num64_t double -#define Num32_t float #define Num_t double +#define Num32_t float -CORD Num64__as_str(const double *f, bool colorize, const TypeInfo *type); -int32_t Num64__compare(const double *x, const double *y, const TypeInfo *type); -bool Num64__equal(const double *x, const double *y, const TypeInfo *type); -CORD Num64__format(double f, int64_t precision); -CORD Num64__scientific(double f, int64_t precision); -double Num64__mod(double num, double modulus); -bool Num64__isinf(double n); -bool Num64__finite(double n); -bool Num64__isnan(double n); -double Num64__nan(CORD tag); +CORD Num__as_str(const double *f, bool colorize, const TypeInfo *type); +int32_t Num__compare(const double *x, const double *y, const TypeInfo *type); +bool Num__equal(const double *x, const double *y, const TypeInfo *type); +CORD Num__format(double f, int64_t precision); +CORD Num__scientific(double f, int64_t precision); +double Num__mod(double num, double modulus); +bool Num__isinf(double n); +bool Num__finite(double n); +bool Num__isnan(double n); +double Num__nan(CORD tag); // Constants: -#define C(name) const double Num64__##name = M_##name; +#define C(name) const double Num__##name = M_##name; C(2_SQRTPI) C(E) C(PI_2) C(2_PI) C(1_PI) C(LN10) C(LN2) C(LOG2E) C(PI) C(PI_4) C(SQRT2) C(SQRT1_2) -const double Num64__INF = INFINITY, Num64__TAU = 2.*M_PI; +const double Num__INF = INFINITY, Num__TAU = 2.*M_PI; #undef C -double Num64__random(void); -bool Num64__finite(double n); -bool Num64__isinf(double n); -bool Num64__isnan(double n); -#define F(name) double (*Num64__##name)(double n) = name; -double (*Num64__abs)(double) = fabs; +double Num__random(void); +bool Num__finite(double n); +bool Num__isinf(double n); +bool Num__isnan(double n); +#define F(name) double (*Num__##name)(double n) = name; +double (*Num__abs)(double) = fabs; F(acos) F(acosh) F(asin) F(asinh) F(atan) F(atanh) F(cbrt) F(ceil) F(cos) F(cosh) F(erf) F(erfc) F(exp) F(exp2) F(expm1) F(floor) F(j0) F(j1) F(log) F(log10) F(log1p) F(log2) F(logb) F(rint) F(round) F(significand) F(sin) F(sinh) F(sqrt) F(tan) F(tanh) F(tgamma) F(trunc) F(y0) F(y1) #undef F -#define F(name) double (*Num64__##name)(double x, double y) = name; +#define F(name) double (*Num__##name)(double x, double y) = name; F(atan2) F(copysign) F(fdim) F(hypot) F(nextafter) F(pow) F(remainder) #undef F -extern const TypeInfo Num64; +extern const TypeInfo Num; CORD Num32__as_str(const float *f, bool colorize, const TypeInfo *type); int32_t Num32__compare(const float *x, const float *y, const TypeInfo *type); diff --git a/compile.c b/compile.c index 4f22199..a7ab054 100644 --- a/compile.c +++ b/compile.c @@ -32,8 +32,8 @@ CORD compile_type(type_t *t) case VoidType: return "void"; case MemoryType: return "void"; case BoolType: return "Bool_t"; - case IntType: return CORD_asprintf("Int%ld_t", Match(t, IntType)->bits); - case NumType: return CORD_asprintf("Num%ld_t", Match(t, NumType)->bits); + case IntType: return Match(t, IntType)->bits == 64 ? "Int_t" : CORD_asprintf("Int%ld_t", Match(t, IntType)->bits); + case NumType: return Match(t, NumType)->bits == 64 ? "Num_t" : CORD_asprintf("Num%ld_t", Match(t, NumType)->bits); case StringType: { const char *dsl = Match(t, StringType)->dsl; return dsl ? CORD_cat(dsl, "_t") : "Str_t"; @@ -72,8 +72,14 @@ CORD expr_as_string(env_t *env, CORD expr, type_t *t, CORD color) switch (t->tag) { case MemoryType: return CORD_asprintf("Memory__as_str($stack(%r), %r, &Memory)", expr, color); case BoolType: return CORD_asprintf("Bool__as_str($stack(%r), %r, &Bool)", expr, color); - case IntType: return CORD_asprintf("Int%ld__as_str($stack(%r), %r, &Int%ld)", Match(t, IntType)->bits, expr, color, Match(t, IntType)->bits); - case NumType: return CORD_asprintf("Num%ld__as_str($stack(%r), %r, &Num%ld)", Match(t, NumType)->bits, expr, color, Match(t, NumType)->bits); + case IntType: { + CORD name = type_to_cord(t); + return CORD_asprintf("%r__as_str($stack(%r), %r, &%r)", name, expr, color, name); + } + case NumType: { + CORD name = type_to_cord(t); + return CORD_asprintf("%r__as_str($stack(%r), %r, &Num%r)", name, expr, color, name); + } case StringType: return CORD_asprintf("Str__as_str($stack(%r), %r, &Str)", expr, color); case ArrayType: return CORD_asprintf("Array__as_str($stack(%r), %r, %r)", expr, color, compile_type_info(env, t)); case TableType: return CORD_asprintf("Table_as_str($stack(%r), %r, %r)", expr, color, compile_type_info(env, t)); @@ -773,7 +779,7 @@ CORD compile(env_t *env, ast_t *ast) if (for_->empty) code_err(for_->empty, "'else' is not implemented for loops over integers"); return CORD_all( - "for (Int64_t ", value, " = 1, $n = ", compile(env, for_->iter), "; ", value, " <= $n; ++", value, ")\n" + "for (int64_t ", value, " = 1, $n = ", compile(env, for_->iter), "; ", value, " <= $n; ++", value, ")\n" "\t", compile(scope, for_->body), "\n"); } default: code_err(for_->iter, "Iteration is not implemented for type: %T", iter_t); @@ -1034,9 +1040,7 @@ CORD compile(env_t *env, ast_t *ast) CORD compile_type_info(env_t *env, type_t *t) { switch (t->tag) { - case BoolType: return "&Bool"; - case IntType: return CORD_asprintf("&Int%ld", Match(t, IntType)->bits); - case NumType: return CORD_asprintf("&Num%ld", Match(t, NumType)->bits); + case BoolType: case IntType: case NumType: return CORD_asprintf("&%r", type_to_cord(t)); case StringType: return CORD_all("&", Match(t, StringType)->dsl ? Match(t, StringType)->dsl : "Str"); case StructType: return CORD_all("&", Match(t, StructType)->name); case EnumType: return CORD_all("&", Match(t, EnumType)->name); diff --git a/environment.c b/environment.c index a702129..7729c3d 100644 --- a/environment.c +++ b/environment.c @@ -60,7 +60,16 @@ env_t *new_compilation_unit(void) array_t namespace; } global_types[] = { {"Bool", Type(BoolType), "Bool_t", "Bool", {}}, - {"Int", Type(IntType, .bits=64), "Int_t", "Int", {}}, + {"Int", Type(IntType, .bits=64), "Int_t", "Int", $TypedArray(ns_entry_t, + {"format", "Int__format", "func(i:Int, digits=0)->Str"}, + {"hex", "Int__hex", "func(i:Int, digits=0, uppercase=yes, prefix=yes)->Str"}, + {"octal", "Int__octal", "func(i:Int, digits=0, prefix=yes)->Str"}, + {"random", "Int__random", "func(min=0, max=0xffffffff)->Int"}, + {"bits", "Int__bits", "func(x:Int)->[Bool]"}, + {"abs", "Int__abs", "func(i:Int)->Int"}, + {"min", "Int__min", "Int"}, + {"max", "Int__max", "Int"} + )}, {"Int32", Type(IntType, .bits=32), "Int32_t", "Int32", {}}, {"Int16", Type(IntType, .bits=16), "Int16_t", "Int16", {}}, {"Int8", Type(IntType, .bits=8), "Int8_t", "Int8", {}}, @@ -117,8 +126,11 @@ binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name) case TableType: { errx(1, "Table methods not implemented"); } - case StringType: { - table_t *ns = Table_str_get(env->type_namespaces, "Str"); + case BoolType: case IntType: case NumType: case StringType: { + table_t *ns = Table_str_get(env->type_namespaces, CORD_to_const_char_star(type_to_cord(cls_type))); + if (!ns) { + code_err(self, "No namespace found for this type!"); + } return Table_str_get(ns, name); } case TypeInfoType: case StructType: case EnumType: { diff --git a/test/integers.tm b/test/integers.tm index c20d08e..2570521 100644 --- a/test/integers.tm +++ b/test/integers.tm @@ -15,7 +15,7 @@ = 3_i16 >> 2 ^ 10 -= 1024 : Num64 += 1024 : Num >> 3 and 2 = 2 @@ -31,3 +31,16 @@ for x in 5 nums ++= "{x}," >> nums = "1,2,3,4,5," + +>> x := 123 +>> x:hex() += "0x7B" +>> x:octal() += "0o173" + +>> Int.random() +>> Int.min += -9223372036854775808 +>> Int.max += 9223372036854775807 + diff --git a/test/tables.tm b/test/tables.tm index 891e061..7c61446 100644 --- a/test/tables.tm +++ b/test/tables.tm @@ -20,7 +20,7 @@ for k,v in t >> t.default = ?(readonly)999 >> t.fallback -= !{Str=>Int64} += !{Str=>Int} >> t.keys = ["one", "two"] @@ -40,7 +40,7 @@ for k,v in t >> #t2 = 1 >> t2.default -= !Int64 += !Int >> t2.fallback = ?(readonly){"one"=>1, "two"=>2; default=999} diff --git a/types.c b/types.c index f03fe26..59896b2 100644 --- a/types.c +++ b/types.c @@ -17,8 +17,8 @@ CORD type_to_cord(type_t *t) { case MemoryType: return "Memory"; case BoolType: return "Bool"; case StringType: return "Str"; - case IntType: return CORD_asprintf("Int%ld", Match(t, IntType)->bits); - case NumType: return CORD_asprintf("Num%ld", Match(t, NumType)->bits); + case IntType: return Match(t, IntType)->bits == 64 ? "Int" : CORD_asprintf("Int%ld", Match(t, IntType)->bits); + case NumType: return Match(t, NumType)->bits == 64 ? "Num" : CORD_asprintf("Num%ld", Match(t, NumType)->bits); case ArrayType: { auto array = Match(t, ArrayType); return CORD_asprintf("[%r]", type_to_cord(array->item_type));