node_get_type_name(binop->right));
}
-CheckStatus check_binaryop_assignment(AstBinaryOp* binop) {
+static AstCall* binaryop_try_operator_overload(AstBinaryOp* binop) {
+ if (bh_arr_length(operator_overloads[binop->operation]) == 0) return NULL;
+
+ Arguments args = ((Arguments) { NULL, NULL });
+ bh_arr_new(global_heap_allocator, args.values, 2);
+ bh_arr_push(args.values, binop->left);
+ bh_arr_push(args.values, binop->right);
+
+ if (binop_is_assignment(binop->operation)) {
+ args.values[0] = (AstTyped *) make_address_of(context.ast_alloc, binop->left);
+
+ u32 current_checking_level_store = current_checking_level;
+ CheckStatus cs = check_address_of((AstAddressOf *) args.values[0]);
+ current_checking_level = current_checking_level_store;
+
+ if (cs == Check_Yield_Macro) return (AstCall *) &node_that_signals_a_yield;
+ if (cs == Check_Error) {
+ return NULL;
+ }
+ }
+
+ b32 should_yield = 0;
+ AstTyped* overload = find_matching_overload_by_arguments(operator_overloads[binop->operation], &args, &should_yield);
+ if (should_yield) {
+ bh_arr_free(args.values);
+ return (AstCall *) &node_that_signals_a_yield;
+ }
+
+ if (overload == NULL) {
+ bh_arr_free(args.values);
+ return NULL;
+ }
+
+ AstCall* implicit_call = onyx_ast_node_new(context.ast_alloc, sizeof(AstCall), Ast_Kind_Call);
+ implicit_call->token = binop->token;
+ implicit_call->callee = overload;
+ implicit_call->va_kind = VA_Kind_Not_VA;
+
+ bh_arr_each(AstTyped *, arg, args.values)
+ *arg = (AstTyped *) make_argument(context.ast_alloc, *arg);
+
+ implicit_call->args = args;
+ return implicit_call;
+}
+
+
+CheckStatus check_binaryop_assignment(AstBinaryOp** pbinop) {
+ AstBinaryOp* binop = *pbinop;
if (current_checking_level == EXPRESSION_LEVEL)
ERROR(binop->token->pos, "Assignment not valid in expression.");
return Check_Success;
}
-static AstCall* binaryop_try_operator_overload(AstBinaryOp* binop) {
- if (bh_arr_length(operator_overloads[binop->operation]) == 0) return NULL;
-
- Arguments args = ((Arguments) { NULL, NULL });
- bh_arr_new(global_heap_allocator, args.values, 2);
- bh_arr_push(args.values, binop->left);
- bh_arr_push(args.values, binop->right);
-
- b32 should_yield = 0;
- AstTyped* overload = find_matching_overload_by_arguments(operator_overloads[binop->operation], &args, &should_yield);
- if (should_yield) {
- bh_arr_free(args.values);
- return (AstCall *) &node_that_signals_a_yield;
- }
-
- if (overload == NULL) {
- bh_arr_free(args.values);
- return NULL;
- }
-
- AstCall* implicit_call = onyx_ast_node_new(context.ast_alloc, sizeof(AstCall), Ast_Kind_Call);
- implicit_call->token = binop->token;
- implicit_call->callee = overload;
- implicit_call->va_kind = VA_Kind_Not_VA;
-
- bh_arr_each(AstTyped *, arg, args.values)
- *arg = (AstTyped *) make_argument(context.ast_alloc, *arg);
-
- implicit_call->args = args;
- return implicit_call;
-}
-
CheckStatus check_binaryop(AstBinaryOp** pbinop) {
AstBinaryOp* binop = *pbinop;
binop->flags |= Ast_Flag_Comptime;
}
- if (binop_is_assignment(binop->operation)) return check_binaryop_assignment(binop);
-
if (expression_types_must_be_known) {
if (binop->left->type == NULL || binop->right->type == NULL) {
ERROR(binop->token->pos, "Internal compiler error: one of the operands types is unknown here.");
}
}
+ if (binop_is_assignment(binop->operation)) return check_binaryop_assignment(pbinop);
+
// NOTE: Comparision operators and boolean operators are handled separately.
if (binop_is_compare(binop->operation))
return check_binaryop_compare(pbinop);
static b32 parse_possible_array_literal(OnyxParser* parser, AstTyped* left, AstTyped** ret) {
if (!next_tokens_are(parser, 2, '.', '[')) return 0;
-
+
AstArrayLiteral* al = make_node(AstArrayLiteral, Ast_Kind_Array_Literal);
al->token = parser->curr;
al->atnode = left;
expect_token(parser, '[');
while (!consume_token_if_next(parser, ']')) {
if (parser->hit_unexpected_token) return 1;
-
+
AstTyped* value = parse_expression(parser, 0);
bh_arr_push(al->values, value);
str_node->token = expect_token(parser, Token_Type_Literal_String);
str_node->addr = 0;
str_node->flags |= Ast_Flag_Comptime;
-
+
ENTITY_SUBMIT(str_node);
-
+
retval = (AstTyped *) str_node;
break;
}
fc->token = parser->prev - 1;
fc->filename_token = expect_token(parser, Token_Type_Literal_String);
fc->type = type_make_slice(parser->allocator, &basic_types[Basic_Kind_U8]);
-
+
ENTITY_SUBMIT(fc);
-
+
retval = (AstTyped *) fc;
break;
}
AstStrLit* filename = make_node(AstStrLit, Ast_Kind_StrLit);
filename->token = str_token;
filename->addr = 0;
-
+
ENTITY_SUBMIT(filename);
retval = (AstTyped *) filename;
break;
case '.': {
if (parse_possible_struct_literal(parser, retval, &retval)) return retval;
if (parse_possible_array_literal(parser, retval, &retval)) return retval;
-
+
consume_token(parser);
AstFieldAccess* field = make_node(AstFieldAccess, Ast_Kind_Field_Access);
field->token = expect_token(parser, Token_Type_Symbol);
right = parse_factor(parser);
bin_op->right = right;
}
-
+
expression_done:
bh_arr_free(tree_stack);
return root;
while (!consume_token_if_next(parser, '}')) {
if (parser->hit_unexpected_token) return s_node;
-
+
member_is_used = consume_token_if_next(parser, Token_Type_Keyword_Use);
if (next_tokens_are(parser, 3, Token_Type_Symbol, ':', ':')) {
if (parser->curr->type != '}')
expect_token(parser, ',');
}
-
+
ENTITY_SUBMIT(ofunc);
return ofunc;
}
pp->token = func_def->token;
pp->poly_params = polymorphic_vars;
pp->base_func = func_def;
-
+
return (AstFunction *) pp;
} else {
else if (parse_possible_directive(parser, "private_file")) private_kind = Ast_Flag_Private_File;
AstBinding* binding = NULL;
-
+
switch ((u16) parser->curr->type) {
case Token_Type_Keyword_Use: {
AstNode* use_node = parse_use_stmt(parser);
goto submit_binding_to_entities;
}
-
+
AstMemRes* memres = make_node(AstMemRes, Ast_Kind_Memres);
memres->token = symbol;
if (parser->curr->type != '=')
memres->type_node = parse_type(parser);
-
+
if (consume_token_if_next(parser, '='))
memres->initial_value = parse_expression(parser, 1);
-
-
+
+
ENTITY_SUBMIT(memres);
-
+
binding = make_node(AstBinding, Ast_Kind_Binding);
binding->token = symbol;
binding->flags |= private_kind;
include->name = bh_strdup(parser->allocator, str_token->text);
token_toggle_end(str_token);
}
-
+
ENTITY_SUBMIT(include);
return;
}
else if (parse_possible_directive(parser, "load_path")) {
AstInclude* include = make_node(AstInclude, Ast_Kind_Load_Path);
include->token = dir_token;
-
+
OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String);
if (str_token != NULL) {
token_toggle_end(str_token);
include->name = bh_strdup(parser->allocator, str_token->text);
token_toggle_end(str_token);
}
-
+
ENTITY_SUBMIT(include);
return;
}
else if (parse_possible_directive(parser, "error")) {
AstDirectiveError *error = make_node(AstDirectiveError, Ast_Kind_Directive_Error);
error->token = dir_token;
- error->error_msg = expect_token(parser, Token_Type_Literal_String);
+ error->error_msg = expect_token(parser, Token_Type_Literal_String);
ENTITY_SUBMIT(error);
return;
BinaryOp op = binary_op_from_token_type(parser->curr->type);
consume_token(parser);
if (op == Binary_Op_Subscript) expect_token(parser, ']'); // #operator [] ... needs to consume the other ']'
-
+
if (op == Binary_Op_Count) {
onyx_report_error(parser->curr->pos, "Invalid binary operator.");
} else {
target_scope = parser->package->private_scope;
if (binding->flags & Ast_Flag_Private_File)
target_scope = parser->file_scope;
-
+
ENTITY_SUBMIT_IN_SCOPE(binding, target_scope);
}
}
OnyxToken* symbol = expect_token(parser, Token_Type_Symbol);
bh_arr_push(package_node->path, symbol);
-
+
if (consume_token_if_next(parser, '.'));
else break;
}
total_package_name_length += (*token)->length + 1;
}
- char* package_name = bh_alloc_array(context.ast_alloc, char, total_package_name_length);
+ char* package_name = bh_alloc_array(context.ast_alloc, char, total_package_name_length);
*package_name = '\0';
bh_arr_each(OnyxToken *, token, package_node->path) {
}
AstPackage* package_node = parse_package_expression(parser);
-
+
char aggregate_name[2048];
aggregate_name[0] = '\0';
strncat(aggregate_name, (*symbol)->text, 2047);
Package* newpackage = package_lookup_or_create(aggregate_name, context.global_scope, parser->allocator);
-
+
AstPackage* pnode = make_node(AstPackage, Ast_Kind_Package);
pnode->token = *symbol;
pnode->package = newpackage;
}
package_node->package = prevpackage;
-
+
return package_node->package;
}
static SymresStatus symres_symbol(AstNode** symbol_node) {
OnyxToken* token = (*symbol_node)->token;
- AstNode* res = symbol_resolve(curr_scope, token);
+ AstNode* res = symbol_resolve(curr_scope, token);
if (!res) { // :SymresStall
if (report_unresolved_symbols) {
//
// Foo :: struct (T: type_expr) {
// use t : T;
- //
+ //
// something_else := 5 + 6 * 8;
// }
//
// because I think the following should be possible:
//
// baked_proc :: (x: $T, $f: (T) -> T) -> T ...
- //
+ //
// The type of 'f' depends on resolving the value for the polyvar 'T'.
SYMRES(type, ¶m->type_expr);
}
return Symres_Error;
}
- if (binop_is_assignment(operator->operator)) {
+ /*if (binop_is_assignment(operator->operator)) {
onyx_report_error(overload->token->pos, "'%s' is not currently overloadable.", binaryop_string[operator->operator]);
return Symres_Error;
- }
+ }*/
add_overload_option(&operator_overloads[operator->operator], 0, operator->overload);
break;
}
case Entity_Type_Static_If: ss = symres_static_if(ent->static_if); break;
-
+
case Entity_Type_Foreign_Function_Header:
case Entity_Type_Function_Header: ss = symres_function_header(ent->function); break;
case Entity_Type_Function: ss = symres_function(ent->function); break;