AstTyped *expr;
AstBinaryOp *potential_substitute;
+
+ // This is set by check_method_call.
+ // If set, the address of node can be removed if the
+ // type checking does not pass for it. This makes it
+ // possible to have something that will optionally
+ // have its address taken, if necessary.
+ b32 can_be_removed : 1;
};
struct AstArgument {
AstTyped_base;
return unify_node_and_type_(&alias->alias, type, permanent);
}
+ else if (node->kind == Ast_Kind_Address_Of) {
+ AstAddressOf *address_of = (AstAddressOf *) node;
+ if (address_of->can_be_removed) {
+ if (!permanent) {
+ return unify_node_and_type_(&address_of->expr, type, permanent);
+
+ } else {
+ *pnode = (AstTyped *) address_of->expr;
+ return unify_node_and_type_(pnode, type, permanent);
+ }
+ }
+ }
+
return TYPE_MATCH_FAILED;
}
&& expr->kind != Ast_Kind_Local
&& expr->kind != Ast_Kind_Constraint_Sentinel)
|| (expr->flags & Ast_Flag_Cannot_Take_Addr) != 0) {
+
+ if (aof->can_be_removed) {
+ *(AstTyped **) paof = aof->expr;
+ return Check_Yield_Macro;
+ }
+
ERROR_(aof->token->pos, "Cannot take the address of something that is not an l-value. %s", onyx_ast_node_kind_string(expr->kind));
}
// Implicitly take the address of the value if it is not already a pointer type.
// This could be weird to think about semantically so some testing with real code
// would be good. - brendanfh 2020/02/05
- if (implicit_argument->type->kind != Type_Kind_Pointer)
- implicit_argument = (AstTyped *) make_address_of(context.ast_alloc, implicit_argument);
+ if (implicit_argument->type->kind != Type_Kind_Pointer) {
+ AstAddressOf *address_of = make_address_of(context.ast_alloc, implicit_argument);
+ address_of->can_be_removed = 1;
+ implicit_argument = (AstTyped *) address_of;
+ }
implicit_argument = (AstTyped *) make_argument(context.ast_alloc, implicit_argument);
method_call->left = retval;
method_call->right = parse_factor(parser);
- retval = (AstTyped *) method_call;
+ if (method_call->right->kind == Ast_Kind_Method_Call) {
+ AstBinaryOp *inner_method_call = (AstBinaryOp *) method_call->right;
+ method_call->right = inner_method_call->left;
+ inner_method_call->left = (AstTyped *) method_call;
+
+ retval = (AstTyped *) inner_method_call;
+
+ } else {
+ retval = (AstTyped *) method_call;
+ }
break;
}
expect_token(parser, ':');
if (parser->curr->type == ':') {
+ bh_arr_push(parser->current_symbol_stack, symbol);
AstBinding* binding = parse_top_level_binding(parser, symbol);
+ bh_arr_pop(parser->current_symbol_stack);
if (parser->hit_unexpected_token) return 2;
ENTITY_SUBMIT(binding);
return Symres_Error;
}
+ // AstAlias *left_alias = onyx_ast_node_new(context.ast_alloc, sizeof(AstAlias), Ast_Kind_Alias);
+ // left_alias->token = (*mcall)->left->token;
+ // left_alias->alias = (*mcall)->left;
+ // (*mcall)->left = (AstTyped *) left_alias;
+
AstFieldAccess* implicit_field_access = make_field_access(context.ast_alloc, (*mcall)->left, NULL);
implicit_field_access->token = ((AstCall *) (*mcall)->right)->callee->token;
((AstCall *) (*mcall)->right)->callee = (AstTyped *) implicit_field_access;