aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--builtins/functions.c4
-rw-r--r--builtins/integers.c30
-rw-r--r--builtins/integers.h6
-rw-r--r--compile.c4
-rw-r--r--test/integers.tm10
6 files changed, 38 insertions, 18 deletions
diff --git a/Makefile b/Makefile
index d115aad7..8780ec21 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,7 @@ tags:
$(CC) $(CFLAGS) -c $< -o $@
%.tm.testresult: %.tm tomo
- VERBOSE=0 COLOR=1 CC=tcc ./tomo $< 2>$@ >$@ && cat $@
+ VERBOSE=0 COLOR=1 CC=gcc ./tomo $< 2>$@ >$@ && cat $@
test: $(TESTS)
@echo -e '\x1b[32;7m ALL TESTS PASSED! \x1b[m'
diff --git a/builtins/functions.c b/builtins/functions.c
index cb75442d..d71587b9 100644
--- a/builtins/functions.c
+++ b/builtins/functions.c
@@ -45,9 +45,9 @@ static void print_stack_trace(FILE *out)
fprintf(out, "\x1b[34m");
fflush(out);
void *array[1024];
- size_t size = backtrace(array, sizeof(array)/sizeof(array[0]));
+ int64_t size = (int64_t)backtrace(array, sizeof(array)/sizeof(array[0]));
char **strings = strings = backtrace_symbols(array, size);
- for (size_t i = 2; i < size - 4; i++) {
+ for (int64_t i = 2; i < size - 4; i++) {
char *filename = strings[i];
const char *cmd = heap_strf("addr2line -e %.*s -fisp | sed 's/\\$/./g;s/ at /() at /' >&2", strcspn(filename, "("), filename);
FILE *fp = popen(cmd, "w");
diff --git a/builtins/integers.c b/builtins/integers.c
index 8bc66172..dd38de91 100644
--- a/builtins/integers.c
+++ b/builtins/integers.c
@@ -75,28 +75,48 @@ public bool Int$hash(const Int_t *x, const TypeInfo *type) {
return hash;
}
-public CORD Int$hex(Int_t i, int64_t digits, bool uppercase, bool prefix) {
+public CORD Int$format(Int_t i, Int_t digits_int)
+{
+ int64_t digits = Int$as_i64(digits_int);
+ if (__builtin_expect(i.small & 1, 1)) {
+ return CORD_asprintf("%0.*ld", digits, (i.small)>>2);
+ } else {
+ CORD str = mpz_get_str(NULL, 10, *i.big);
+ bool negative = (str[0] == '-');
+ if (digits > (int64_t)CORD_len(str)) {
+ if (negative)
+ str = CORD_all("-", CORD_chars('0', digits - CORD_len(str)), CORD_substr(str, 1, ~0));
+ else
+ str = CORD_all(CORD_chars('0', digits - CORD_len(str)), str);
+ }
+ return str;
+ }
+}
+
+public CORD Int$hex(Int_t i, Int_t digits_int, bool uppercase, bool prefix) {
+ int64_t digits = Int$as_i64(digits_int);
const char *hex_fmt = uppercase ? (prefix ? "0x%0.*lX" : "%0.*lX") : (prefix ? "0x%0.*lx" : "%0.*lx");
if (__builtin_expect(i.small & 1, 1)) {
- return CORD_asprintf(hex_fmt, (i.small)>>2);
+ return CORD_asprintf(hex_fmt, digits, (i.small)>>2);
} else {
CORD str = mpz_get_str(NULL, 16, *i.big);
if (uppercase) str = Text$upper(str);
if (digits > (int64_t)CORD_len(str))
- str = CORD_cat(str, CORD_chars('0', digits - CORD_len(str)));
+ str = CORD_cat(CORD_chars('0', digits - CORD_len(str)), str);
if (prefix) str = CORD_cat("0x", str);
return str;
}
}
-public CORD Int$octal(Int_t i, int64_t digits, bool prefix) {
+public CORD Int$octal(Int_t i, Int_t digits_int, bool prefix) {
+ int64_t digits = Int$as_i64(digits_int);
const char *octal_fmt = prefix ? "0o%0.*lo" : "%0.*lo";
if (__builtin_expect(i.small & 1, 1)) {
return CORD_asprintf(octal_fmt, (int)digits, (uint64_t)(i.small >> 2));
} else {
CORD str = mpz_get_str(NULL, 8, *i.big);
if (digits > (int64_t)CORD_len(str))
- str = CORD_cat(str, CORD_chars('0', digits - CORD_len(str)));
+ str = CORD_cat(CORD_chars('0', digits - CORD_len(str)), str);
if (prefix) str = CORD_cat("0o", str);
return str;
}
diff --git a/builtins/integers.h b/builtins/integers.h
index a586dfcf..f93e7abf 100644
--- a/builtins/integers.h
+++ b/builtins/integers.h
@@ -50,9 +50,9 @@ int32_t Int$compare(const Int_t *x, const Int_t *y, const TypeInfo *type);
int32_t Int$compare_value(const Int_t x, const Int_t y);
bool Int$equal(const Int_t *x, const Int_t *y, const TypeInfo *type);
bool Int$equal_value(const Int_t x, const Int_t y);
-CORD Int$format(Int_t i, int64_t digits);
-CORD Int$hex(Int_t i, int64_t digits, bool uppercase, bool prefix);
-CORD Int$octal(Int_t i, int64_t digits, bool prefix);
+CORD Int$format(Int_t i, Int_t digits);
+CORD Int$hex(Int_t i, Int_t digits, bool uppercase, bool prefix);
+CORD Int$octal(Int_t i, Int_t digits, bool prefix);
void Int$init_random(long seed);
Int_t Int$random(Int_t min, Int_t max);
Range_t Int$to(Int_t from, Int_t to);
diff --git a/compile.c b/compile.c
index af7211ad..2377ec25 100644
--- a/compile.c
+++ b/compile.c
@@ -1487,8 +1487,8 @@ CORD compile(env_t *env, ast_t *ast)
switch (binop->op) {
case BINOP_POWER: {
- if (operand_t->tag != NumType && operand_t->tag != IntType)
- code_err(ast, "Exponentiation is only supported for numeric types");
+ if (operand_t->tag != NumType)
+ code_err(ast, "Exponentiation is only supported for Num types");
if (operand_t->tag == NumType && Match(operand_t, NumType)->bits == 32)
return CORD_all("powf(", lhs, ", ", rhs, ")");
else
diff --git a/test/integers.tm b/test/integers.tm
index 94ab8ac6..a99f614a 100644
--- a/test/integers.tm
+++ b/test/integers.tm
@@ -14,7 +14,7 @@ func main():
>> 1i8 + 2i16
= 3_i16
- >> 2 ^ 10
+ >> 1 << 10
= 1024 : Num
>> 3 and 2
@@ -32,7 +32,7 @@ func main():
>> nums
= "1,2,3,4,5,"
- >> x := 123
+ >> x := 123i64
>> x:format(digits=5)
= "00123"
>> x:hex()
@@ -40,10 +40,10 @@ func main():
>> x:octal()
= "0o173"
- >> Int.random()
- >> Int.min
+ >> Int.random(1, 100)
+ >> Int64.min
= -9223372036854775808
- >> Int.max
+ >> Int64.max
= 9223372036854775807