Bug fixes with first class functions
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 27 Jul 2020 20:43:05 +0000 (15:43 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 27 Jul 2020 20:43:05 +0000 (15:43 -0500)
onyx
progs/fcf.onyx
src/onyxchecker.c
src/onyxtypes.c
src/onyxwasm.c

diff --git a/onyx b/onyx
index c90b1111f5debb7bc5536bfa7ea449cdcdf3ff50..5691a378a7c311f3b29a4a1352769f9ce575a5a7 100755 (executable)
Binary files a/onyx and b/onyx differ
index f1303890375b08574b2b5feb05fbb9e98480ec51..f043423fadb39a36fae023f6f5e9fb66da0e3248 100644 (file)
@@ -3,7 +3,7 @@ use "progs/intrinsics"
 
 use package printing
 
-call_me :: proc (f: proc (i32), val: i32) {
+call_me :: proc (f: proc (i32) -> i32, val: i32) {
        f(val);
 }
 
@@ -25,8 +25,15 @@ execute :: proc (use dc: ^DeferredCall) -> i32 {
     return func(left, right);
 }
 
+echo :: proc (i: i32) -> i32 {
+    print(i);
+    return i;
+}
+
 proc #export "main" {
-       call_me(print_i32, 10);
+       call_me(echo, 10);
+
+    print(add as i32);
 
     funcs[0] = add;
     funcs[1] = sub;
index 5d5c7c10f983a9671d5f06051c70c498979df73b..d73db301bc2be0c5fc07c05460d669199f0e3686 100644 (file)
@@ -173,6 +173,13 @@ CHECK(call, AstCall* call) {
     while (actual_param != NULL) {
         if (check_expression((AstTyped **) &actual_param)) return 1;
 
+        if (actual_param->value->kind == Ast_Kind_Overloaded_Function) {
+            onyx_message_add(Msg_Type_Literal,
+                    actual_param->token->pos,
+                    "cannot pass overloaded functions as parameters.");
+            return 1;
+        }
+
         // NOTE: Splat structures into multiple arguments
         if (actual_param->type->kind == Type_Kind_Struct) {
             if (!type_struct_is_simple(actual_param->type)) {
index 71cab6619157a339910436682a23d3adc69e3a73..45b18079f37007d9c51e757b2977fa779c41b433 100644 (file)
@@ -154,6 +154,8 @@ b32 types_are_compatible(Type* t1, Type* t2) {
             if (t2->kind != Type_Kind_Function) return 0;
             if (t1->Function.param_count != t2->Function.param_count) return 0;
 
+            if (!types_are_compatible(t1->Function.return_type, t2->Function.return_type)) return 0;
+
             fori (i, 0, t1->Function.param_count - 1) {
                 if (!types_are_compatible(t1->Function.params[i], t2->Function.params[i])) return 0;
             }
index 966b9ca82dd4a9abef9a3b749bd06d4f7b1e8e65..56afd0455e7131642bcc7291e4a84c89e774c0fd 100644 (file)
@@ -1067,6 +1067,14 @@ COMPILE_FUNC(cast, AstUnaryOp* cast) {
         return;
     }
 
+    if (to->kind == Type_Kind_Function) {
+        onyx_message_add(Msg_Type_Literal,
+                cast->token->pos,
+                "cannot cast to a function");
+        WI(WI_DROP);
+        return;
+    }
+
     if (to->kind == Type_Kind_Basic && to->Basic.kind == Basic_Kind_Void) {
         WI(WI_DROP);
         return;