ast,checker,cgen: support simple `const x = u16(0x53)` without using _vinit()
							parent
							
								
									afb7168a64
								
							
						
					
					
						commit
						06d1422a05
					
				| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
		//
 | 
			
		||||
		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,95 +83,69 @@ 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 {
 | 
			
		||||
		f32 {
 | 
			
		||||
			if val <= 18446744073709551615.0 {
 | 
			
		||||
				return u64(val)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		f64 {
 | 
			
		||||
			if val <= 18446744073709551615.0 {
 | 
			
		||||
				return u64(val)
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		f64 {
 | 
			
		||||
			if 0 <= val && val <= 255 {
 | 
			
		||||
				return byte(val)
 | 
			
		||||
		i16 {
 | 
			
		||||
			return f64(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 {}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) ?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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")')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue