added optional operator overloading via methods
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 15 Nov 2022 23:20:06 +0000 (17:20 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 15 Nov 2022 23:20:06 +0000 (17:20 -0600)
compiler/include/astnodes.h
compiler/src/types.c
core/misc/method_ops.onyx [new file with mode: 0644]

index 05349313ecf0f5e7e774479ffd3c3ac50f3fc577..ae5b9d2991e2785ae1bfdc396f391e9f99c030ea 100644 (file)
@@ -689,6 +689,8 @@ struct AstStructLiteral {
     AstTyped *stnode;
 
     Arguments args;
+
+    Type *generated_inferred_type;
 };
 struct AstArrayLiteral {
     AstTyped_base;
index e74f0c782638957bdf4d764262a44f898fbf46e7..ec3b33341621321030535bb1ce59c90b922155ad 100644 (file)
@@ -709,6 +709,10 @@ Type* type_build_compound_type(bh_allocator alloc, AstCompound* compound) {
 }
 
 Type* type_build_implicit_type_of_struct_literal(bh_allocator alloc, AstStructLiteral* lit) {
+    if (lit->generated_inferred_type) {
+        return lit->generated_inferred_type;
+    }
+
     Type* type = type_create(Type_Kind_Struct, alloc, 0);
     type->ast_type = NULL;
     type->Struct.name = NULL;
@@ -779,6 +783,7 @@ Type* type_build_implicit_type_of_struct_literal(bh_allocator alloc, AstStructLi
     build_linear_types_with_offset(type, &type->Struct.linear_members, 0);
 
     type->Struct.status = SPS_Uses_Done;
+    lit->generated_inferred_type = type;
     return type;
 }
 
diff --git a/core/misc/method_ops.onyx b/core/misc/method_ops.onyx
new file mode 100644 (file)
index 0000000..f9d975d
--- /dev/null
@@ -0,0 +1,47 @@
+package core
+
+#local {
+    __HasEqMethod     :: interface (t: $T, r: $R) { T.__eq(t, r); }
+    __HasNeMethod     :: interface (t: $T, r: $R) { T.__ne(t, r); }
+    __HasLtMethod     :: interface (t: $T, r: $R) { T.__lt(t, r); }
+    __HasLeMethod     :: interface (t: $T, r: $R) { T.__le(t, r); }
+    __HasGtMethod     :: interface (t: $T, r: $R) { T.__gt(t, r); }
+    __HasGeMethod     :: interface (t: $T, r: $R) { T.__ge(t, r); }
+    __HasAddMethod    :: interface (t: $T, r: $R) { T.__add(t, r); }
+    __HasMinusMethod  :: interface (t: $T, r: $R) { T.__minus(t, r); }
+    __HasMulMethod    :: interface (t: $T, r: $R) { T.__mul(t, r); }
+    __HasDivMethod    :: interface (t: $T, r: $R) { T.__div(t, r); }
+    __HasModMethod    :: interface (t: $T, r: $R) { T.__mod(t, r); }
+    __HasAndMethod    :: interface (t: $T, r: $R) { T.__and(t, r); }
+    __HasOrMethod     :: interface (t: $T, r: $R) { T.__or(t, r); }
+    __HasShlMethod    :: interface (t: $T, r: $R) { T.__shl(t, r); }
+    __HasShrMethod    :: interface (t: $T, r: $R) { T.__shr(t, r); }
+    __HasSarMethod    :: interface (t: $T, r: $R) { T.__sar(t, r); }
+    __HasXorMethod    :: interface (t: $T, r: $R) { T.__xor(t, r); }
+    __HasBandMethod   :: interface (t: $T, r: $R) { T.__band(t, r); }
+    __HasBorMethod    :: interface (t: $T, r: $R) { T.__bor(t, r); }
+    __HasSubMethod    :: interface (t: $T, r: $R) { T.__sub(t, r); }
+}
+
+#if #defined(runtime.vars.Onyx_Enable_Operator_Methods) {
+    #operator ==  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasEqMethod(T, R) do return T.__eq(t, r);
+    #operator !=  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasNeMethod(T, R) do return T.__ne(t, r);
+    #operator <   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasLtMethod(T, R) do return T.__lt(t, r);
+    #operator <=  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasLeMethod(T, R) do return T.__le(t, r);
+    #operator >   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasGtMethod(T, R) do return T.__gt(t, r);
+    #operator >=  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasGeMethod(T, R) do return T.__ge(t, r);
+    #operator +   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasAddMethod(T, R) do return T.__add(t, r);
+    #operator -   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasMinusMethod(T, R) do return T.__minus(t, r);
+    #operator *   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasMulMethod(T, R) do return T.__mul(t, r);
+    #operator /   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasDivMethod(T, R) do return T.__div(t, r);
+    #operator %   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasModMethod(T, R) do return T.__mod(t, r);
+    #operator &   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasAndMethod(T, R) do return T.__and(t, r);
+    #operator |   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasOrMethod(T, R) do return T.__or(t, r);
+    #operator <<  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasShlMethod(T, R) do return T.__shl(t, r);
+    #operator >>  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasShrMethod(T, R) do return T.__shr(t, r);
+    #operator >>> #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasSarMethod(T, R) do return T.__sar(t, r);
+    #operator ^   #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasXorMethod(T, R) do return T.__xor(t, r);
+    #operator &&  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasBandMethod(T, R) do return T.__band(t, r);
+    #operator ||  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasBorMethod(T, R) do return T.__bor(t, r);
+    #operator []  #precedence 10000 macro (t: $T, r: $R) -> #auto where __HasSubMethod(T, R) do return T.__sub(t, r);
+}