better error checking for operator overloading
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 10 Jan 2021 05:36:36 +0000 (23:36 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 10 Jan 2021 05:36:36 +0000 (23:36 -0600)
bin/onyx
include/onyxastnodes.h
onyx.exe
src/onyx.c
src/onyxchecker.c
src/onyxsymres.c
src/onyxwasm.c

index ea4c0c52959aed9255588b349bc2f3cfae051834..3d666761c5b3404da8360af1610c79226ddef5f4 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index f87ccdf7560c98c36671cc1e9f5b7b8d37984975..b29e9a2a61f6a6786f768bd59febc82badc1e17e 100644 (file)
@@ -982,14 +982,12 @@ static inline b32 is_lval(AstNode* node) {
         || (node->kind == Ast_Kind_Memres);
 }
 
-static inline b32 binop_is_assignment(AstBinaryOp* binop) {
-    return (binop->operation >= Binary_Op_Assign_Start
-            && binop->operation <= Binary_Op_Assign_End);
+static inline b32 binop_is_assignment(BinaryOp binop) {
+    return (binop >= Binary_Op_Assign_Start && binop <= Binary_Op_Assign_End);
 }
 
-static inline b32 binop_is_compare(AstBinaryOp* binop) {
-    return (binop->operation >= Binary_Op_Equal
-            && binop->operation <= Binary_Op_Greater_Equal);
+static inline b32 binop_is_compare(BinaryOp binop) {
+    return (binop >= Binary_Op_Equal && binop <= Binary_Op_Greater_Equal);
 }
 
 static inline b32 node_is_type(AstNode* node) {
index 515eb88918fbc3c139c4adc6bb9945faad9c717d..282b35bf428a8ff2c7cd941e5f08ed5533de02a9 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index 204130b56d3ecca81fb98719dd03dedd1b7a130c..852129e768a1e09b904938921f92d69308897d9b 100644 (file)
@@ -98,6 +98,9 @@ static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char
             else if (!strcmp(argv[i], "-VV")) {
                 options.verbose_output = 2;
             }
+            else if (!strcmp(argv[i], "-VVV")) {
+                options.verbose_output = 3;
+            }
             else if (!strcmp(argv[i], "--fun") || !strcmp(argv[i], "-F")) {
                 options.fun_output = 1;
             }
@@ -434,7 +437,7 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char*
     bh_table_put(bh_file_contents, compiler_state->loaded_files, (char *) filename, fc);
     fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename);
 
-    if (compiler_state->options->verbose_output)
+    if (compiler_state->options->verbose_output == 2)
         bh_printf("Processing source file:    %s\n", file.filename);
 
     ParseResults results = parse_source_file(compiler_state, &fc);
@@ -467,7 +470,7 @@ static b32 process_load_entity(CompilerState* compiler_state, Entity* ent) {
 static b32 process_entity(CompilerState* compiler_state, Entity* ent) {
     i32 changed = 1;
 
-    if (compiler_state->options->verbose_output == 2) {
+    if (compiler_state->options->verbose_output == 3) {
         if (ent->expr && ent->expr->token)
             printf("%s | %s | %s:%i:%i\n",
                 entity_state_strings[ent->state],
@@ -570,7 +573,7 @@ static i32 onyx_compile(CompilerState* compiler_state) {
 
     u64 duration = bh_time_duration(start_time);
     
-    if (compiler_state->options->verbose_output) {
+    if (compiler_state->options->verbose_output > 0) {
         // TODO: Replace these with bh_printf when padded formatting is added.
         printf("\nStatistics:\n");
         printf("    Time taken: %lf seconds\n", (double) duration / 1000);
index 47ea5c7f017bbcdf456a6742b5087e555303eaaa..6d52a70cf641209d936280ea52a0550aa00b60ac 100644 (file)
@@ -732,10 +732,9 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop, b32 assignment_is_ok) {
         binop->flags |= Ast_Flag_Comptime;
     }
 
-    if (binop_is_assignment(binop)) return check_binop_assignment(binop, assignment_is_ok);
-    if (binop_is_compare(binop))    return check_binaryop_compare(pbinop);
-    if (binop->operation == Binary_Op_Bool_And
-        || binop->operation == Binary_Op_Bool_Or)
+    if (binop_is_assignment(binop->operation)) return check_binop_assignment(binop, assignment_is_ok);
+    if (binop_is_compare(binop->operation))    return check_binaryop_compare(pbinop);
+    if (binop->operation == Binary_Op_Bool_And || binop->operation == Binary_Op_Bool_Or)
         return check_binaryop_bool(pbinop);
 
     if (binop->left->type == NULL) {
@@ -753,6 +752,8 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop, b32 assignment_is_ok) {
     }
 
     if (binop->left->type->kind != Type_Kind_Basic || binop->right->type->kind != Type_Kind_Basic) {
+        if (bh_arr_length(operator_overloads[binop->operation]) == 0) goto not_overloaded;
+
         bh_arr(AstTyped *) args = NULL;
         bh_arr_new(global_heap_allocator, args, 2);
         bh_arr_push(args, binop->left);
index 10ab50b2bc38b0328a98615efa5ce951b7cdd987..d1160ce5557d7838c0964c1cf75f889a6929c027 100644 (file)
@@ -662,6 +662,11 @@ void symres_function_header(AstFunction* func) {
             onyx_report_error(func->token->pos, "Expected 2 exactly arguments for binary operator overload.");
         }
 
+        if (binop_is_assignment(func->operator_overload) ||
+             binop_is_compare(func->operator_overload)) {
+            onyx_report_error(func->token->pos, "'%s' is not currently overloadable.", binaryop_string[func->operator_overload]);
+        }
+
         bh_arr_push(operator_overloads[func->operator_overload], (AstTyped *) func);
     }
 
index fae576491741a52975f724822dfd280f750c343b..e1837dd736758aa055239e415136296cf6ee5f0c 100644 (file)
@@ -1114,7 +1114,7 @@ static const WasmInstructionType binop_map[][4] = {
 EMIT_FUNC(binop, AstBinaryOp* binop) {
     bh_arr(WasmInstruction) code = *pcode;
 
-    if (binop_is_assignment(binop)) {
+    if (binop_is_assignment(binop->operation)) {
         emit_assignment(mod, &code, binop);
         *pcode = code;
         return;