From b44f81528f33c4a18c923dc1ea2c6cfec978bf60 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Mon, 26 Jul 2021 08:06:59 +0300 Subject: [PATCH] v.gen.c: fix codegen for `const a = u64(5) + 5` --- vlib/builtin/int.v | 74 +++++++++++++++--------- vlib/v/gen/c/cgen.v | 9 ++- vlib/v/tests/const_representation_test.v | 39 +++++++++++++ 3 files changed, 95 insertions(+), 27 deletions(-) create mode 100644 vlib/v/tests/const_representation_test.v diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 84c86cde00..7887367ea7 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -31,7 +31,7 @@ const ( // This implementation is the quickest with gcc -O2 // str_l returns the string representation of the integer nn with max chars. -[inline] [direct_array_access] +[direct_array_access; inline] fn (nn int) str_l(max int) string { unsafe { mut n := i64(nn) @@ -39,7 +39,7 @@ fn (nn int) str_l(max int) string { if n == 0 { return '0' } - + mut is_neg := false if n < 0 { n = -n @@ -84,7 +84,7 @@ fn (nn int) str_l(max int) string { */ return tos(buf, diff) - //return tos(memdup(&buf[0] + index, (max - index)), (max - index)) + // return tos(memdup(&buf[0] + index, (max - index)), (max - index)) } } @@ -114,7 +114,7 @@ pub fn (n int) str() string { // str returns the value of the `u32` as a `string`. // Example: assert u32(20000).str() == '20000' -[inline] [direct_array_access] +[direct_array_access; inline] pub fn (nn u32) str() string { unsafe { mut n := nn @@ -146,7 +146,7 @@ pub fn (nn u32) str() string { C.memmove(buf, buf + index, diff + 1) return tos(buf, diff) - //return tos(memdup(&buf[0] + index, (max - index)), (max - index)) + // return tos(memdup(&buf[0] + index, (max - index)), (max - index)) } } @@ -158,7 +158,7 @@ pub fn (n int_literal) str() string { // str returns the value of the `i64` as a `string`. // Example: assert i64(-200000).str() == '-200000' -[inline] [direct_array_access] +[direct_array_access; inline] pub fn (nn i64) str() string { unsafe { mut n := nn @@ -199,13 +199,13 @@ pub fn (nn i64) str() string { diff := max - index C.memmove(buf, buf + index, diff + 1) return tos(buf, diff) - //return tos(memdup(&buf[0] + index, (max - index)), (max - index)) + // return tos(memdup(&buf[0] + index, (max - index)), (max - index)) } } // str returns the value of the `u64` as a `string`. // Example: assert u64(2000000).str() == '2000000' -[inline] [direct_array_access] +[direct_array_access; inline] pub fn (nn u64) str() string { unsafe { mut n := nn @@ -236,7 +236,7 @@ pub fn (nn u64) str() string { diff := max - index C.memmove(buf, buf + index, diff + 1) return tos(buf, diff) - //return tos(memdup(&buf[0] + index, (max - index)), (max - index)) + // return tos(memdup(&buf[0] + index, (max - index)), (max - index)) } } @@ -254,7 +254,7 @@ pub fn (b bool) str() string { // // u64_to_hex converts the number `nn` to a (zero padded if necessary) hexadecimal `string`. -[inline] [direct_array_access] +[direct_array_access; inline] fn u64_to_hex(nn u64, len byte) string { mut n := nn mut buf := [256]byte{} @@ -270,7 +270,7 @@ fn u64_to_hex(nn u64, len byte) string { } // u64_to_hex_no_leading_zeros converts the number `nn` to hexadecimal `string`. -[inline] [direct_array_access] +[direct_array_access; inline] fn u64_to_hex_no_leading_zeros(nn u64, len byte) string { mut n := nn mut buf := [256]byte{} @@ -391,19 +391,47 @@ pub fn (nn voidptr) str() string { // hex returns the value of the `byteptr` as a hexadecimal `string`. // Note that the output is ***not*** zero padded. -//pub fn (nn byteptr) str() string { +// pub fn (nn byteptr) str() string { pub fn (nn byteptr) str() string { return u64(nn).hex() } -/* -pub fn (nn byte) hex_full() string { return u64_to_hex(nn, 2) } -pub fn (nn i8) hex_full() string { return u64_to_hex(byte(nn), 2) } -pub fn (nn u16) hex_full() string { return u64_to_hex(nn, 4) } -pub fn (nn i16) hex_full() string { return u64_to_hex(u16(nn), 4) } -pub fn (nn u32) hex_full() string { return u64_to_hex(nn, 8) } -pub fn (nn int) hex_full() string { return u64_to_hex(u32(nn), 8) } -*/ +pub fn (nn byte) hex_full() string { + return u64_to_hex(u64(nn), 2) +} + +pub fn (nn i8) hex_full() string { + return u64_to_hex(u64(nn), 2) +} + +pub fn (nn u16) hex_full() string { + return u64_to_hex(u64(nn), 4) +} + +pub fn (nn i16) hex_full() string { + return u64_to_hex(u64(nn), 4) +} + +pub fn (nn u32) hex_full() string { + return u64_to_hex(u64(nn), 8) +} + +pub fn (nn int) hex_full() string { + return u64_to_hex(u64(nn), 8) +} + +pub fn (nn i64) hex_full() string { + return u64_to_hex(u64(nn), 16) +} + +pub fn (nn voidptr) hex_full() string { + return u64_to_hex(u64(nn), 16) +} + +pub fn (nn int_literal) hex_full() string { + return u64_to_hex(u64(nn), 16) +} + // hex_full returns the value of the `u64` as a *full* 16-digit hexadecimal `string`. // Example: assert u64(2).hex_full() == '0000000000000002' // Example: assert u64(255).hex_full() == '00000000000000ff' @@ -411,12 +439,6 @@ pub fn (nn u64) hex_full() string { return u64_to_hex(nn, 16) } -/* -pub fn (nn i64) hex_full() string { return u64_to_hex(u64(nn), 16) } -pub fn (nn int_literal) hex_full() string { return u64_to_hex(nn, 16) } -pub fn (nn voidptr) hex_full() string { return u64_to_hex(nn, 16) } -pub fn (nn byteptr) hex_full() string { return u64_to_hex(nn, 16) } -*/ // str returns the contents of `byte` as a zero terminated `string`. // Example: assert byte(111).str() == '111' pub fn (b byte) str() string { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index f36a692ee7..90574cfd0c 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5000,6 +5000,9 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) { fn (mut g Gen) const_decl_precomputed(mod string, name string, ct_value ast.ComptTimeConstValue, typ ast.Type) bool { mut styp := g.typ(typ) cname := '_const_$name' + $if trace_const_precomputed ? { + eprintln('> styp: $styp | cname: $cname | ct_value: $ct_value | $ct_value.type_name()') + } match ct_value { byte { g.const_decl_write_precomputed(styp, cname, ct_value.str()) @@ -5026,7 +5029,11 @@ fn (mut g Gen) const_decl_precomputed(mod string, name string, ct_value ast.Comp g.const_decl_simple_define(name, ct_value.str()) return true } - g.const_decl_write_precomputed(styp, cname, ct_value.str()) + if typ == ast.u64_type { + g.const_decl_write_precomputed(styp, cname, ct_value.str() + 'U') + } else { + g.const_decl_write_precomputed(styp, cname, ct_value.str()) + } } u64 { g.const_decl_write_precomputed(styp, cname, ct_value.str() + 'U') diff --git a/vlib/v/tests/const_representation_test.v b/vlib/v/tests/const_representation_test.v new file mode 100644 index 0000000000..d1f8435e03 --- /dev/null +++ b/vlib/v/tests/const_representation_test.v @@ -0,0 +1,39 @@ +const zzz_byte_a = byte(`A`) + +const zzz_u16_a = u16(999) + 5 + +const zzza = u64(123) + +const zzzb = 5 + zzzc + +const zzzc = 6 + zzza + +const zzzx = zzza - 124 + +const zzz_zz = i64(-1) + +struct Abc { + x int +} + +const zzz_struct = Abc{123} + +const zzzs = 'xyz' + 'abc' + +fn test_number_consts() { + assert zzz_byte_a.hex_full() == '41' + assert zzz_u16_a.hex_full() == '03ec' + assert zzza.hex_full() == '000000000000007b' + assert zzzb.hex_full() == '0000000000000086' + assert zzzc.hex_full() == '0000000000000081' + // assert zzzx.hex_full() == '00000000ffffffff' // TODO: see why + assert zzz_zz.hex_full() == 'ffffffffffffffff' +} + +fn test_struct_consts() { + assert zzz_struct.str().contains('x: 123') +} + +fn test_string_consts() { + assert zzzs == 'xyzabc' +}