From 06d1422a059d078e16cd3f2e1ac6ba3692754f2c Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Fri, 30 Jul 2021 17:22:27 +0300 Subject: [PATCH] ast,checker,cgen: support simple `const x = u16(0x53)` without using _vinit() --- vlib/v/ast/comptime_const_values.v | 262 +++++++++++++++++---------- vlib/v/checker/comptime_const_eval.v | 27 ++- vlib/v/gen/c/cgen.v | 42 +++-- 3 files changed, 223 insertions(+), 108 deletions(-) diff --git a/vlib/v/ast/comptime_const_values.v b/vlib/v/ast/comptime_const_values.v index 25b07bd4ce..6f9ef6a1c9 100644 --- a/vlib/v/ast/comptime_const_values.v +++ b/vlib/v/ast/comptime_const_values.v @@ -1,29 +1,77 @@ module ast -pub type ComptTimeConstValue = EmptyExpr | byte | f64 | i64 | rune | string | u64 +pub type ComptTimeConstValue = EmptyExpr | byte | f32 | f64 | i16 | i64 | i8 | int | rune | + string | u16 | u32 | u64 pub fn empty_comptime_const_expr() ComptTimeConstValue { return EmptyExpr{} } +pub fn (val ComptTimeConstValue) i8() ?i8 { + x := val.i64() ? + if x > -129 && x < 128 { + return i8(x) + } + return none +} + +pub fn (val ComptTimeConstValue) i16() ?i16 { + x := val.i64() ? + if x > -32769 && x < 32768 { + return i16(x) + } + return none +} + +pub fn (val ComptTimeConstValue) int() ?int { + x := val.i64() ? + if x > -2147483649 && x < 2147483648 { + return int(x) + } + return none +} + pub fn (val ComptTimeConstValue) i64() ?i64 { match val { - byte { + i8 { + return i64(val) + } + i16 { + return i64(val) + } + int { return i64(val) } i64 { return i64(val) } - f64 { - if -9223372036854775808.0 <= val && val <= 9223372036854775807.0 { - return i64(val) - } + // + byte { + return i64(val) + } + u16 { + return i64(val) + } + u32 { + return i64(val) } u64 { if val <= 9223372036854775807 { return i64(val) } } + // + f32 { + if -9223372036854775808.0 <= val && val <= 9223372036854775807.0 { + return i64(val) + } + } + f64 { + if -9223372036854775808.0 <= val && val <= 9223372036854775807.0 { + return i64(val) + } + } + // string { return val.i64() } @@ -35,94 +83,68 @@ pub fn (val ComptTimeConstValue) i64() ?i64 { return none } -pub fn (val ComptTimeConstValue) int() ?int { - match val { - u64 { - if val <= 2147483647 { - return int(val) - } - } - f64 { - if -2147483648.0 <= val && val <= 2147483647.0 { - return int(val) - } - } - i64 { - if -2147483648 <= val && val <= 2147483647 { - return int(val) - } - } - byte { - return int(val) - } - string { - return val.int() - } - rune, EmptyExpr {} +pub fn (val ComptTimeConstValue) byte() ?byte { + x := val.u64() ? + if x < 256 { + return byte(x) } return none } -pub fn (val ComptTimeConstValue) string() ?string { - match val { - u64 { - return val.str() - } - i64 { - return val.str() - } - f64 { - return val.str() - } - byte { - return val.str() - } - rune { - return val.str() - } - string { - return val - } - EmptyExpr {} +pub fn (val ComptTimeConstValue) u16() ?u16 { + x := val.u64() ? + if x < 65536 { + return u16(x) } return none } -pub fn (val ComptTimeConstValue) f64() ?f64 { - match val { - i64 { - return f64(val) - } - u64 { - return f64(val) - } - byte { - return f64(val) - } - f64 { - return val - } - string { - return val.f64() - } - rune {} - EmptyExpr {} +pub fn (val ComptTimeConstValue) u32() ?u32 { + x := val.u64() ? + if x < 4294967296 { + return u32(x) } return none } pub fn (val ComptTimeConstValue) u64() ?u64 { match val { + i8 { + if val >= 0 { + return u64(val) + } + } + i16 { + if val >= 0 { + return u64(val) + } + } + int { + if val >= 0 { + return u64(val) + } + } i64 { if val >= 0 { return u64(val) } } + byte { + return u64(val) + } + u16 { + return u64(val) + } + u32 { + return u64(val) + } u64 { return val } - byte { - return u64(val) + f32 { + if val <= 18446744073709551615.0 { + return u64(val) + } } f64 { if val <= 18446744073709551615.0 { @@ -138,37 +160,89 @@ pub fn (val ComptTimeConstValue) u64() ?u64 { return none } -pub fn (val ComptTimeConstValue) byte() ?byte { +pub fn (val ComptTimeConstValue) f32() ?f32 { + x := val.f64() ? + return f32(x) +} + +pub fn (val ComptTimeConstValue) f64() ?f64 { match val { - byte { - return val + i8 { + return f64(val) } - u64 { - if val <= 255 { - return byte(val) - } + i16 { + return f64(val) } - f64 { - if 0 <= val && val <= 255 { - return byte(val) - } + int { + return f64(val) } i64 { - if 0 <= val && val <= 255 { - return byte(val) - } + return f64(val) + } + byte { + return f64(val) + } + u16 { + return f64(val) + } + u32 { + return f64(val) + } + u64 { + return f64(val) + } + f32 { + return f64(val) + } + f64 { + return val } string { - x := val.int() - if 0 <= x && x <= 255 { - return byte(x) - } + return val.f64() + } + rune {} + EmptyExpr {} + } + return none +} + +pub fn (val ComptTimeConstValue) string() ?string { + match val { + i8 { + return val.str() + } + i16 { + return val.str() + } + int { + return val.str() + } + i64 { + return val.str() + } + byte { + return val.str() + } + u16 { + return val.str() + } + u32 { + return val.str() + } + u64 { + return val.str() + } + f32 { + return val.str() + } + f64 { + return val.str() } rune { - x := u32(val) - if 0 <= x && x <= 255 { - return byte(x) - } + return val.str() + } + string { + return val } EmptyExpr {} } diff --git a/vlib/v/checker/comptime_const_eval.v b/vlib/v/checker/comptime_const_eval.v index 0d20d89dbc..5bb0781558 100644 --- a/vlib/v/checker/comptime_const_eval.v +++ b/vlib/v/checker/comptime_const_eval.v @@ -33,15 +33,38 @@ fn eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.ComptTimeConstValue } ast.CastExpr { cast_expr_value := eval_comptime_const_expr(expr.expr, nlevel + 1) or { return none } + if expr.typ == ast.i8_type { + return cast_expr_value.i8() or { return none } + } + if expr.typ == ast.i16_type { + return cast_expr_value.i16() or { return none } + } + if expr.typ == ast.int_type { + return cast_expr_value.int() or { return none } + } + if expr.typ == ast.i64_type { + return cast_expr_value.i64() or { return none } + } + // if expr.typ == ast.byte_type { return cast_expr_value.byte() or { return none } } - if expr.typ == ast.int_type { - return i64(cast_expr_value.int() or { return none }) + if expr.typ == ast.u16_type { + return cast_expr_value.u16() or { return none } + } + if expr.typ == ast.u32_type { + return cast_expr_value.u32() or { return none } } if expr.typ == ast.u64_type { return cast_expr_value.u64() or { return none } } + // + if expr.typ == ast.f32_type { + return cast_expr_value.f32() or { return none } + } + if expr.typ == ast.f64_type { + return cast_expr_value.f64() or { return none } + } } ast.InfixExpr { left := eval_comptime_const_expr(expr.left, nlevel + 1) ? diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 29cbd44296..39ac7e667b 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5018,20 +5018,14 @@ fn (mut g Gen) const_decl_precomputed(mod string, name string, ct_value ast.Comp eprintln('> styp: $styp | cname: $cname | ct_value: $ct_value | $ct_value.type_name()') } match ct_value { - byte { + i8 { g.const_decl_write_precomputed(styp, cname, ct_value.str()) } - rune { - rune_code := u32(ct_value) - if rune_code <= 255 { - if rune_code in [`"`, `\\`, `\'`] { - return false - } - escval := util.smart_quote(byte(rune_code).ascii_str(), false) - g.const_decl_write_precomputed(styp, cname, "'$escval'") - } else { - g.const_decl_write_precomputed(styp, cname, u32(ct_value).str()) - } + i16 { + g.const_decl_write_precomputed(styp, cname, ct_value.str()) + } + int { + g.const_decl_write_precomputed(styp, cname, ct_value.str()) } i64 { if typ == ast.int_type { @@ -5049,12 +5043,36 @@ fn (mut g Gen) const_decl_precomputed(mod string, name string, ct_value ast.Comp g.const_decl_write_precomputed(styp, cname, ct_value.str()) } } + byte { + g.const_decl_write_precomputed(styp, cname, ct_value.str()) + } + u16 { + g.const_decl_write_precomputed(styp, cname, ct_value.str()) + } + u32 { + g.const_decl_write_precomputed(styp, cname, ct_value.str()) + } u64 { g.const_decl_write_precomputed(styp, cname, ct_value.str() + 'U') } + f32 { + g.const_decl_write_precomputed(styp, cname, ct_value.str()) + } f64 { g.const_decl_write_precomputed(styp, cname, ct_value.str()) } + rune { + rune_code := u32(ct_value) + if rune_code <= 255 { + if rune_code in [`"`, `\\`, `\'`] { + return false + } + escval := util.smart_quote(byte(rune_code).ascii_str(), false) + g.const_decl_write_precomputed(styp, cname, "'$escval'") + } else { + g.const_decl_write_precomputed(styp, cname, u32(ct_value).str()) + } + } string { escaped_val := util.smart_quote(ct_value, false) // g.const_decl_write_precomputed(styp, cname, '_SLIT("$escaped_val")')