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 {
|
ast.Ident {
|
||||||
if init_expr.obj is ast.ConstField {
|
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
|
fixed_size = cint
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -3080,17 +3080,43 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
||||||
return array_init.typ
|
return array_init.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
fn const_int_value(cfield ast.ConstField) ?int {
|
fn eval_int_expr(expr ast.Expr, nlevel int) ?int {
|
||||||
if cint := is_const_integer(cfield) {
|
if nlevel > 100 {
|
||||||
return cint.val.int()
|
// protect against a too deep comptime eval recursion:
|
||||||
|
return none
|
||||||
}
|
}
|
||||||
return none
|
match expr {
|
||||||
}
|
ast.IntegerLiteral {
|
||||||
|
return expr.val.int()
|
||||||
fn is_const_integer(cfield ast.ConstField) ?ast.IntegerLiteral {
|
}
|
||||||
match cfield.expr {
|
ast.InfixExpr {
|
||||||
ast.IntegerLiteral { return cfield.expr }
|
left := eval_int_expr(expr.left, nlevel + 1) ?
|
||||||
else {}
|
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
|
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