Skip to content

Commit

Permalink
Fixed partial array initialization. Fixes #262 (#358)
Browse files Browse the repository at this point in the history
  • Loading branch information
yulvil authored and elliotchance committed Nov 17, 2017
1 parent 3f9aca2 commit c9ea0f3
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
16 changes: 15 additions & 1 deletion tests/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,22 @@ void test_stringarr_init()
is_streq(a[2], "def");
}

void test_partialarr_init()
{
// Last 2 values are filled with zeros
double a[4] = {1.1, 2.2};
is_eq(a[2], 0.0);
is_eq(a[3], 0.0);

struct s b[3] = {{97, 'a'}};
is_eq(b[0].i, 97);
is_eq(b[2].i, 0);
is_eq(b[2].c, 0);
}

int main()
{
plan(42);
plan(47);

START_TEST(intarr);
START_TEST(doublearr);
Expand All @@ -157,6 +170,7 @@ int main()
START_TEST(multidim);
START_TEST(ptrarr);
START_TEST(stringarr_init);
START_TEST(partialarr_init);

done_testing();
}
37 changes: 35 additions & 2 deletions transpiler/variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ func newDeclStmt(a *ast.VarDecl, p *program.Program) (
}

defaultValue, _, newPre, newPost, err := getDefaultValueForVar(p, a)
p.AddMessage(p.GenerateWarningMessage(err, a))
preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)

// Allocate slice so that it operates like a fixed size array.
Expand Down Expand Up @@ -209,7 +210,15 @@ func GenerateFuncType(fields, returns []string) *goast.FuncType {

func transpileInitListExpr(e *ast.InitListExpr, p *program.Program) (goast.Expr, string, error) {
resp := []goast.Expr{}
var hasArrayFiller = false

for _, node := range e.Children() {
// Skip ArrayFiller
if _, ok := node.(*ast.ArrayFiller); ok {
hasArrayFiller = true
continue
}

var expr goast.Expr
var err error
expr, _, _, _, err = transpileToExpr(node, p, true)
Expand All @@ -228,13 +237,37 @@ func transpileInitListExpr(e *ast.InitListExpr, p *program.Program) (goast.Expr,
goArrayType, err := types.ResolveType(p, arrayType)
p.AddMessage(p.GenerateWarningMessage(err, e))

cTypeString = fmt.Sprintf("%s[%d]", arrayType, arraySize)

if hasArrayFiller {
t = &goast.ArrayType{
Elt: &goast.Ident{
Name: goArrayType,
},
Len: util.NewIntLit(arraySize),
}

// Array fillers do not work with slices.
// We initialize the array first, then convert to a slice.
// For example: (&[4]int{1,2})[:]
return &goast.SliceExpr{
X: &goast.ParenExpr{
X: &goast.UnaryExpr{
Op: token.AND,
X: &goast.CompositeLit{
Type: t,
Elts: resp,
},
},
},
}, cTypeString, nil
}

t = &goast.ArrayType{
Elt: &goast.Ident{
Name: goArrayType,
},
}

cTypeString = fmt.Sprintf("%s[%d]", arrayType, arraySize)
} else {
goType, err := types.ResolveType(p, e.Type1)
if err != nil {
Expand Down

0 comments on commit c9ea0f3

Please sign in to comment.