`map := { 'foo': 'bar' }` syntax

pull/1454/head
Alexander Medvednikov 2019-08-03 09:44:08 +02:00
parent bfddb9a80f
commit a5f5b52204
4 changed files with 71 additions and 2 deletions

View File

@ -2241,6 +2241,10 @@ fn (p mut Parser) factor() string {
// everything should do next() // everything should do next()
return p.array_init() return p.array_init()
case Token.lcbr: case Token.lcbr:
// `m := { 'one': 1 }`
if p.peek() == .str {
return p.map_init()
}
// { user | name :'new name' } // { user | name :'new name' }
return p.assoc() return p.assoc()
case Token.key_if: case Token.key_if:
@ -2415,7 +2419,50 @@ fn (p mut Parser) string_expr() {
} }
// m := map[string]int{} // m := map[string]int{}
// m := { 'one': 1 }
fn (p mut Parser) map_init() string { 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.next()
p.check(.lsbr) p.check(.lsbr)
key_type := p.check_name() 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.error('only string key maps allowed for now')
} }
p.check(.rsbr) p.check(.rsbr)
val_type := p.check_name() val_type = p.check_name()
if !p.table.known_type(val_type) { if !p.table.known_type(val_type) {
p.error('map init unknown type "$val_type"') p.error('map init unknown type "$val_type"')
} }
@ -2435,7 +2482,7 @@ fn (p mut Parser) map_init() string {
return typ return typ
} }
// [1,2,3] // `nums := [1, 2, 3]`
fn (p mut Parser) array_init() string { fn (p mut Parser) array_init() string {
p.is_alloc = true p.is_alloc = true
p.check(.lsbr) p.check(.lsbr)

View File

@ -501,6 +501,9 @@ fn (p mut Parser) _check_types(got, expected string, throw bool) bool {
if got=='int' && expected=='byte*' { if got=='int' && expected=='byte*' {
return true return true
} }
//if got=='int' && expected=='voidptr*' {
//return true
//}
// byteptr += int // byteptr += int
if got=='int' && expected=='byteptr' { if got=='int' && expected=='byteptr' {
return true return true

View File

@ -29,6 +29,18 @@ fn new_map(cap, elm_size int) map {
return res 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 { fn new_node(key string, val voidptr, element_size int) *Node {
new_e := &Node { new_e := &Node {
key: key key: key

View File

@ -60,6 +60,13 @@ fn test_map() {
assert a.m['two'] == 2 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() { fn test_string_map() {
//m := map[string]Fn //m := map[string]Fn
} }