diff --git a/vlib/compiler/for.v b/vlib/compiler/for.v index 24e807e120..fc9a1f0633 100644 --- a/vlib/compiler/for.v +++ b/vlib/compiler/for.v @@ -141,18 +141,19 @@ fn (p mut Parser) for_st() { if p.pref.x64 { label = p.x64.gen_loop_start(expr.int()) //to = range_expr.int() // TODO why empty? - } - + } + } is_arr := typ.contains('array') + is_fixed := typ.starts_with('[') is_str := typ == 'string' - if !is_arr && !is_str && !is_range && !is_variadic_arg { + if !is_arr && !is_str && !is_range && !is_fixed && !is_variadic_arg { p.error('cannot range over type `$typ`') } if !is_variadic_arg { if p.is_js { p.genln('var $tmp = $expr;') - } else { + } else if !is_fixed { // Don't copy if it's a fixed array p.genln('$typ $tmp = $expr;') } } @@ -174,6 +175,10 @@ fn (p mut Parser) for_st() { typ = 'byte' p.gen_for_str_header(i, tmp, typ, val) } + else if is_fixed { + typ = typ.all_after(']') + p.gen_for_fixed_header(i, expr, typ, val) + } // println('for typ=$typ vartyp=$var_typ') // Register temp var if val != '_' { @@ -201,6 +206,6 @@ fn (p mut Parser) for_st() { p.returns = false // TODO handle loops that are guaranteed to return if label > 0 { p.x64.gen_loop_end(to, label) - } + } } diff --git a/vlib/compiler/gen_c.v b/vlib/compiler/gen_c.v index f63a47a274..48abfdf004 100644 --- a/vlib/compiler/gen_c.v +++ b/vlib/compiler/gen_c.v @@ -365,6 +365,12 @@ fn (p mut Parser) gen_for_header(i, tmp, var_typ, val string) { p.genln('$var_typ $val = (($var_typ *) $tmp . data)[$i];') } +fn (p mut Parser) gen_for_fixed_header(i, tmp, var_typ, val string) { + p.genln('for (int $i = 0; $i < sizeof(${tmp}) / sizeof($tmp [0]); $i++) {') + if val == '_' { return } + p.genln('$var_typ $val = $tmp[$i];') +} + fn (p mut Parser) gen_for_str_header(i, tmp, var_typ, val string) { // TODO var_typ is always byte //p.genln('array_byte bytes_$tmp = string_bytes( $tmp );')