diff --git a/compiler/parser.v b/compiler/parser.v index 1e9cb87bf7..6b6f19b0be 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -2241,6 +2241,10 @@ fn (p mut Parser) factor() string { // everything should do next() return p.array_init() case Token.lcbr: + // `m := { 'one': 1 }` + if p.peek() == .str { +return p.map_init() +} // { user | name :'new name' } return p.assoc() case Token.key_if: @@ -2415,7 +2419,50 @@ fn (p mut Parser) string_expr() { } // m := map[string]int{} +// m := { 'one': 1 } fn (p mut Parser) map_init() string { + // m := { 'one': 1, 'two': 2 } + mut keys := []string // ['one', 'two'] + mut keys_gen := '' // ' (string[]){tos2("one"), tos2("two")} + mut vals := []string // [1, 2] + mut vals_gen := '' + mut val_type := '' // 'int' + if p.tok == .lcbr { + p.check(.lcbr) + mut i := 0 + for { + key := p.lit + keys << key + keys_gen += 'tos2("$key"), ' + p.check(.str) + p.check(.colon) + p.cgen.start_tmp() + t := p.bool_expression() + if i == 0 { + val_type = t + } + i++ + if val_type != t { + if !p.check_types_no_throw(val_type, t) { + p.error('bad map element type `$val_type` instead of `$t`') + } + } + val_expr := p.cgen.end_tmp() + vals << val_expr + vals_gen += '$val_expr, ' + if p.tok == .rcbr { + p.check(.rcbr) + break + } + if p.tok == .comma { + p.check(.comma) + } + } + p.gen('new_map_init($keys.len, sizeof($val_type), ' + + '(string[]){ $keys_gen }, ($val_type []){ $vals_gen } )') + typ := 'map_$val_type' + return typ + } p.next() p.check(.lsbr) key_type := p.check_name() @@ -2423,7 +2470,7 @@ fn (p mut Parser) map_init() string { p.error('only string key maps allowed for now') } p.check(.rsbr) - val_type := p.check_name() + val_type = p.check_name() if !p.table.known_type(val_type) { p.error('map init unknown type "$val_type"') } @@ -2435,7 +2482,7 @@ fn (p mut Parser) map_init() string { return typ } -// [1,2,3] +// `nums := [1, 2, 3]` fn (p mut Parser) array_init() string { p.is_alloc = true p.check(.lsbr) diff --git a/compiler/table.v b/compiler/table.v index 8e6bb2aa7d..df389c09cd 100644 --- a/compiler/table.v +++ b/compiler/table.v @@ -501,6 +501,9 @@ fn (p mut Parser) _check_types(got, expected string, throw bool) bool { if got=='int' && expected=='byte*' { return true } + //if got=='int' && expected=='voidptr*' { + //return true + //} // byteptr += int if got=='int' && expected=='byteptr' { return true diff --git a/vlib/builtin/map.v b/vlib/builtin/map.v index c34b9d2bb9..7a401bf8ee 100644 --- a/vlib/builtin/map.v +++ b/vlib/builtin/map.v @@ -29,6 +29,18 @@ fn new_map(cap, elm_size int) map { return res } +// `m := { 'one': 1, 'two': 2 }` +fn new_map_init(cap, elm_size int, keys *string, vals voidptr) map { + mut res := map { + element_size: elm_size + root: 0 + } + for i in 0 .. cap { + res._set(keys[i], vals + i * elm_size) + } + return res +} + fn new_node(key string, val voidptr, element_size int) *Node { new_e := &Node { key: key diff --git a/vlib/builtin/map_test.v b/vlib/builtin/map_test.v index 508c0b71a6..c973f91401 100644 --- a/vlib/builtin/map_test.v +++ b/vlib/builtin/map_test.v @@ -60,6 +60,13 @@ fn test_map() { assert a.m['two'] == 2 } +fn test_map_init() { + m := { 'one': 1, 'two': 2, 'jooo': 'sdf' } + assert m['one'] == 1 + assert m['two'] == 2 + assert m['three'] == 0 +} + fn test_string_map() { //m := map[string]Fn }