From d15d13674cc32e31c126cf21f3b9f87d32775d47 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Fri, 1 Jan 2021 13:38:11 +0000 Subject: [PATCH] parser: parse non-identifier expressions for sizeof too (#7781) --- vlib/v/parser/pratt.v | 8 +++++--- vlib/v/tests/sizeof_test.v | 13 ++++++++++++- vlib/v/token/token.v | 11 +++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index 84aac03b51..c19ab55133 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -142,9 +142,11 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr { pos := p.tok.position() p.next() // sizeof p.check(.lpar) - is_known_var := p.mark_var_as_used(p.tok.lit) - if is_known_var { - expr := p.parse_ident(table.Language.v) + if !p.tok.can_start_type(table.builtin_type_names) { + if p.tok.kind == .name { + p.mark_var_as_used(p.tok.lit) + } + expr := p.expr(0) node = ast.SizeOf{ is_type: false expr: expr diff --git a/vlib/v/tests/sizeof_test.v b/vlib/v/tests/sizeof_test.v index bea1d39360..372f13250b 100644 --- a/vlib/v/tests/sizeof_test.v +++ b/vlib/v/tests/sizeof_test.v @@ -1,6 +1,17 @@ import math -fn test_sizeof() { +struct S1 { + i voidptr +} + +fn test_math_sizeof() { r := math.f32_from_bits(sizeof(int)) assert r > 5.6e-45 && r < 5.7e-45 } + +fn test_sizeof() { + // depends on compiler + assert sizeof(`€`) in [u32(2), 4] + // depends on -m32/64 + assert sizeof(S1) in [u32(4), 8] +} diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index 0646ce1e38..8bf8f4fadc 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -431,3 +431,14 @@ pub fn (kind Kind) is_infix() bool { return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in, /* */.key_as, .ge, .le, .logical_or, .xor, .not_in, .key_is, .not_is, /* */.and, .dot, .pipe, .amp, .left_shift, .right_shift, .arrow] } + +// Pass table.builtin_type_names +// Note: can't import table here due to circular module dependency +pub fn (tok &Token) can_start_type(builtin_type_names []string) bool { + match tok.kind { + .name { return tok.lit[0].is_capital() || tok.lit in builtin_type_names } + .amp, .lsbr, .question { return true } + else {} + } + return false +}