diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 1a78c776f7..086ac8a5ad 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -490,11 +490,13 @@ mut: pub struct MapInit { pub: - pos token.Position - keys []Expr - vals []Expr + pos token.Position + keys []Expr + vals []Expr mut: - typ table.Type + typ table.Type + key_type table.Type + value_type table.Type } // s[10..20] diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index ab16488fc9..50d8c8d413 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -875,6 +875,14 @@ pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type { } pub fn (c mut Checker) map_init(node mut ast.MapInit) table.Type { + // `x ;= map[string]string` - set in parser + if node.typ != 0 { + info := c.table.get_type_symbol(node.typ).map_info() + node.key_type = info.key_type + node.value_type = info.value_type + return node.typ + } + // `{'age': 20}` key0_type := c.expr(node.keys[0]) val0_type := c.expr(node.vals[0]) for i, key in node.keys { @@ -897,6 +905,8 @@ pub fn (c mut Checker) map_init(node mut ast.MapInit) table.Type { } map_type := table.new_type(c.table.find_or_register_map(key0_type, val0_type)) node.typ = map_type + node.key_type = key0_type + node.value_type = val0_type return map_type } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 41047fb078..034b858977 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -549,6 +549,27 @@ fn (g mut Gen) expr(node ast.Expr) { g.writeln('}') } } + ast.MapInit { + key_typ_sym := g.table.get_type_symbol(it.key_type) + value_typ_sym := g.table.get_type_symbol(it.value_type) + size := it.vals.len + if size > 0 { + g.write('new_map_init($size, sizeof($value_typ_sym.name), (${key_typ_sym.name}[$size]){') + for expr in it.keys { + g.expr(expr) + g.write(', ') + } + g.write('}, (${value_typ_sym.name}[$size]){') + for expr in it.vals { + g.expr(expr) + g.write(', ') + } + g.write('})') + } + else { + g.write('new_map(1, sizeof($value_typ_sym.name))') + } + } ast.MethodCallExpr { mut receiver_name := 'TODO' // TODO: there are still due to unchecked exprs (opt/some fn arg) diff --git a/vlib/v/gen/tests/4.c b/vlib/v/gen/tests/4.c index dea218e977..4fb0cc96af 100644 --- a/vlib/v/gen/tests/4.c +++ b/vlib/v/gen/tests/4.c @@ -52,6 +52,8 @@ int main() { }); Foo af_idx_el = array_get(arr_foo, 0); string foo_a = af_idx_el.a; + map_string_string m1 = new_map(1, sizeof(string)); + map_string_int m2 = new_map_init(2, sizeof(int), (string[2]){tos3("v"), tos3("lang"), }, (int[2]){1, 2, }); return 0; } diff --git a/vlib/v/gen/tests/4.vv b/vlib/v/gen/tests/4.vv index b761c733ad..0ef5a679af 100644 --- a/vlib/v/gen/tests/4.vv +++ b/vlib/v/gen/tests/4.vv @@ -31,14 +31,16 @@ fn main() { mut f := [testa(),2,3,4] mut g := [testb(1),'hello'] - m1, m2 := mr_test() + mr1, mr2 := mr_test() //mut arr_foo := []Foo arr_foo := [a] //arr_foo << a // TODO af_idx_el := arr_foo[0] foo_a := af_idx_el.a - + + mut m1 := map[string]string + mut m2 := {'v': 1, 'lang': 2} } fn mr_test() (int, string) { diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index fb5c49ced3..aaecf35fc4 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -530,7 +530,7 @@ pub fn (p mut Parser) name_expr() ast.Expr { // `map[string]int` initialization if p.tok.lit == 'map' && p.peek_tok.kind == .lsbr { map_type := p.parse_map_type() - return ast.Type{ + return ast.MapInit { typ: map_type } }