diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 6e95f10ae4..3142edb79c 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1012,6 +1012,7 @@ pub mut: obj ScopeObject mod string name string + full_name string kind IdentKind info IdentInfo is_mut bool // if mut *token* is before name. Use `is_mut()` to lookup mut variable @@ -1019,6 +1020,19 @@ pub mut: concrete_types []Type } +// full_name returns the name of the ident, prefixed with the module name +pub fn (mut i Ident) full_name() string { + if i.full_name != '' { + return i.full_name + } + if i.name.contains('.') { + i.full_name = i.name + } else { + i.full_name = i.mod + '.' + i.name + } + return i.full_name +} + pub fn (i &Ident) is_auto_heap() bool { return match i.obj { Var { i.obj.is_auto_heap } diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index d65fbf633a..edf8ab4352 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -291,10 +291,7 @@ fn (mut c Checker) get_comptime_number_value(mut expr ast.Expr) ?i64 { } } if mut expr is ast.Ident { - has_expr_mod_in_name := expr.name.contains('.') - expr_name := if has_expr_mod_in_name { expr.name } else { '${expr.mod}.${expr.name}' } - - if mut obj := c.table.global_scope.find_const(expr_name) { + if mut obj := c.table.global_scope.find_const(expr.full_name()) { if obj.typ == 0 { obj.typ = c.expr(mut obj.expr) } diff --git a/vlib/v/gen/c/match.v b/vlib/v/gen/c/match.v index 4104d31a45..44fb27e737 100644 --- a/vlib/v/gen/c/match.v +++ b/vlib/v/gen/c/match.v @@ -403,7 +403,8 @@ fn (mut g Gen) should_check_low_bound_in_range_expr(expr ast.RangeExpr, node_con should_check_low_bound = false } } else if expr.low is ast.Ident { - if mut obj := g.table.global_scope.find_const(expr.low.name) { + mut elow := unsafe { expr.low } + if mut obj := g.table.global_scope.find_const(elow.full_name()) { if mut obj.expr is ast.IntegerLiteral { if obj.expr.val == '0' { should_check_low_bound = false diff --git a/vlib/v/gen/c/testdata/global_export_nix.c.must_have b/vlib/v/gen/c/testdata/global_export_nix.c.must_have index 4229067361..5fc07d9a9f 100644 --- a/vlib/v/gen/c/testdata/global_export_nix.c.must_have +++ b/vlib/v/gen/c/testdata/global_export_nix.c.must_have @@ -1 +1 @@ - string VV_EXPORTED_SYMBOL global_exported; // global4 \ No newline at end of file + string VV_EXPORTED_SYMBOL global_exported = _SLIT("barqux"); diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 1e324bb5c1..abeb598031 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -42,7 +42,7 @@ fn (mut p Parser) parse_array_type(expecting token.Kind, is_option bool) ast.Typ } } ast.Ident { - if mut const_field := p.table.global_scope.find_const('${p.mod}.${size_expr.name}') { + if mut const_field := p.table.global_scope.find_const(size_expr.full_name()) { if mut const_field.expr is ast.IntegerLiteral { fixed_size = const_field.expr.val.int() size_unresolved = false diff --git a/vlib/v/tests/enum_test.v b/vlib/v/tests/enum_test.v index 4da2cd5dd3..88c9306e36 100644 --- a/vlib/v/tests/enum_test.v +++ b/vlib/v/tests/enum_test.v @@ -172,3 +172,20 @@ fn test_enum_variant_and_method_name_clash() { x := Bar.baz println(x) } + +const base = 600000 + +enum EnumWithExpressions { + aa + bb = base + cc + dd = base + 10 + ee = base * 99 - 4 +} + +fn test_enum_variant_with_value_based_on_const_expression() { + assert int(EnumWithExpressions.bb) == base + assert int(EnumWithExpressions.cc) == base + 1 + assert int(EnumWithExpressions.dd) == 600010 + assert int(EnumWithExpressions.ee) == 59399996 +} diff --git a/vlib/v/transformer/transformer.v b/vlib/v/transformer/transformer.v index a77047a3c2..f67726a527 100644 --- a/vlib/v/transformer/transformer.v +++ b/vlib/v/transformer/transformer.v @@ -220,7 +220,13 @@ pub fn (mut t Transformer) stmt(mut node ast.Stmt) ast.Stmt { stmt = t.stmt(mut stmt) } } - ast.EnumDecl {} + ast.EnumDecl { + for mut field in node.fields { + if field.has_expr { + field.expr = t.expr(mut field.expr) + } + } + } ast.ExprStmt { // TODO: check if this can be handled in `t.expr` node.expr = match mut node.expr { @@ -719,7 +725,7 @@ fn (mut t Transformer) trans_const_value_to_literal(mut expr ast.Expr) { if _ := expr_.scope.find_var(expr_.name) { return } - if mut obj := t.table.global_scope.find_const(expr_.mod + '.' + expr_.name) { + if mut obj := t.table.global_scope.find_const(expr_.full_name()) { if mut obj.expr is ast.BoolLiteral { expr = obj.expr } else if mut obj.expr is ast.IntegerLiteral {