Operator overload found!
This commit is contained in:
@@ -79,6 +79,7 @@ struct Ast{
|
|||||||
struct Ast_Type;
|
struct Ast_Type;
|
||||||
struct Ast_Expr:Ast{
|
struct Ast_Expr:Ast{
|
||||||
Ast_Type *resolved_type;
|
Ast_Type *resolved_type;
|
||||||
|
Ast_Decl *resolved_operator_overload;
|
||||||
union{
|
union{
|
||||||
Ast_Type *index_original_type;
|
Ast_Type *index_original_type;
|
||||||
Ast_Type *cast_after_type;
|
Ast_Type *cast_after_type;
|
||||||
|
|||||||
@@ -252,16 +252,25 @@ type_array(Ast_Type *base, S64 size){
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline U64
|
inline U64
|
||||||
calculate_hash_for_arguments(Array<Ast_Type *> args){
|
calculate_hash_for_arguments(Ast_Type *a, Ast_Type *b){
|
||||||
U64 result = 13;
|
U64 result = 13;
|
||||||
For(args) result = hash_mix(result, hash_ptr(it));
|
result = hash_mix(result, hash_ptr(a));
|
||||||
|
result = hash_mix(result, hash_ptr(b));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline U64
|
||||||
|
calculate_hash_for_arguments(Ast_Type *a){
|
||||||
|
U64 result = 13;
|
||||||
|
result = hash_mix(result, hash_ptr(a));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Type *
|
function Ast_Type *
|
||||||
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
||||||
Ast_Type *ret = type_try_tupling(return_vals, ast);
|
Ast_Type *ret = type_try_tupling(return_vals, ast);
|
||||||
U64 hash_without_ret = calculate_hash_for_arguments(args);
|
U64 hash_without_ret = 13;
|
||||||
|
For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it));
|
||||||
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret);
|
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret);
|
||||||
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
|
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
|
||||||
|
|
||||||
@@ -844,8 +853,38 @@ resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag searc
|
|||||||
return decl;
|
return decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Intern_String
|
||||||
|
map_operator_to_intern(Token_Kind op){
|
||||||
|
switch(op){
|
||||||
|
case TK_Add: return op_add; break;
|
||||||
|
case TK_Mul: return op_mul; break;
|
||||||
|
case TK_Div: return op_div; break;
|
||||||
|
case TK_Sub: return op_sub; break;
|
||||||
|
case TK_And: return op_and; break;
|
||||||
|
case TK_BitAnd: return op_bitand; break;
|
||||||
|
case TK_Or: return op_or; break;
|
||||||
|
case TK_BitOr: return op_bitor; break;
|
||||||
|
case TK_BitXor: return op_xor; break;
|
||||||
|
case TK_Equals: return op_equals; break;
|
||||||
|
case TK_NotEquals: return op_not_equals; break;
|
||||||
|
case TK_LesserThenOrEqual: return op_lesser_then_or_equal; break;
|
||||||
|
case TK_GreaterThenOrEqual: return op_greater_then_or_equal; break;
|
||||||
|
case TK_LesserThen: return op_lesser_then; break;
|
||||||
|
case TK_GreaterThen: return op_greater_then; break;
|
||||||
|
case TK_LeftShift: return op_left_shift; break;
|
||||||
|
case TK_RightShift: return op_right_shift; break;
|
||||||
|
case TK_Not: return op_not; break;
|
||||||
|
case TK_Neg: return op_neg; break;
|
||||||
|
case TK_Decrement: return op_decrement; break;
|
||||||
|
case TK_Increment: return op_increment; break;
|
||||||
|
default: return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Ast_Decl *
|
function Ast_Decl *
|
||||||
resolve_operator_overload(Ast_Scope *scope, Token *pos, Intern_String name, U64 argument_hash){
|
resolve_operator_overload(Ast_Scope *scope, Token *pos, Token_Kind op, U64 argument_hash){
|
||||||
|
Intern_String name = map_operator_to_intern(op);
|
||||||
|
if(name.str == 0) return 0;
|
||||||
|
|
||||||
// Search for all possible candidates
|
// Search for all possible candidates
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
@@ -853,10 +892,6 @@ resolve_operator_overload(Ast_Scope *scope, Token *pos, Intern_String name, U64
|
|||||||
search.exit_on_find = false;
|
search.exit_on_find = false;
|
||||||
scope_search(&search);
|
scope_search(&search);
|
||||||
|
|
||||||
if(search.results.len == 0){
|
|
||||||
compiler_error(pos, "Failed to find matching operator overload for [%s] No operator of this kind is defined", name.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve them until we hit a match
|
// Resolve them until we hit a match
|
||||||
Array<Ast_Decl *> matching_ops = {scratch};
|
Array<Ast_Decl *> matching_ops = {scratch};
|
||||||
For(search.results){
|
For(search.results){
|
||||||
@@ -866,15 +901,15 @@ resolve_operator_overload(Ast_Scope *scope, Token *pos, Intern_String name, U64
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(matching_ops.len == 0){
|
|
||||||
compiler_error(pos, "Failed to find matching operator overload for [%s]", name.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(matching_ops.len > 1){
|
if(matching_ops.len > 1){
|
||||||
compiler_error(pos, "Found multiple matching operator overloads for [%s]", name.str);
|
compiler_error(pos, "Found multiple matching operator overloads for [%s]", name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
return matching_ops.data[0];
|
if(matching_ops.len == 1){
|
||||||
|
return matching_ops.data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
@@ -1579,6 +1614,14 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
|||||||
return operand_const_rvalue(value);
|
return operand_const_rvalue(value);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
|
||||||
|
U64 hash = calculate_hash_for_arguments(left.type, right.type);
|
||||||
|
Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, node->pos, node->op, hash);
|
||||||
|
if(operator_overload){
|
||||||
|
__debugbreak();
|
||||||
|
}
|
||||||
|
|
||||||
try_propagating_resolved_type_to_untyped_literals(node->left, value.type);
|
try_propagating_resolved_type_to_untyped_literals(node->left, value.type);
|
||||||
try_propagating_resolved_type_to_untyped_literals(node->right, value.type);
|
try_propagating_resolved_type_to_untyped_literals(node->right, value.type);
|
||||||
return operand_rvalue(value.type);
|
return operand_rvalue(value.type);
|
||||||
|
|||||||
@@ -1,24 +1,14 @@
|
|||||||
|
|
||||||
/*
|
Vec3 :: struct;; x: F32; y: F32; z: F32
|
||||||
@todo: Add function overloading
|
"+" :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x+b.x, a.y+b.y, a.z+b.z}
|
||||||
Current plan:
|
|
||||||
* allow insert_into_scope to insert multiple lambdas
|
|
||||||
* change resolve_name and search_for_decl to something
|
|
||||||
that can seek multiple lambda declarations
|
|
||||||
resolve them and return a match to hash or type
|
|
||||||
* change the order of lambda call resolution, probably would have to
|
|
||||||
hash the arguments first to match the lambda call
|
|
||||||
|
|
||||||
*/
|
|
||||||
// Add :: (a: int, b: int): int ;; return a + b
|
|
||||||
// Add :: (a: F32, b: F32): F32 ;; return a + b
|
|
||||||
|
|
||||||
main :: (): int
|
main :: (): int
|
||||||
a: F32 = 3
|
a := Vec3{1,1,1}
|
||||||
b: F32 = 2
|
b := Vec3{2,3,4}
|
||||||
c: int = 4
|
c := a + b
|
||||||
d: int = 10
|
Assert(a.x == 3)
|
||||||
// e := Add(a, b)
|
Assert(a.y == 4)
|
||||||
// f := Add(c, d)
|
Assert(a.z == 5)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@@ -6,9 +6,6 @@ Vec2I :: struct;; x: S64; y: S64
|
|||||||
Vec2 :: struct;; x: F32; y: F32
|
Vec2 :: struct;; x: F32; y: F32
|
||||||
Vec3 :: struct;; x: F32; y: F32; z: F32
|
Vec3 :: struct;; x: F32; y: F32; z: F32
|
||||||
|
|
||||||
"+" :: (a: Vec3, b: Vec3): Vec3
|
|
||||||
return Vec3_Add(a,b)
|
|
||||||
|
|
||||||
Vec3_Cross :: (a: Vec3, b: Vec3): Vec3
|
Vec3_Cross :: (a: Vec3, b: Vec3): Vec3
|
||||||
result := Vec3{
|
result := Vec3{
|
||||||
a.y * b.z - a.z * b.y,
|
a.y * b.z - a.z * b.y,
|
||||||
|
|||||||
Reference in New Issue
Block a user