ast,checker,cgen: support simple `const x = u16(0x53)` without using _vinit()

pull/11006/head
Delyan Angelov 2021-07-30 17:22:27 +03:00
parent afb7168a64
commit 06d1422a05
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
3 changed files with 223 additions and 108 deletions

View File

@ -1,29 +1,77 @@
module ast 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 { pub fn empty_comptime_const_expr() ComptTimeConstValue {
return EmptyExpr{} 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 { pub fn (val ComptTimeConstValue) i64() ?i64 {
match val { match val {
byte { i8 {
return i64(val)
}
i16 {
return i64(val)
}
int {
return i64(val) return i64(val)
} }
i64 { i64 {
return i64(val) return i64(val)
} }
f64 { //
if -9223372036854775808.0 <= val && val <= 9223372036854775807.0 { byte {
return i64(val) return i64(val)
} }
u16 {
return i64(val)
}
u32 {
return i64(val)
} }
u64 { u64 {
if val <= 9223372036854775807 { if val <= 9223372036854775807 {
return i64(val) 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 { string {
return val.i64() return val.i64()
} }
@ -35,94 +83,68 @@ pub fn (val ComptTimeConstValue) i64() ?i64 {
return none return none
} }
pub fn (val ComptTimeConstValue) int() ?int { pub fn (val ComptTimeConstValue) byte() ?byte {
match val { x := val.u64() ?
u64 { if x < 256 {
if val <= 2147483647 { return byte(x)
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 {}
} }
return none return none
} }
pub fn (val ComptTimeConstValue) string() ?string { pub fn (val ComptTimeConstValue) u16() ?u16 {
match val { x := val.u64() ?
u64 { if x < 65536 {
return val.str() return u16(x)
}
i64 {
return val.str()
}
f64 {
return val.str()
}
byte {
return val.str()
}
rune {
return val.str()
}
string {
return val
}
EmptyExpr {}
} }
return none return none
} }
pub fn (val ComptTimeConstValue) f64() ?f64 { pub fn (val ComptTimeConstValue) u32() ?u32 {
match val { x := val.u64() ?
i64 { if x < 4294967296 {
return f64(val) return u32(x)
}
u64 {
return f64(val)
}
byte {
return f64(val)
}
f64 {
return val
}
string {
return val.f64()
}
rune {}
EmptyExpr {}
} }
return none return none
} }
pub fn (val ComptTimeConstValue) u64() ?u64 { pub fn (val ComptTimeConstValue) u64() ?u64 {
match val { match val {
i8 {
if val >= 0 {
return u64(val)
}
}
i16 {
if val >= 0 {
return u64(val)
}
}
int {
if val >= 0 {
return u64(val)
}
}
i64 { i64 {
if val >= 0 { if val >= 0 {
return u64(val) return u64(val)
} }
} }
byte {
return u64(val)
}
u16 {
return u64(val)
}
u32 {
return u64(val)
}
u64 { u64 {
return val return val
} }
byte { f32 {
return u64(val) if val <= 18446744073709551615.0 {
return u64(val)
}
} }
f64 { f64 {
if val <= 18446744073709551615.0 { if val <= 18446744073709551615.0 {
@ -138,37 +160,89 @@ pub fn (val ComptTimeConstValue) u64() ?u64 {
return none 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 { match val {
byte { i8 {
return val return f64(val)
} }
u64 { i16 {
if val <= 255 { return f64(val)
return byte(val)
}
} }
f64 { int {
if 0 <= val && val <= 255 { return f64(val)
return byte(val)
}
} }
i64 { i64 {
if 0 <= val && val <= 255 { return f64(val)
return byte(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 { string {
x := val.int() return val.f64()
if 0 <= x && x <= 255 { }
return byte(x) 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 { rune {
x := u32(val) return val.str()
if 0 <= x && x <= 255 { }
return byte(x) string {
} return val
} }
EmptyExpr {} EmptyExpr {}
} }

View File

@ -33,15 +33,38 @@ fn eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.ComptTimeConstValue
} }
ast.CastExpr { ast.CastExpr {
cast_expr_value := eval_comptime_const_expr(expr.expr, nlevel + 1) or { return none } 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 { if expr.typ == ast.byte_type {
return cast_expr_value.byte() or { return none } return cast_expr_value.byte() or { return none }
} }
if expr.typ == ast.int_type { if expr.typ == ast.u16_type {
return i64(cast_expr_value.int() or { return none }) 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 { if expr.typ == ast.u64_type {
return cast_expr_value.u64() or { return none } 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 { ast.InfixExpr {
left := eval_comptime_const_expr(expr.left, nlevel + 1) ? left := eval_comptime_const_expr(expr.left, nlevel + 1) ?

View File

@ -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()') eprintln('> styp: $styp | cname: $cname | ct_value: $ct_value | $ct_value.type_name()')
} }
match ct_value { match ct_value {
byte { i8 {
g.const_decl_write_precomputed(styp, cname, ct_value.str()) g.const_decl_write_precomputed(styp, cname, ct_value.str())
} }
rune { i16 {
rune_code := u32(ct_value) g.const_decl_write_precomputed(styp, cname, ct_value.str())
if rune_code <= 255 { }
if rune_code in [`"`, `\\`, `\'`] { int {
return false g.const_decl_write_precomputed(styp, cname, ct_value.str())
}
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())
}
} }
i64 { i64 {
if typ == ast.int_type { 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()) 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 { u64 {
g.const_decl_write_precomputed(styp, cname, ct_value.str() + 'U') g.const_decl_write_precomputed(styp, cname, ct_value.str() + 'U')
} }
f32 {
g.const_decl_write_precomputed(styp, cname, ct_value.str())
}
f64 { f64 {
g.const_decl_write_precomputed(styp, cname, ct_value.str()) 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 { string {
escaped_val := util.smart_quote(ct_value, false) escaped_val := util.smart_quote(ct_value, false)
// g.const_decl_write_precomputed(styp, cname, '_SLIT("$escaped_val")') // g.const_decl_write_precomputed(styp, cname, '_SLIT("$escaped_val")')