Bug ASH allows ArrayLiterals in initialization but not function calls

Veracity

Developer
Staff member
Code:
int[] make_array(int... data)
{
    return data;
}

int[] test1_array = {};
int[] test1 = make_array(test1_array);
print( count( test1) );

int[] test2_array = {1, 2, 3};
int[] test2 = make_array(test2_array);
print( count( test2) );

int[] test3 = make_array(1, 2, 3);
print( count( test3) );

/*
int[] test4 = make_array({1, 2, 3});
print( count( test4) );
*/

yields

Code:
> array_literal_test

0
3
3

If I uncomment the last test:

Code:
> array_literal_test

Expected ), found { (array_literal_test.ash, line 17, char 26 to char 27)

Yes, obviously in this case, I could just use the varargs to create the array for me, but if I want to pass in an anonymous array as the not-last argument, that won't work.
 

heeheehee

Developer
Staff member
Note that this does work for array literals where you specify the type:

Code:
int[] test4 = make_array(int[]{1, 2, 3});
print( count( test4) );

Normally we can omit the types when it's unambiguous from the context (e.g. an assignment or initialization). But when parsing a function call, you're actually using the arguments to disambiguate which function to call (due to polymorphism).

(I'm not saying this can't or shouldn't be done, just explaining why it doesn't work today.)
 

Veracity

Developer
Staff member
Huh. You are exactly right about that. I was thinking that we knew the parameter types when parsing a function call, but, no.
I'll ponder this a bit more and probably end up closing it as not a bug. :)
 

heeheehee

Developer
Staff member
(brainstorming how this could work)

Suppose that we called make_array{{1, 2, 3}). Parser.parseAggregateLiteral() would not know the type of the literal, so we'd have to provide some placeholder. Throughout the parsing process, we'd have to check something like Operator.validCoercion() for newly-parsed keys and values and refine the type as we continued with the parse.

That resulting type might not be sufficiently refined to match an existing function (e.g. float[] instead of int[]), so we'd potentially need another round of coercion.

I believe the only coercion we need is for promoting int -> float, potentially nested within an aggregate, e.g.
Code:
{1: {2: 3, 4: 5.0}}
since that's the only confusable literal type.
 
Top