checker: eval `const a = 1024 * 1024` and other simple integer expressions at compile time
parent
f1469a8761
commit
26cfd0eda9
|
@ -3056,7 +3056,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
|||
}
|
||||
ast.Ident {
|
||||
if init_expr.obj is ast.ConstField {
|
||||
if cint := const_int_value(init_expr.obj) {
|
||||
if cint := eval_int_expr(init_expr.obj.expr, 0) {
|
||||
fixed_size = cint
|
||||
}
|
||||
} else {
|
||||
|
@ -3080,17 +3080,43 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
|||
return array_init.typ
|
||||
}
|
||||
|
||||
fn const_int_value(cfield ast.ConstField) ?int {
|
||||
if cint := is_const_integer(cfield) {
|
||||
return cint.val.int()
|
||||
fn eval_int_expr(expr ast.Expr, nlevel int) ?int {
|
||||
if nlevel > 100 {
|
||||
// protect against a too deep comptime eval recursion:
|
||||
return none
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
fn is_const_integer(cfield ast.ConstField) ?ast.IntegerLiteral {
|
||||
match cfield.expr {
|
||||
ast.IntegerLiteral { return cfield.expr }
|
||||
else {}
|
||||
match expr {
|
||||
ast.IntegerLiteral {
|
||||
return expr.val.int()
|
||||
}
|
||||
ast.InfixExpr {
|
||||
left := eval_int_expr(expr.left, nlevel + 1) ?
|
||||
right := eval_int_expr(expr.right, nlevel + 1) ?
|
||||
match expr.op {
|
||||
.plus { return left + right }
|
||||
.minus { return left - right }
|
||||
.mul { return left * right }
|
||||
.div { return left / right }
|
||||
.mod { return left % right }
|
||||
.xor { return left ^ right }
|
||||
.pipe { return left | right }
|
||||
.amp { return left & right }
|
||||
.left_shift { return left << right }
|
||||
.right_shift { return left >> right }
|
||||
else { return none }
|
||||
}
|
||||
}
|
||||
ast.Ident {
|
||||
if expr.obj is ast.ConstField {
|
||||
// an int constant?
|
||||
cint := eval_int_expr(expr.obj.expr, nlevel + 1) ?
|
||||
return cint
|
||||
}
|
||||
}
|
||||
else {
|
||||
// dump(expr)
|
||||
return none
|
||||
}
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
const kb = 1024
|
||||
|
||||
const buf_siz = 1024 * kb
|
||||
|
||||
fn test_consts() {
|
||||
assert kb == 1024
|
||||
assert buf_siz == 1024 * kb
|
||||
assert buf_siz == 1048576
|
||||
println(buf_siz)
|
||||
}
|
||||
|
||||
fn test_fixed_size_arrays_can_use_known_comptime_consts_as_their_size() {
|
||||
buf := [buf_siz]byte{}
|
||||
println(buf.len)
|
||||
assert buf.len == 1048576
|
||||
}
|
||||
|
||||
// zbuf := [1024*1024]byte{}
|
||||
// error: fixed size cannot be zero or negative
|
||||
|
||||
// buf := [1048576]byte{}
|
Loading…
Reference in New Issue