1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

for key, val in map syntax

This commit is contained in:
Alexander Medvednikov 2019-07-12 07:23:16 +02:00
parent e246833daa
commit 56b7c9e35f
2 changed files with 35 additions and 33 deletions

View File

@ -14,13 +14,13 @@ const (
enum BuildMode { enum BuildMode {
// `v program.v' // `v program.v'
// Build user code only, and add pre-compiled vlib (`cc program.o builtin.o os.o...`) // Build user code only, and add pre-compiled vlib (`cc program.o builtin.o os.o...`)
default_mode default_mode
// `v -embed_vlib program.v` // `v -embed_vlib program.v`
// vlib + user code in one file (slower compilation, but easier when working on vlib and cross-compiling) // vlib + user code in one file (slower compilation, but easier when working on vlib and cross-compiling)
embed_vlib embed_vlib
// `v -lib ~/v/os` // `v -lib ~/v/os`
// build any module (generate os.o + os.vh) // build any module (generate os.o + os.vh)
build //TODO a better name would be smth like `.build_module` I think build //TODO a better name would be smth like `.build_module` I think
} }
fn vtmp_path() string { fn vtmp_path() string {

View File

@ -2806,10 +2806,7 @@ fn (p mut Parser) for_st() {
p.fgen(' ') p.fgen(' ')
p.for_expr_cnt++ p.for_expr_cnt++
next_tok := p.peek() next_tok := p.peek()
debug := p.scanner.file_path.contains('r_draw') //debug := p.scanner.file_path.contains('r_draw')
if debug {
println('\n\nF.ortok {')
}
p.cur_fn.open_scope() p.cur_fn.open_scope()
if p.tok == .lcbr { if p.tok == .lcbr {
// Infinite loop // Infinite loop
@ -2820,9 +2817,6 @@ fn (p mut Parser) for_st() {
} }
// for i := 0; i < 10; i++ { // for i := 0; i < 10; i++ {
else if next_tok == .decl_assign || next_tok == .assign || p.tok == .semicolon { else if next_tok == .decl_assign || next_tok == .assign || p.tok == .semicolon {
if debug {
println('for 1')
}
p.genln('for (') p.genln('for (')
if next_tok == .decl_assign { if next_tok == .decl_assign {
p.var_decl() p.var_decl()
@ -2832,27 +2826,18 @@ fn (p mut Parser) for_st() {
// Allow `for i = 0; i < ...` // Allow `for i = 0; i < ...`
p.statement(false) p.statement(false)
} }
if debug {
println('for 2')
}
p.check(.semicolon) p.check(.semicolon)
p.gen(' ; ') p.gen(' ; ')
p.fgen(' ') p.fgen(' ')
if p.tok != .semicolon { if p.tok != .semicolon {
p.bool_expression() p.bool_expression()
} }
if debug {
println('for 3')
}
p.check(.semicolon) p.check(.semicolon)
p.gen(' ; ') p.gen(' ; ')
p.fgen(' ') p.fgen(' ')
if p.tok != .lcbr { if p.tok != .lcbr {
p.statement(false) p.statement(false)
} }
if debug {
println('for 4')
}
p.genln(') { ') p.genln(') { ')
} }
// for i, val in array // for i, val in array
@ -2871,27 +2856,47 @@ fn (p mut Parser) for_st() {
tmp := p.get_tmp() tmp := p.get_tmp()
p.cgen.start_tmp() p.cgen.start_tmp()
typ := p.bool_expression() typ := p.bool_expression()
is_arr := typ.starts_with('array_')
is_map := typ.starts_with('map_')
is_str := typ == 'string'
if !is_arr && !is_str && !is_map {
p.error('cannot range over type `$typ`')
}
expr := p.cgen.end_tmp() expr := p.cgen.end_tmp()
p.genln('$typ $tmp = $expr ;') p.genln('$typ $tmp = $expr ;')
var_typ := typ.right(6) pad := if is_arr { 6 } else { 4 }
var_typ := typ.right(pad)
// typ = strings.Replace(typ, "_ptr", "*", -1) // typ = strings.Replace(typ, "_ptr", "*", -1)
// Register temp var // Register temp var
val_var := Var { val_var := Var {
name: val name: val
typ: var_typ typ: var_typ
// parent_fn: p.cur_fn
ptr: typ.contains('*') ptr: typ.contains('*')
} }
p.register_var(val_var) p.register_var(val_var)
i_var := Var { if is_arr || is_str {
name: i i_var := Var {
typ: 'int' name: i
// parent_fn: p.cur_fn typ: 'int'
is_mut: true // parent_fn: p.cur_fn
is_mut: true
}
p.register_var(i_var)
p.genln(';\nfor (int $i = 0; $i < $tmp .len; $i ++) {')
p.genln('$var_typ $val = (($var_typ *) $tmp . data)[$i];')
} }
p.register_var(i_var) else if is_map {
p.genln(';\nfor (int $i = 0; $i < $tmp .len; $i ++) {') i_var := Var {
p.genln('$var_typ $val = (($var_typ *) $tmp . data)[$i];') name: i
typ: 'string'
is_mut: true
}
p.register_var(i_var)
p.genln('for (int l = 0; l < $tmp . entries.len; l++) {')
p.genln('Entry entry = *((Entry*) (array__get($tmp .entries, l)));')
p.genln('string $i = entry.key;')
p.genln('$var_typ $val; map_get($tmp, $i, & $val);')
}
} }
// `for val in vals` // `for val in vals`
else if p.peek() == .key_in { else if p.peek() == .key_in {
@ -2903,8 +2908,6 @@ fn (p mut Parser) for_st() {
p.cgen.start_tmp() p.cgen.start_tmp()
typ := p.bool_expression() typ := p.bool_expression()
expr := p.cgen.end_tmp() expr := p.cgen.end_tmp()
// println('if in:')
// println(p.strtok())
is_range := p.tok == .dotdot is_range := p.tok == .dotdot
mut range_end := '' mut range_end := ''
if is_range { if is_range {
@ -2916,9 +2919,8 @@ fn (p mut Parser) for_st() {
} }
is_arr := typ.contains('array') is_arr := typ.contains('array')
is_str := typ == 'string' is_str := typ == 'string'
// ////if !typ.contains('array') && typ != 'string' {
if !is_arr && !is_str && !is_range { if !is_arr && !is_str && !is_range {
p.error('`for in` requires an array or a string but got `$typ`') p.error('cannot range over type `$typ`')
} }
p.genln('$typ $tmp = $expr;') p.genln('$typ $tmp = $expr;')
// TODO var_type := if... // TODO var_type := if...