diff --git a/lib/core/src/StaticBuffer.c.ri b/lib/core/src/StaticBuffer.c.ri index 98bd43e48..d99699ca0 100644 --- a/lib/core/src/StaticBuffer.c.ri +++ b/lib/core/src/StaticBuffer.c.ri @@ -21,6 +21,11 @@ struct StaticBuffer { return unsafe { libc.strtoul(&self.buf[0], none, 10) }; } + pub func as_uint(&self) -> uint { + self.buf[self.len] = 0; + return unsafe { @as(uint, libc.strtoul(&self.buf[0], none, 10)) }; + } + pub func as_int(&self) -> int { self.buf[self.len] = 0; return unsafe { @as(int, libc.strtol(&self.buf[0], none, 10))}; diff --git a/lib/core/src/StringFormatter.ri b/lib/core/src/StringFormatter.ri index 8ff1ca71f..eb0527f70 100644 --- a/lib/core/src/StringFormatter.ri +++ b/lib/core/src/StringFormatter.ri @@ -65,7 +65,7 @@ pub struct StringFormatter { ); } } - index := buf.as_uint64(); + index := buf.as_uint(); if index >= args.len { runtime_error( "string.fmt: argument index out of range (index: {}, len: {})", diff --git a/lib/core/src/int.ri b/lib/core/src/int.ri index d4df25c3a..9ebbfa1d8 100644 --- a/lib/core/src/int.ri +++ b/lib/core/src/int.ri @@ -61,7 +61,7 @@ extend int32 < Stringable { while n > 0 { n1 := @as(int32, n / 100); d = @as(uint32, @as(int32, n) - (n1 * 100)) << 1; - n = n1; + n = @as(int64, n1); buf[index] = digitPairs.ptr[d]; index -= 1; d += 1; diff --git a/lib/core/src/string.c.ri b/lib/core/src/string.c.ri index 2af80e869..29c14ea5a 100644 --- a/lib/core/src/string.c.ri +++ b/lib/core/src/string.c.ri @@ -818,7 +818,7 @@ pub struct string < Stringable, Hashable, Throwable { #[inline] pub func hash(self) -> uint { - return sum64_string(self); + return @as(uint, sum64_string(self)); } #[inline] diff --git a/lib/core/src/wyhash.c.ri b/lib/core/src/wyhash.c.ri index b03d77955..b7fb1563f 100644 --- a/lib/core/src/wyhash.c.ri +++ b/lib/core/src/wyhash.c.ri @@ -5,7 +5,7 @@ import c; #[unsafe; inline] -func wyhash(key: &uint8, len: uint64, seed: uint64) -> uint64 { +func wyhash(key: &uint8, len: uint, seed: uint64) -> uint64 { return unsafe { c.wyhash(key, len, seed, &c._wyp[0]) }; } @@ -16,10 +16,10 @@ func wyhash64(a: uint64, b: uint64) -> uint64 { #[inline] pub func sum64(key: []uint8, seed: uint64 := 0) -> uint64 { - return unsafe { wyhash(&key[0], @as(uint64, key.len), seed) }; + return unsafe { wyhash(&key[0], key.len, seed) }; } #[inline] pub func sum64_string(key: string, seed: uint64 := 0) -> uint64 { - return unsafe { wyhash(key.ptr, @as(uint64, key.len), seed) }; + return unsafe { wyhash(key.ptr, key.len, seed) }; } diff --git a/lib/core/tests/string_test.ri b/lib/core/tests/string_test.ri index 89b742796..0e072a1c2 100644 --- a/lib/core/tests/string_test.ri +++ b/lib/core/tests/string_test.ri @@ -146,12 +146,7 @@ test "string.parse_int()" { @assert("9223372036854775807".parse_int(10, 64)! == 9223372036854775807); @assert("baobab".parse_int(36, 64)! == 123314438); - // invalid bit sizes - @assert(if _ := "123".parse_int(10, -1) { - false - } else { - true - }); + // invalid bit size @assert(if _ := "123".parse_int(10, 65) { false } else { diff --git a/lib/rivet/src/ast/Table.ri b/lib/rivet/src/ast/Table.ri index a63052a7c..44eb67580 100644 --- a/lib/rivet/src/ast/Table.ri +++ b/lib/rivet/src/ast/Table.ri @@ -241,7 +241,7 @@ pub struct Table { pub func comptime_number_to_type(self, type: Type) -> Type { return if type == self.comptime_int_t { - self.int32_t + self.int_t } else if type == self.comptime_float_t { self.float64_t } else { diff --git a/lib/rivet/src/checker/exprs.ri b/lib/rivet/src/checker/exprs.ri index 0b10d81e2..f3c6f6281 100644 --- a/lib/rivet/src/checker/exprs.ri +++ b/lib/rivet/src/checker/exprs.ri @@ -641,7 +641,7 @@ extend Checker { ); } } else { - promoted_type = self.promote(left_type, right_type); + promoted_type = left_type; if promoted_type is .Void { report.error( "mismatched types `{}` and `{}`".fmt(left_type, right_type), diff --git a/lib/rivet/src/checker/types.ri b/lib/rivet/src/checker/types.ri index d25f8d2d3..3785b7eba 100644 --- a/lib/rivet/src/checker/types.ri +++ b/lib/rivet/src/checker/types.ri @@ -145,7 +145,6 @@ extend Checker { if self.table.is_comptime_number(expected) || self.table.is_comptime_number(got) { return true; } - return self.promote_number(expected, got) == expected; } match expected_sym.info { @@ -192,65 +191,6 @@ extend Checker { return expected == got; } - - func promote(self, left_type: ast.Type, right_type: ast.Type) -> ast.Type { - if left_type == right_type { - return left_type; - } else if self.table.is_number(left_type) && self.table.is_number(right_type) { - return self.promote_number(left_type, right_type); - } - return left_type; - } - - func promote_number(self, expected: ast.Type, got: ast.Type) -> ast.Type { - mut type_hi := expected; - mut type_lo := got; - mut bits_hi := self.table.number_bits(type_hi); - mut bits_lo := self.table.number_bits(type_lo); - if bits_hi < bits_lo { - old_hi := type_hi; - type_hi = type_lo; - type_lo = old_hi; - - old_bhi := bits_hi; - bits_hi = bits_lo; - bits_lo = old_bhi; - } - - return if self.table.is_float(type_hi) { - if self.table.is_float(type_lo) { - // float -> float (good) - type_hi - } else { - // float -> int (bad) - .Void - } - } else { - is_signed_lo := self.table.is_signed_int(type_lo); - is_unsigned_lo := !is_signed_lo; - - is_signed_hi := self.table.is_signed_int(type_hi); - is_unsigned_hi := !is_signed_hi; - - if is_unsigned_lo && is_unsigned_hi { - // unsigned number -> unsigned number (good) - type_hi - } else if is_signed_lo && is_signed_hi { - // signed number -> signed number (good) - if bits_lo == 64 && bits_hi != 64 { - type_lo - } else { - type_hi - } - } else if is_unsigned_lo && is_signed_hi && bits_hi > bits_lo { - // unsigned number -> signed number (good, if signed type is larger) - type_lo - } else { - // signed number -> unsigned number (bad) - .Void - } - }; - } } func check_pointer(expected: ast.Type, got: ast.Type) -> bool { diff --git a/lib/rivet/tests/tokenizer.ri b/lib/rivet/tests/tokenizer.ri index 9550761f8..d4fc35bfc 100644 --- a/lib/rivet/tests/tokenizer.ri +++ b/lib/rivet/tests/tokenizer.ri @@ -5,7 +5,7 @@ import rivet/prefs; import rivet/token; import rivet/tokenizer; -import rivet/ast.{ Table }; +import rivet/ast.Table; var prefs_ := prefs.Prefs(); diff --git a/lib/std/src/hash/fnv1a/mod.ri b/lib/std/src/hash/fnv1a/mod.ri index 4be85c972..c0d85875e 100644 --- a/lib/std/src/hash/fnv1a/mod.ri +++ b/lib/std/src/hash/fnv1a/mod.ri @@ -76,7 +76,7 @@ pub func sum64_string(data: string) -> uint64 { mut hash := FNV64_OFFSET_BASIS; mut i: uint := 0; while i < data.len : i += 1 { - hash = (hash ^ @as(uint32, data[i])) * FNV64_PRIME; + hash = (hash ^ @as(uint64, data[i])) * FNV64_PRIME; } return hash; } diff --git a/lib/std/src/semver/parse.ri b/lib/std/src/semver/parse.ri index f6febcda0..9538b51f6 100644 --- a/lib/std/src/semver/parse.ri +++ b/lib/std/src/semver/parse.ri @@ -2,9 +2,9 @@ // Use of this source code is governed by an MIT license that can // be found in the LICENSE file. -const VER_MAJOR: uint64 := 0; -const VER_MINOR: uint64 := 1; -const VER_PATCH: uint64 := 2; +const VER_MAJOR: uint := 0; +const VER_MINOR: uint := 1; +const VER_PATCH: uint := 2; var versions := [VER_MAJOR, VER_MINOR, VER_PATCH]; struct RawVersion { @@ -40,7 +40,7 @@ struct RawVersion { } #[inline] - func is_missing(&self, typ: uint64) -> bool { + func is_missing(&self, typ: uint) -> bool { return typ >= self.raw_ints.len - 1; } diff --git a/lib/std/src/strings/TextScanner.ri b/lib/std/src/strings/TextScanner.ri index 724f873df..8021d7fec 100644 --- a/lib/std/src/strings/TextScanner.ri +++ b/lib/std/src/strings/TextScanner.ri @@ -71,7 +71,7 @@ pub struct TextScanner { /// of the input text. /// NOTE: after `c := ts.next()`, `ts.current()` will also return `c`. #[inline] - pub func current(self) -> ?uint { + pub func current(self) -> ?uint8 { if self.pos > 0 { return self.input[self.pos - 1]; } diff --git a/lib/std/tests/semver_test.ri b/lib/std/tests/semver_test.ri index 1bd51b192..43025de56 100644 --- a/lib/std/tests/semver_test.ri +++ b/lib/std/tests/semver_test.ri @@ -2,9 +2,9 @@ import std/semver; struct TestVersion { raw: string; - major: uint64; - minor: uint64; - patch: uint64; + major: uint; + minor: uint; + patch: uint; prerelease: string; metadata: string; } diff --git a/rivetc/src/__init__.py b/rivetc/src/__init__.py index 438185524..7d407892d 100644 --- a/rivetc/src/__init__.py +++ b/rivetc/src/__init__.py @@ -314,7 +314,7 @@ def is_comptime_number(self, typ): def comptime_number_to_type(self, typ): if typ == self.comptime_int_t: - return self.int32_t + return self.int_t elif typ == self.comptime_float_t: return self.float64_t return typ diff --git a/rivetc/src/checker.py b/rivetc/src/checker.py index 8eb71906b..2afab9a91 100644 --- a/rivetc/src/checker.py +++ b/rivetc/src/checker.py @@ -390,7 +390,10 @@ def check_expr(self, expr): expr.typ = self.comp.rune_t return expr.typ elif isinstance(expr, ast.IntegerLiteral): - expr.typ = self.comp.comptime_int_t + if self.comp.is_number(self.expected_type): + expr.typ = self.expected_type + else: + expr.typ = self.comp.comptime_int_t return expr.typ elif isinstance(expr, ast.FloatLiteral): expr.typ = self.comp.comptime_float_t @@ -687,7 +690,7 @@ def check_expr(self, expr): expr.pos ) else: - promoted_type = self.promote(ltyp, rtyp) + promoted_type = ltyp if promoted_type == self.comp.void_t: report.error( f"mismatched types `{ltyp}` and `{rtyp}`", expr.pos @@ -1838,7 +1841,6 @@ def check_compatible_types(self, got, expected): expected ) or self.comp.is_comptime_number(got): return True - return self.promote_number(expected, got) == expected elif exp_sym.kind == TypeKind.Trait: if self.comp.comptime_number_to_type(got).symbol( ) in exp_sym.info.implements: @@ -1876,52 +1878,6 @@ def check_pointer(self, expected, got): return False return expected.typ == got.typ - def promote(self, left_typ, right_typ): - if left_typ == right_typ: - return left_typ - elif self.comp.is_number(left_typ) and self.comp.is_number(right_typ): - return self.promote_number(left_typ, right_typ) - return left_typ - - def promote_number(self, expected, got): - type_hi = expected - type_lo = got - bits_hi = self.comp.num_bits(type_hi) - bits_lo = self.comp.num_bits(type_lo) - if bits_hi < bits_lo: - old_hi = type_hi - type_hi = type_lo - type_lo = old_hi - - old_bhi = bits_hi - bits_hi = bits_lo - bits_lo = old_bhi - - if self.comp.is_float(type_hi): - if self.comp.is_float(type_lo): - # float -> float (good) - return type_hi - # float -> int (bad) - return self.comp.void_t - - is_signed_lo = self.comp.is_signed_int(type_lo) - is_unsigned_lo = not is_signed_lo - is_signed_hi = self.comp.is_signed_int(type_hi) - is_unsigned_hi = not is_signed_hi - - if is_unsigned_lo and is_unsigned_hi: - # unsigned number -> unsigned number (good) - return type_hi - elif is_signed_lo and is_signed_hi: - # signed number -> signed number (good) - return type_lo if bits_lo == 64 and is_signed_lo else type_hi - elif is_unsigned_lo and is_signed_hi and bits_lo < bits_hi: - # unsigned number -> signed number (good, if signed type is larger) - return type_lo - else: - # signed number -> unsigned number (bad) - return self.comp.void_t - def check_expr_is_mut(self, expr, from_assign = False): if isinstance(expr, ast.ParExpr): self.check_expr_is_mut(expr.expr) diff --git a/rivetc/src/codegen/c_headers.py b/rivetc/src/codegen/c_headers.py index 87138545b..2ffb0ce4c 100644 --- a/rivetc/src/codegen/c_headers.py +++ b/rivetc/src/codegen/c_headers.py @@ -64,7 +64,7 @@ typedef uint64_t uint64; typedef ptrdiff_t ri_int; typedef size_t ri_uint; -typedef ri_int comptime_int; // TODO: remove +typedef ri_int comptime_int; typedef uint8 bool; typedef uint32 rune; diff --git a/tests/b_invalid/checking_trait.out b/tests/b_invalid/checking_trait.out index dd38e3929..c3e183491 100644 --- a/tests/b_invalid/checking_trait.out +++ b/tests/b_invalid/checking_trait.out @@ -1,4 +1,4 @@ -tests/b_invalid/checking_trait.ri:24:14: error: type `int32` does not implement trait `ToStr` +tests/b_invalid/checking_trait.ri:24:14: error: type `int` does not implement trait `ToStr` 24 | my_print(1); // FAIL | ^ = note: in argument `v` of function `my_print` diff --git a/tests/invalid/checking_trait.out b/tests/invalid/invalid_trait_implementation.out similarity index 52% rename from tests/invalid/checking_trait.out rename to tests/invalid/invalid_trait_implementation.out index f595a66fa..f29a568dc 100644 --- a/tests/invalid/checking_trait.out +++ b/tests/invalid/invalid_trait_implementation.out @@ -1,7 +1,4 @@ -tests/invalid/checking_trait.ri:2:18: error: cannot take the address of a boxed value as receiver - 2 | func to_str1(&self) -> string; - | ^~~~~ -tests/invalid/checking_trait.ri:10:5-12:5: error: type `checking_trait.MyStruct1` incorrectly implements method `to_str1` of trait `checking_trait.ToStr` +tests/invalid/invalid_trait_implementation.ri:10:5-12:5: error: type `invalid_trait_implementation.MyStruct1` incorrectly implements method `to_str1` of trait `invalid_trait_implementation.ToStr` | /~~ from here 10 | func to_str1(self) -> string { 11 | return self; @@ -11,13 +8,13 @@ tests/invalid/checking_trait.ri:10:5-12:5: error: type `checking_trait.MyStruct1 = note: receiver `self` should be a reference, or use the attribute `boxed`. = note: ====== method signature for `to_str1` ====== - = note: trait `ToStr` has `func(&self) -> string` + = note: trait `ToStr` has `func(self) -> string` = note: type `MyStruct1` has `func(self) -> string` -tests/invalid/checking_trait.ri:11:16: error: expected type `string`, found `MyStruct1` +tests/invalid/invalid_trait_implementation.ri:11:16: error: expected type `string`, found `MyStruct1` 11 | return self; | ^~~~ = note: in return of method `to_str1` -tests/invalid/checking_trait.ri:16:5-18:5: error: type `checking_trait.MyStruct2` incorrectly implements method `to_str1` of trait `checking_trait.ToStr` +tests/invalid/invalid_trait_implementation.ri:16:5-18:5: error: type `invalid_trait_implementation.MyStruct2` incorrectly implements method `to_str1` of trait `invalid_trait_implementation.ToStr` | /~~ from here 16 | func to_str1(&self) -> string { 17 | return if self.* { "true" } else { "false" }; @@ -25,21 +22,21 @@ tests/invalid/checking_trait.ri:16:5-18:5: error: type `checking_trait.MyStruct2 | ^~~ to here = note: method `to_str1` should be public. = note: ====== method signature for `to_str1` ====== - = note: trait `ToStr` has `func(&self) -> string` + = note: trait `ToStr` has `func(self) -> string` = note: type `MyStruct2` has `func(&self) -> string` -tests/invalid/checking_trait.ri:17:19: error: non-boolean expression used as `if` condition +tests/invalid/invalid_trait_implementation.ri:17:19: error: non-boolean expression used as `if` condition 17 | return if self.* { "true" } else { "false" }; | ^~~~~~ -tests/invalid/checking_trait.ri:22:14: error: type `string` does not implement trait `ToStr` +tests/invalid/invalid_trait_implementation.ri:22:14: error: type `string` does not implement trait `ToStr` 22 | my_print(""); // OK | ^~ = note: in argument `v` of function `my_print` -tests/invalid/checking_trait.ri:23:14: error: type `bool` does not implement trait `ToStr` +tests/invalid/invalid_trait_implementation.ri:23:14: error: type `bool` does not implement trait `ToStr` 23 | my_print(true); // OK | ^~~~ = note: in argument `v` of function `my_print` -tests/invalid/checking_trait.ri:24:14: error: type `int32` does not implement trait `ToStr` +tests/invalid/invalid_trait_implementation.ri:24:14: error: type `int` does not implement trait `ToStr` 24 | my_print(1); // FAIL | ^ = note: in argument `v` of function `my_print` -rivet: error: could not compile module `checking_trait`, aborting due to 8 previous errors \ No newline at end of file +rivet: error: could not compile module `invalid_trait_implementation`, aborting due to 7 previous errors \ No newline at end of file diff --git a/tests/invalid/checking_trait.ri b/tests/invalid/invalid_trait_implementation.ri similarity index 91% rename from tests/invalid/checking_trait.ri rename to tests/invalid/invalid_trait_implementation.ri index 983c65480..fa9e492c9 100644 --- a/tests/invalid/checking_trait.ri +++ b/tests/invalid/invalid_trait_implementation.ri @@ -1,5 +1,5 @@ trait ToStr { - func to_str1(&self) -> string; + func to_str1(self) -> string; } func my_print(v: ToStr) { diff --git a/tests/valid/src/call_expr.ri b/tests/valid/src/call_expr.ri index 933479563..ca4c36835 100644 --- a/tests/valid/src/call_expr.ri +++ b/tests/valid/src/call_expr.ri @@ -25,7 +25,7 @@ test "call expression with named arguments" { qux(a); } -func args(values: ...int32) -> int32 { +func args(values: ...int) -> int { mut res := 0; for v in values { res += v; @@ -38,7 +38,7 @@ test "call expression with spread expression" { @assert(args(...+[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]) == 55); } -func mutable_primitive_type_argument(mut a: int32) { +func mutable_primitive_type_argument(mut a: int) { a += 2; } diff --git a/tests/valid/src/for_stmt.ri b/tests/valid/src/for_stmt.ri index 804d13815..3dab226a0 100644 --- a/tests/valid/src/for_stmt.ri +++ b/tests/valid/src/for_stmt.ri @@ -17,14 +17,14 @@ test "`for` statement with dynamic array" { test "`for` statement with `string.as_bytes()`" { mut sum := 0; for b in "Hello World!".as_bytes() { - sum += @as(int32, b); + sum += @as(int, b); } @assert(sum == 1085); } test "`for` statement with referenced value" { mut res := 0; - arr: []mut int32 := +[1, 2, 3]; + arr: []mut int := +[1, 2, 3]; for &value in arr { res += value.*; }