compiler: initializing fixed arrays with [1,2,3]

pull/2243/head
Delyan Angelov 2019-10-06 03:07:02 +03:00 committed by Alexander Medvednikov
parent 22f162c3cd
commit ebc50432c7
3 changed files with 58 additions and 6 deletions

View File

@ -53,7 +53,15 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
// `foo := C.Foo{}` => `Foo foo;` // `foo := C.Foo{}` => `Foo foo;`
if !p.is_empty_c_struct_init && !typ.starts_with('['){ if !p.is_empty_c_struct_init && !typ.starts_with('['){
nt_gen += '=' 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 { if is_static {
nt_gen = 'static $nt_gen' nt_gen = 'static $nt_gen'
} }

View File

@ -1389,6 +1389,17 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
typ := expr_type.replace('Option_', '') typ := expr_type.replace('Option_', '')
p.cgen.resetln(left + 'opt_ok($expr, sizeof($typ))') 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) { 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) 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' return 'void'
} }
field_name := p.lit field_name := p.lit
fname_tidx := p.cur_tok_index()
p.fgen(field_name) p.fgen(field_name)
//p.log('dot() field_name=$field_name typ=$str_typ') //p.log('dot() field_name=$field_name typ=$str_typ')
//if p.fileis('main.v') { //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(field.name)
//} //}
//println('str_typ=="$str_typ"') //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 := '.' mut dot := '.'
if str_typ.ends_with('*') || str_typ == 'FT_Face' { // TODO fix C ptr typedefs 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 { if has_field {
struct_field := if typ.name != 'Option' { p.table.var_cgen_name(field_name) } else { field_name } 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 { 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) exit(1)
} }
if !field.is_mut && !p.has_immutable_field { 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 if !p.builtin_mod && !p.pref.translated && modifying && !is_vi
&& p.has_immutable_field { && p.has_immutable_field {
f := p.first_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:` 'declare the field with `mut:`
struct $f.parent_fn { struct $f.parent_fn {
mut: mut:
$f.name $f.typ $f.name $f.typ
} }
') ', fname_tidx)
} }
if !p.builtin_mod && p.mod != typ.mod { 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 { if field.access_mod == .private && !p.builtin_mod && !p.pref.translated && p.mod != typ.mod {
// println('$typ.name :: $field.name ') // println('$typ.name :: $field.name ')
// println(field.access_mod) // 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.gen(dot + struct_field)
p.next() p.next()
@ -2141,7 +2153,7 @@ struct $f.parent_fn {
} }
// method // method
method := p.table.find_method(typ, field_name) or { 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) exit(1)
} }
p.fn_call(method, method_ph, '', str_typ) p.fn_call(method, method_ph, '', str_typ)

View File

@ -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] )
*/
}