diff --git a/compiler/gen_c.v b/compiler/gen_c.v index 33faf6a8c4..ed70aada62 100644 --- a/compiler/gen_c.v +++ b/compiler/gen_c.v @@ -53,7 +53,15 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string { // `foo := C.Foo{}` => `Foo foo;` if !p.is_empty_c_struct_init && !typ.starts_with('['){ nt_gen += '=' + } else if typ.starts_with('[') && typ[ typ.len-1 ] != `*` { + // a fixed_array initializer, like `v := [1.1, 2.2]!!` + // ... should translate to the following in C `f32 v[2] = {1.1, 2.2};` + initializer := p.cgen.cur_line.right(pos) + if initializer.len > 0 { + p.cgen.resetln(' = {' + initializer.all_after('{') ) + } } + if is_static { nt_gen = 'static $nt_gen' } diff --git a/compiler/parser.v b/compiler/parser.v index 30be4b8f15..6ccb159b18 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -1389,6 +1389,17 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) { typ := expr_type.replace('Option_', '') p.cgen.resetln(left + 'opt_ok($expr, sizeof($typ))') } + else if expr_type[0]==`[` { + // assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!` + expr := p.cgen.cur_line.right(pos).all_after('{').all_before('}') + left := p.cgen.cur_line.left(pos).all_before('=') + cline_pos := p.cgen.cur_line.right(pos) + etype := cline_pos.all_before(' {') + if p.assigned_type != p.expected_type { + p.error_with_token_index( 'incompatible types: $p.assigned_type != $p.expected_type', errtok) + } + p.cgen.resetln('memcpy(& $left, $etype{$expr}, sizeof( $left ) );') + } else if !p.builtin_mod && !p.check_types_no_throw(expr_type, p.assigned_type) { p.error_with_token_index( 'cannot use type `$expr_type` as type `$p.assigned_type` in assignment', errtok) } @@ -2062,6 +2073,7 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string { return 'void' } field_name := p.lit + fname_tidx := p.cur_tok_index() p.fgen(field_name) //p.log('dot() field_name=$field_name typ=$str_typ') //if p.fileis('main.v') { @@ -2094,7 +2106,7 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string { //println(field.name) //} //println('str_typ=="$str_typ"') - p.error('type `$typ.name` has no field or method `$field_name`') + p.error_with_token_index('type `$typ.name` has no field or method `$field_name`', fname_tidx) } mut dot := '.' if str_typ.ends_with('*') || str_typ == 'FT_Face' { // TODO fix C ptr typedefs @@ -2104,7 +2116,7 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string { if has_field { struct_field := if typ.name != 'Option' { p.table.var_cgen_name(field_name) } else { field_name } field := p.table.find_field(typ, struct_field) or { - p.error('missing field: $struct_field in type $typ.name') + p.error_with_token_index('missing field: $struct_field in type $typ.name', fname_tidx) exit(1) } if !field.is_mut && !p.has_immutable_field { @@ -2119,13 +2131,13 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string { if !p.builtin_mod && !p.pref.translated && modifying && !is_vi && p.has_immutable_field { f := p.first_immutable_field - p.error('cannot modify immutable field `$f.name` (type `$f.parent_fn`)\n' + + p.error_with_token_index('cannot modify immutable field `$f.name` (type `$f.parent_fn`)\n' + 'declare the field with `mut:` struct $f.parent_fn { mut: $f.name $f.typ } -') +', fname_tidx) } if !p.builtin_mod && p.mod != typ.mod { } @@ -2133,7 +2145,7 @@ struct $f.parent_fn { if field.access_mod == .private && !p.builtin_mod && !p.pref.translated && p.mod != typ.mod { // println('$typ.name :: $field.name ') // println(field.access_mod) - p.error('cannot refer to unexported field `$struct_field` (type `$typ.name`)') + p.error_with_token_index('cannot refer to unexported field `$struct_field` (type `$typ.name`)', fname_tidx) } p.gen(dot + struct_field) p.next() @@ -2141,7 +2153,7 @@ struct $f.parent_fn { } // method method := p.table.find_method(typ, field_name) or { - p.error('could not find method `$field_name`') // should never happen + p.error_with_token_index('could not find method `$field_name`', fname_tidx) // should never happen exit(1) } p.fn_call(method, method_ph, '', str_typ) diff --git a/compiler/tests/fixed_array_test.v b/compiler/tests/fixed_array_test.v new file mode 100644 index 0000000000..f953050af0 --- /dev/null +++ b/compiler/tests/fixed_array_test.v @@ -0,0 +1,32 @@ + +fn test_fixed_array_can_be_assigned(){ + x := 2.32 + mut v := [8]f32 + v = [1.0, x, 3.0,4.0,5.0,6.0,7.0,8.0]!! + assert v[1] == x +} + +fn test_fixed_array_can_be_used_in_declaration(){ + x := 2.32 + v := [1.0, x, 3.0,4.0,5.0,6.0,7.0,8.0]!! + assert v[1] == x +} + + +struct Context { + pub mut: + vb [8]f32 +} +fn test_fixed_array_can_be_assigned_to_a_struct_field(){ + mut ctx := Context{} + x := 2.32 + ctx.vb = [1.1, x, 3.3, 4.4, 5.0, 6.0, 7.0, 8.9]!! + assert ctx.vb[1] == x + assert ctx.vb[7] == 8.9 + /* + println( ctx.vb[0] ) + println( ctx.vb[1] ) + println( ctx.vb[2] ) + println( ctx.vb[3] ) + */ +}