b32 cast_is_legal(Type* from_, Type* to_, char** err_msg);
char* get_function_name(AstFunction* func);
+b32 fill_in_arguments(bh_arr(AstNode *) values, bh_arr(AstNamedValue *) named_values, AstNode* provider);
+
AstNumLit* make_int_literal(bh_allocator a, i64 value);
AstNumLit* make_float_literal(bh_allocator a, f64 value);
AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right);
return Check_Error;
}
- if (bh_arr_length(sl->values) == 0) {
- bh_arr_new(global_heap_allocator, sl->values, type_structlike_mem_count(sl->type));
- bh_arr_set_length(sl->values, type_structlike_mem_count(sl->type));
- bh_arr_zero(sl->values);
-
- StructMember s;
- bh_arr_each(AstNamedValue *, named_value, sl->named_values) {
- token_toggle_end((*named_value)->token);
- if (!type_lookup_member(sl->type, (*named_value)->token->text, &s)) {
- onyx_report_error((*named_value)->token->pos,
- "The field '%s' does not exist on type '%s'.", (*named_value)->token->text, type_get_name(sl->type));
- token_toggle_end((*named_value)->token);
- return Check_Error;
- }
- token_toggle_end((*named_value)->token);
-
- if (s.included_through_use) {
- onyx_report_error((*named_value)->token->pos, "Cannot specify value for member '%s', which was included through a 'use' statement.", s.name);
- return Check_Error;
- }
-
- if (sl->values[s.idx] != NULL) {
- onyx_report_error((*named_value)->token->pos, "Multiple values given for '%b'.", (*named_value)->token->text, (*named_value)->token->length);
- return Check_Error;
- }
-
- sl->values[s.idx] = (AstTyped *) (*named_value)->value;
- }
-
- if (sl->type->kind == Type_Kind_Struct) {
- bh_arr_each(StructMember*, smem, sl->type->Struct.memarr) {
- u32 idx = (*smem)->idx;
-
- if (sl->values[idx] == NULL) {
- if (*(*smem)->initial_value == NULL) {
- onyx_report_error(sl->token->pos, "No value was given for the field '%s'.", (*smem)->name);
- return Check_Error;
- }
+ i32 mem_count = type_structlike_mem_count(sl->type);
- sl->values[idx] = *(*smem)->initial_value;
- }
+ bh_arr_grow(sl->values, mem_count);
+ fori (i, bh_arr_length(sl->values), mem_count) sl->values[i] = NULL;
+ bh_arr_set_length(sl->values, mem_count);
+ if (!fill_in_arguments((bh_arr(AstNode *)) sl->values, sl->named_values, (AstNode *) sl)) {
+ bh_arr_each(AstTyped *, value, sl->values) {
+ if (*value == NULL) {
+ i32 member_idx = value - sl->values; // Pointer subtraction hack
+
+ onyx_report_error(sl->token->pos,
+ "Value not given for %d%s member, '%s'.",
+ member_idx + 1, bh_num_suffix(member_idx + 1),
+ sl->type->Struct.memarr[member_idx]->name);
}
}
- }
-
- i32 mem_count = type_structlike_mem_count(sl->type);
- if (mem_count != bh_arr_length(sl->values)) {
- onyx_report_error(sl->token->pos,
- "'%s' expects %d values, given %d.",
- type_get_name(sl->type),
- mem_count,
- bh_arr_length(sl->values));
return Check_Error;
}
static AstNumLit* parse_float_literal(OnyxParser* parser);
static b32 parse_possible_struct_literal(OnyxParser* parser, AstTyped* left, AstTyped** ret);
static b32 parse_possible_array_literal(OnyxParser* parser, AstTyped* left, AstTyped** ret);
+static void parse_values_and_named_values(OnyxParser* parser, TokenType end_token,
+ bh_arr(AstNode *)* values, bh_arr(AstNamedValue *)* named_values);
static AstTyped* parse_factor(OnyxParser* parser);
static AstTyped* parse_compound_assignment(OnyxParser* parser, AstTyped* lhs);
static AstTyped* parse_compound_expression(OnyxParser* parser, b32 assignment_allowed);
expect_token(parser, '.');
expect_token(parser, '{');
- b32 is_named = (peek_token(1)->type == '=');
- OnyxToken* name = NULL;
- while (parser->curr->type != '}') {
- if (parser->hit_unexpected_token) break;
-
- if (is_named) {
- name = expect_token(parser, Token_Type_Symbol);
- expect_token(parser, '=');
- } else {
- name = NULL;
- }
-
- AstTyped *expr = parse_expression(parser, 0);
-
- if (is_named) {
- AstNamedValue* nv = make_node(AstStructMember, Ast_Kind_Named_Value);
- nv->token = name;
- nv->value = (AstNode *) expr;
-
- bh_arr_push(sl->named_values, nv);
-
- } else {
- bh_arr_push(sl->values, expr);
- }
-
- if (parser->curr->type != '}')
- expect_token(parser, ',');
- }
-
- expect_token(parser, '}');
+ parse_values_and_named_values(parser, '}',
+ (bh_arr(AstNode *)*) &sl->values,
+ (bh_arr(AstNamedValue *)*) &sl->named_values);
*ret = (AstTyped *) sl;
return 1;
return 1;
}
+static void parse_values_and_named_values(OnyxParser* parser, TokenType end_token,
+ bh_arr(AstNode *)* pvalues, bh_arr(AstNamedValue *)* pnamed_values) {
+ bh_arr(AstNode *) values = *pvalues;
+ bh_arr(AstNamedValue *) named_values = *pnamed_values;
+
+ while (parser->curr->type != end_token) {
+ if (parser->hit_unexpected_token) return;
+
+ if (peek_token(0)->type == Token_Type_Symbol && peek_token(1)->type == '=') {
+ OnyxToken* name = expect_token(parser, Token_Type_Symbol);
+ expect_token(parser, '=');
+
+ AstNamedValue* named_value = make_node(AstNamedValue, Ast_Kind_Named_Value);
+ named_value->token = name;
+ named_value->value = (AstNode *) parse_expression(parser, 0);
+
+ bh_arr_push(named_values, named_value);
+
+ } else {
+ AstNode* value = (AstNode *) parse_expression(parser, 0);
+ bh_arr_push(values, value);
+ }
+
+ if (parser->curr->type != end_token)
+ expect_token(parser, ',');
+ }
+
+ expect_token(parser, end_token);
+
+ *pvalues = values;
+ *pnamed_values = named_values;
+}
+
// ( <expr> )
// - <factor>
// ! <factor>
token_toggle_end(named_value->token);
i32 idx = lookup_idx_by_name(provider, named_value->token->text);
if (idx == -1) {
- onyx_report_error(provider->token->pos,
- "'%s' is not a valid named parameter here.",
- named_value->token->text);
-
+ onyx_report_error(provider->token->pos, "'%s' is not a valid named parameter here.", named_value->token->text);
token_toggle_end(named_value->token);
return 0;
}
values[idx] = named_value->value;
}
+ b32 success = 1;
fori (idx, 0, bh_arr_length(values)) {
- if (values[idx] == NULL) {
- values[idx] = lookup_default_value_by_idx(provider, idx);
-
- if (values[idx] == NULL) return 0;
- }
+ if (values[idx] == NULL) values[idx] = lookup_default_value_by_idx(provider, idx);
+ if (values[idx] == NULL) success = 0;
}
- return 1;
+ return success;
}
\ No newline at end of file