From cc8ee5fb84409a37f98ff684b86f982a666e0abb Mon Sep 17 00:00:00 2001 From: Enzo Date: Wed, 8 Sep 2021 04:53:39 +0200 Subject: [PATCH] all: introduce `isize` and `usize` (#11437) --- CHANGELOG.md | 4 ++ doc/docs.md | 2 + vlib/builtin/int.v | 9 +++ vlib/orm/orm.v | 44 +++++++----- vlib/orm/orm_fn_test.v | 25 +++---- vlib/sqlite/sqlite_orm_test.v | 11 +-- vlib/v/ast/types.v | 89 ++++++++++++++---------- vlib/v/checker/check_types.v | 2 +- vlib/v/gen/c/cgen.v | 3 +- vlib/v/gen/c/cheaders.v | 2 + vlib/v/gen/js/builtin_types.v | 4 +- vlib/v/markused/markused.v | 112 +++++++++++++++---------------- vlib/v/tests/integer_size_test.v | 36 ++++++++++ 13 files changed, 213 insertions(+), 130 deletions(-) create mode 100644 vlib/v/tests/integer_size_test.v diff --git a/CHANGELOG.md b/CHANGELOG.md index d4307c0633..493ecf2b60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +-## V 0.2.5 +-*Not yet released, changelog is not full* +- Introduce `isize` and `usize` types, deprecate `size_t` in favor of `usize` + -## V 0.2.4 -*Not yet released, changelog is not full* - Bare metal support. Vinix OS kernel is now being developed in V. diff --git a/doc/docs.md b/doc/docs.md index 78c27b7e04..bcb4ff1c0e 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -419,6 +419,8 @@ rune // represents a Unicode code point f32 f64 +isize, usize // platform-dependent, the size is how many bytes it takes to reference any location in memory + voidptr, size_t // these are mostly used for C interoperability any // similar to C's void* and Go's interface{} diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 24e658f276..845ae401d8 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -15,6 +15,15 @@ pub fn ptr_str(ptr voidptr) string { return buf1 } +// TODO uncomment to have string representation of i/usize +// pub fn (x isize) str() string { +// return u64(x).str() +// } +// +// pub fn (x usize) str() string { +// return u64(x).str() +// } + pub fn (x size_t) str() string { return u64(x).str() } diff --git a/vlib/orm/orm.v b/vlib/orm/orm.v index 960e1764f7..11cfc9a941 100644 --- a/vlib/orm/orm.v +++ b/vlib/orm/orm.v @@ -1,26 +1,38 @@ module orm import time +import v.ast pub const ( - num64 = [8, 12] - nums = [5, 6, 7, 9, 10, 11, 16] - float = [13, 14] - string = 18 + num64 = [ast.i64_type_idx, ast.u64_type_idx] + nums = [ + ast.i8_type_idx, + ast.i16_type_idx, + ast.int_type_idx, + ast.byte_type_idx, + ast.u16_type_idx, + ast.u32_type_idx, + ast.bool_type_idx, + ] + float = [ + ast.f32_type_idx, + ast.f64_type_idx, + ] + string = ast.string_type_idx time = -2 type_idx = { - 'i8': 5 - 'i16': 6 - 'int': 7 - 'i64': 8 - 'byte': 9 - 'u16': 10 - 'u32': 11 - 'u64': 12 - 'f32': 13 - 'f64': 14 - 'bool': 16 - 'string': 18 + 'i8': ast.i8_type_idx + 'i16': ast.i16_type_idx + 'int': ast.int_type_idx + 'i64': ast.i64_type_idx + 'byte': ast.byte_type_idx + 'u16': ast.u16_type_idx + 'u32': ast.u32_type_idx + 'u64': ast.u64_type_idx + 'f32': ast.f32_type_idx + 'f64': ast.f64_type_idx + 'bool': ast.bool_type_idx + 'string': ast.string_type_idx } string_max_len = 2048 ) diff --git a/vlib/orm/orm_fn_test.v b/vlib/orm/orm_fn_test.v index e79b17567f..a4ab0989e0 100644 --- a/vlib/orm/orm_fn_test.v +++ b/vlib/orm/orm_fn_test.v @@ -1,4 +1,5 @@ import orm +import v.ast fn test_orm_stmt_gen_update() { query := orm.orm_stmt_gen('Test', "'", .update, true, '?', 0, orm.QueryData{ @@ -120,7 +121,7 @@ fn test_orm_table_gen() { query := orm.orm_table_gen('test_table', "'", true, 0, [ orm.TableField{ name: 'id' - typ: 7 + typ: ast.int_type_idx default_val: '10' attrs: [ StructAttribute{ @@ -136,11 +137,11 @@ fn test_orm_table_gen() { }, orm.TableField{ name: 'test' - typ: 18 + typ: ast.string_type_idx }, orm.TableField{ name: 'abc' - typ: 8 + typ: ast.i64_type_idx default_val: '6754' }, ], sql_type_from_v, false) or { panic(err) } @@ -149,7 +150,7 @@ fn test_orm_table_gen() { alt_query := orm.orm_table_gen('test_table', "'", true, 0, [ orm.TableField{ name: 'id' - typ: 7 + typ: ast.int_type_idx default_val: '10' attrs: [ StructAttribute{ @@ -165,11 +166,11 @@ fn test_orm_table_gen() { }, orm.TableField{ name: 'test' - typ: 18 + typ: ast.string_type_idx }, orm.TableField{ name: 'abc' - typ: 8 + typ: ast.i64_type_idx default_val: '6754' }, ], sql_type_from_v, true) or { panic(err) } @@ -178,7 +179,7 @@ fn test_orm_table_gen() { unique_query := orm.orm_table_gen('test_table', "'", true, 0, [ orm.TableField{ name: 'id' - typ: 7 + typ: ast.int_type_idx default_val: '10' attrs: [ StructAttribute{ @@ -194,7 +195,7 @@ fn test_orm_table_gen() { }, orm.TableField{ name: 'test' - typ: 18 + typ: ast.string_type_idx attrs: [ StructAttribute{ name: 'unique' @@ -203,7 +204,7 @@ fn test_orm_table_gen() { }, orm.TableField{ name: 'abc' - typ: 8 + typ: ast.i64_type_idx default_val: '6754' }, ], sql_type_from_v, false) or { panic(err) } @@ -212,7 +213,7 @@ fn test_orm_table_gen() { mult_unique_query := orm.orm_table_gen('test_table', "'", true, 0, [ orm.TableField{ name: 'id' - typ: 7 + typ: ast.int_type_idx default_val: '10' attrs: [ StructAttribute{ @@ -228,7 +229,7 @@ fn test_orm_table_gen() { }, orm.TableField{ name: 'test' - typ: 18 + typ: ast.string_type_idx attrs: [ StructAttribute{ name: 'unique' @@ -240,7 +241,7 @@ fn test_orm_table_gen() { }, orm.TableField{ name: 'abc' - typ: 8 + typ: ast.i64_type_idx default_val: '6754' attrs: [ StructAttribute{ diff --git a/vlib/sqlite/sqlite_orm_test.v b/vlib/sqlite/sqlite_orm_test.v index efbd9fe4b1..4aa714293e 100644 --- a/vlib/sqlite/sqlite_orm_test.v +++ b/vlib/sqlite/sqlite_orm_test.v @@ -1,5 +1,6 @@ import orm import sqlite +import v.ast fn test_sqlite_orm() { sdb := sqlite.connect(':memory:') or { panic(err) } @@ -7,7 +8,7 @@ fn test_sqlite_orm() { db.create('Test', [ orm.TableField{ name: 'id' - typ: 7 + typ: ast.int_type_idx attrs: [ StructAttribute{ name: 'primary' @@ -22,12 +23,12 @@ fn test_sqlite_orm() { }, orm.TableField{ name: 'name' - typ: 18 + typ: ast.string_type_idx attrs: [] }, orm.TableField{ name: 'age' - typ: 8 + typ: ast.i64_type_idx }, ]) or { panic(err) } @@ -40,11 +41,11 @@ fn test_sqlite_orm() { table: 'Test' has_where: true fields: ['id', 'name', 'age'] - types: [7, 18, 8] + types: [ast.int_type_idx, ast.string_type_idx, ast.i64_type_idx] }, orm.QueryData{}, orm.QueryData{ fields: ['name', 'age'] data: [orm.Primitive('Louis'), i64(100)] - types: [18, 8] + types: [ast.string_type_idx, ast.i64_type_idx] is_and: [true, true] kinds: [.eq, .eq] }) or { panic(err) } diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 03a85dd6e8..7a0ec69cce 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -378,40 +378,45 @@ pub const ( i16_type_idx = 6 int_type_idx = 7 i64_type_idx = 8 - byte_type_idx = 9 - u16_type_idx = 10 - u32_type_idx = 11 - u64_type_idx = 12 - f32_type_idx = 13 - f64_type_idx = 14 - char_type_idx = 15 - bool_type_idx = 16 - none_type_idx = 17 - string_type_idx = 18 - rune_type_idx = 19 - array_type_idx = 20 - map_type_idx = 21 - chan_type_idx = 22 - size_t_type_idx = 23 - any_type_idx = 24 - float_literal_type_idx = 25 - int_literal_type_idx = 26 - thread_type_idx = 27 - error_type_idx = 28 - u8_type_idx = 29 + isize_type_idx = 9 + byte_type_idx = 10 + u16_type_idx = 11 + u32_type_idx = 12 + u64_type_idx = 13 + usize_type_idx = 14 + f32_type_idx = 15 + f64_type_idx = 16 + char_type_idx = 17 + bool_type_idx = 18 + none_type_idx = 19 + string_type_idx = 20 + rune_type_idx = 21 + array_type_idx = 22 + map_type_idx = 23 + chan_type_idx = 24 + size_t_type_idx = 25 + any_type_idx = 26 + float_literal_type_idx = 27 + int_literal_type_idx = 28 + thread_type_idx = 29 + error_type_idx = 30 + u8_type_idx = 31 ) pub const ( integer_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i64_type_idx, - byte_type_idx, u8_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, int_literal_type_idx, - rune_type_idx, + byte_type_idx, u8_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, isize_type_idx, + usize_type_idx, int_literal_type_idx, rune_type_idx] + signed_integer_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i64_type_idx, + isize_type_idx, + ] + unsigned_integer_type_idxs = [byte_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, + usize_type_idx, ] - signed_integer_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i64_type_idx] - unsigned_integer_type_idxs = [byte_type_idx, u16_type_idx, u32_type_idx, u64_type_idx] float_type_idxs = [f32_type_idx, f64_type_idx, float_literal_type_idx] number_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i64_type_idx, - byte_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, f32_type_idx, f64_type_idx, - int_literal_type_idx, float_literal_type_idx, rune_type_idx] + byte_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, isize_type_idx, usize_type_idx, + f32_type_idx, f64_type_idx, int_literal_type_idx, float_literal_type_idx, rune_type_idx] pointer_type_idxs = [voidptr_type_idx, byteptr_type_idx, charptr_type_idx] string_type_idxs = [string_type_idx] ) @@ -426,11 +431,13 @@ pub const ( int_type = new_type(int_type_idx) i16_type = new_type(i16_type_idx) i64_type = new_type(i64_type_idx) + isize_type = new_type(isize_type_idx) byte_type = new_type(byte_type_idx) u8_type = new_type(u8_type_idx) u16_type = new_type(u16_type_idx) u32_type = new_type(u32_type_idx) u64_type = new_type(u64_type_idx) + usize_type = new_type(usize_type_idx) f32_type = new_type(f32_type_idx) f64_type = new_type(f64_type_idx) char_type = new_type(char_type_idx) @@ -498,11 +505,13 @@ pub enum Kind { i16 int i64 + isize byte u8 u16 u32 u64 + usize f32 f64 char @@ -632,10 +641,12 @@ pub fn (mut t Table) register_builtin_type_symbols() { t.register_type_symbol(kind: .i16, name: 'i16', cname: 'i16', mod: 'builtin') t.register_type_symbol(kind: .int, name: 'int', cname: 'int', mod: 'builtin') t.register_type_symbol(kind: .i64, name: 'i64', cname: 'i64', mod: 'builtin') + t.register_type_symbol(kind: .isize, name: 'isize', cname: 'isize', mod: 'builtin') t.register_type_symbol(kind: .byte, name: 'byte', cname: 'byte', mod: 'builtin') t.register_type_symbol(kind: .u16, name: 'u16', cname: 'u16', mod: 'builtin') t.register_type_symbol(kind: .u32, name: 'u32', cname: 'u32', mod: 'builtin') t.register_type_symbol(kind: .u64, name: 'u64', cname: 'u64', mod: 'builtin') + t.register_type_symbol(kind: .usize, name: 'usize', cname: 'usize', mod: 'builtin') t.register_type_symbol(kind: .f32, name: 'f32', cname: 'f32', mod: 'builtin') t.register_type_symbol(kind: .f64, name: 'f64', cname: 'f64', mod: 'builtin') t.register_type_symbol(kind: .char, name: 'char', cname: 'char', mod: 'builtin') @@ -680,7 +691,9 @@ pub fn (t &TypeSymbol) is_pointer() bool { [inline] pub fn (t &TypeSymbol) is_int() bool { - res := t.kind in [.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .int_literal, .rune] + res := t.kind in [.i8, .i16, .int, .i64, .isize, .byte, .u16, .u32, .u64, .usize, .int_literal, + .rune, + ] if !res && t.kind == .alias { return (t.info as Alias).parent_type.is_number() } @@ -725,11 +738,13 @@ pub fn (k Kind) str() string { .i8 { 'i8' } .i16 { 'i16' } .i64 { 'i64' } + .isize { 'isize' } .byte { 'byte' } .u8 { 'u8' } .u16 { 'u16' } .u32 { 'u32' } .u64 { 'u64' } + .usize { 'usize' } .int_literal { 'int_literal' } .f32 { 'f32' } .f64 { 'f64' } @@ -927,16 +942,16 @@ pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string] .int_literal, .float_literal { res = sym.name } - .i8, .i16, .int, .i64, .byte, .u8, .u16, .u32, .u64, .f32, .f64, .char, .rune, .string, - .bool, .none_, .byteptr, .voidptr, .charptr { + .byteptr { + res = '&byte' + } + .charptr { + res = '&char' + } + .i8, .i16, .int, .i64, .isize, .byte, .u8, .u16, .u32, .u64, .usize, .f32, .f64, .char, + .rune, .string, .bool, .none_, .voidptr { // primitive types - if sym.kind == .byteptr { - res = '&byte' - } else if sym.kind == .charptr { - res = '&char' - } else { - res = sym.kind.str() - } + res = sym.kind.str() } .array { if typ == ast.array_type { diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 8bc96c3d28..8d14cb0960 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -254,7 +254,7 @@ fn (c &Checker) promote_num(left_type ast.Type, right_type ast.Type) ast.Type { } else if idx_lo >= ast.byte_type_idx { // both operands are unsigned return type_hi } else if idx_lo >= ast.i8_type_idx - && (idx_hi <= ast.i64_type_idx || idx_hi == ast.rune_type_idx) { // both signed + && (idx_hi <= ast.isize_type_idx || idx_hi == ast.rune_type_idx) { // both signed return if idx_lo == ast.i64_type_idx { type_lo } else { type_hi } } else if idx_hi - idx_lo < (ast.byte_type_idx - ast.i8_type_idx) { return type_lo // conversion unsigned -> signed if signed type is larger diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 3c7804d504..a9398c143c 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -416,7 +416,8 @@ pub fn (mut g Gen) init() { #endif' g.cheaders.writeln(tcc_undef_has_include) g.includes.writeln(tcc_undef_has_include) - g.cheaders.writeln(get_guarded_include_text('', 'The C compiler can not find . Please install build-essentials')) // int64_t etc + g.cheaders.writeln(get_guarded_include_text('', 'The C compiler can not find . Please install build-essentials')) // int64_t etc + g.cheaders.writeln(get_guarded_include_text('', 'The C compiler can not find . Please install build-essentials')) // size_t, ptrdiff_t g.cheaders.writeln(c_builtin_types) if g.pref.is_bare { g.cheaders.writeln(c_bare_headers) diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index 1c03c6f6dd..7989006991 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -512,6 +512,8 @@ typedef uint8_t u8; typedef uint16_t u16; typedef uint8_t byte; typedef uint32_t rune; +typedef size_t usize; +typedef ptrdiff_t isize; typedef float f32; typedef double f64; typedef int64_t int_literal; diff --git a/vlib/v/gen/js/builtin_types.v b/vlib/v/gen/js/builtin_types.v index 916490aa92..330e4c8a0c 100644 --- a/vlib/v/gen/js/builtin_types.v +++ b/vlib/v/gen/js/builtin_types.v @@ -132,8 +132,8 @@ pub fn (mut g JsGen) typ(t ast.Type) string { .byteptr, .charptr { styp = '${g.sym_to_js_typ(sym)}' } - .i8, .i16, .int, .i64, .byte, .u8, .u16, .u32, .u64, .f32, .f64, .int_literal, - .float_literal, .size_t { + .i8, .i16, .int, .i64, .isize, .byte, .u8, .u16, .u32, .u64, .usize, .f32, .f64, + .int_literal, .float_literal, .size_t { styp = '${g.sym_to_js_typ(sym)}' } .bool { diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index c40dcbedac..bc6330ed1f 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -54,52 +54,52 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F '4.vstring_with_len', '4.vstring_literal', // byte. methods - '9.str_escaped', + '10.str_escaped', // string. methods - '18.add', - '18.trim_space', - '18.repeat', - '18.replace', - '18.clone', - '18.clone_static', - '18.trim', - '18.substr', - '18.at', - '18.at_with_check', - '18.index_kmp', + '20.add', + '20.trim_space', + '20.repeat', + '20.replace', + '20.clone', + '20.clone_static', + '20.trim', + '20.substr', + '20.at', + '20.at_with_check', + '20.index_kmp', // string. ==, !=, etc... - '18.eq', - '18.ne', - '18.lt', - '18.gt', - '18.le', - '18.ge', + '20.eq', + '20.ne', + '20.lt', + '20.gt', + '20.le', + '20.ge', 'fast_string_eq', // other array methods - '20.get', - '20.set', - '20.get_unsafe', - '20.set_unsafe', - '20.get_with_check' /* used for `x := a[i] or {}` */, - '20.clone_static_to_depth', - '20.clone_to_depth', - '20.first', - '20.last', - '20.pointers' /* TODO: handle generic methods calling array primitives more precisely in pool_test.v */, - '20.reverse', - '20.repeat_to_depth', - '20.slice', - '20.slice2', - '59.get', - '59.set', - '65556.last', - '65556.pop', - '65556.push', - '65556.insert_many', - '65556.prepend_many', - '65556.reverse', - '65556.set', - '65556.set_unsafe', + '22.get', + '22.set', + '22.get_unsafe', + '22.set_unsafe', + '22.get_with_check' /* used for `x := a[i] or {}` */, + '22.clone_static_to_depth', + '22.clone_to_depth', + '22.first', + '22.last', + '22.pointers' /* TODO: handle generic methods calling array primitives more precisely in pool_test.v */, + '22.reverse', + '22.repeat_to_depth', + '22.slice', + '22.slice2', + '61.get', + '61.set', + '65558.last', + '65558.pop', + '65558.push', + '65558.insert_many', + '65558.prepend_many', + '65558.reverse', + '65558.set', + '65558.set_unsafe', // TODO: process the _vinit const initializations automatically too 'json.decode_string', 'json.decode_int', @@ -136,20 +136,20 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F '__new_array_with_default_noscan', '__new_array_with_array_default_noscan', 'new_array_from_c_array_noscan', - '20.clone_static_to_depth_noscan', - '20.clone_to_depth_noscan', - '20.reverse_noscan', - '20.repeat_to_depth_noscan', - '65556.pop_noscan', - '65556.push_noscan', - '65556.push_many_noscan', - '65556.insert_noscan', - '65556.insert_many_noscan', - '65556.prepend_noscan', - '65556.prepend_many_noscan', - '65556.reverse_noscan', - '65556.grow_cap_noscan', - '65556.grow_len_noscan', + '22.clone_static_to_depth_noscan', + '22.clone_to_depth_noscan', + '22.reverse_noscan', + '22.repeat_to_depth_noscan', + '65558.pop_noscan', + '65558.push_noscan', + '65558.push_many_noscan', + '65558.insert_noscan', + '65558.insert_many_noscan', + '65558.prepend_noscan', + '65558.prepend_many_noscan', + '65558.reverse_noscan', + '65558.grow_cap_noscan', + '65558.grow_len_noscan', ] } diff --git a/vlib/v/tests/integer_size_test.v b/vlib/v/tests/integer_size_test.v new file mode 100644 index 0000000000..6a019437bb --- /dev/null +++ b/vlib/v/tests/integer_size_test.v @@ -0,0 +1,36 @@ +fn f(u usize) usize +fn g(i isize) isize + +// TODO refactor once `str` method is implemented + +fn test_usize() { + mut u := usize(3) + u += u32(1) + // assert u == 4 + if u != 4 { + assert false + } + u = 4 + u++ + // assert u == 5 + if u != 5 { + assert false + } + // assert u.str() == '5' +} + +fn test_isize() { + mut i := isize(-3) + i -= int(1) + // assert i == -4 + if i != -4 { + assert false + } + i = -5 + i += 2 + // assert i == -3 + if i != -3 { + assert false + } + // assert i.str() == '-2' +}