documented overloaded procs; bugfixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 13 Apr 2021 13:58:53 +0000 (08:58 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 13 Apr 2021 13:58:53 +0000 (08:58 -0500)
bin/onyx
include/onyxtypes.h
src/onyxastnodes.c
src/onyxchecker.c
src/onyxtypes.c
src/onyxutils.c

index 303d9fdd4600c06a6e214dd090834cdb2e735702..903d52710345b4d9ba9f9f0d656b1e35a854b3ce 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index daa6d7b00a6e790c4ac7315793c7acbc8f2f5de0..b0d22e27cad61607aeb5a607c49d3c1584b7b342 100644 (file)
@@ -201,5 +201,6 @@ b32 type_is_structlike(Type* type);
 b32 type_is_structlike_strict(Type* type);
 u32 type_structlike_mem_count(Type* type);
 u32 type_structlike_is_simple(Type* type);
+b32 type_is_sl_constructable(Type* type);
 
 #endif // #ifndef ONYX_TYPES
index 95a71acabd8ddcd95417bb63dd4a5edb73c1394c..6811e98c73a43236b9bb790ea5b87428ac7f7c36 100644 (file)
@@ -430,6 +430,8 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) {
 
     if (node->kind == Ast_Kind_Struct_Literal && node->type_node == NULL) {
         if (type->kind == Type_Kind_VarArgs) type = type->VarArgs.ptr_to_data->Pointer.elem;
+        if (!type_is_sl_constructable(type)) return 0;
+
         node->type = type;
 
         add_entities_for_node(NULL, (AstNode *) node, NULL, NULL);
index 7e2eae1af494dcfae477cf145019e34c1a716fa8..83602da106054ea638ac9f2cba860154303d42c0 100644 (file)
@@ -938,11 +938,13 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) {
         bh_arr_each(AstTyped *, value, sl->args.values) {
             if (*value == NULL) {
                 i32 member_idx = value - sl->args.values; // Pointer subtraction hack
+                StructMember smem;
+                type_lookup_member_by_idx(sl->type, member_idx, &smem);
 
                 onyx_report_error(sl->token->pos,
-                    "Value not given for %d%s member, '%s'.",
+                    "Value not given for %d%s member, '%s', for type '%s'.",
                     member_idx + 1, bh_num_suffix(member_idx + 1),
-                    sl->type->Struct.memarr[member_idx]->name);
+                    smem.name, type_get_name(sl->type));
             }
         }
 
index 778b38978d10837818693ac787e8a0136761cffc..18251cf673501a9bd392d7006dbd06775c6d39c3 100644 (file)
@@ -1043,3 +1043,12 @@ u32 type_structlike_is_simple(Type* type) {
         default: return 0;
     }
 }
+
+b32 type_is_sl_constructable(Type* type) {
+    switch (type->kind) {
+        case Type_Kind_Struct:   return 1;
+        case Type_Kind_Slice:    return 1;
+        case Type_Kind_DynArray: return 1;
+        default: return 0;
+    }
+}
index 6d7e3aeebf9af4c022696749cbaa09d73a8bf3bb..e1557180942add55fd066355f9d5bb7f40418490 100644 (file)
@@ -943,6 +943,24 @@ AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupM
 //  * Resolving an overload from a TypeFunction (so an overloaded procedure can be passed as a parameter)
 //
 
+// NOTE: The job of this function is to take a set of overloads, and traverse it to add all possible
+// overloads that are reachable. This is slightly more difficult than it may seem. In this language,
+// overloaded procedures have a strict ordering to their overloads, which determines how the correct
+// match will be found. This was not very complicated until overloaded procedures could be used as
+// overload options. This means that you could create an "infinite loop" of overloads like so:
+// 
+//  o1 :: {                 o2 :: {
+//      (...) { ... },          (...) { ... },
+//      o2                      o1
+//  }                       }
+//
+// Obviously, this is not really an infinite loop. It just means that all options are available if
+// o1 or o2 are called. The difference between o1 and o2 is the order that the overloads will be
+// searched. To build the the list of overloads, a hashmap is used to prevent the problem from being
+// O(n^2), even though n would (probably) be small. bh_imap has the useful property that it maintains
+// an "entries" array that, so long as nothing is ever removed from it, will maintain the order in
+// which entries were put into the map. This is useful because a simple recursive algorithm can
+// collect all the overloads into the map, and also use the map to provide a base case.
 static void build_all_overload_options(bh_arr(AstTyped *) overloads, bh_imap* all_overloads) {
     bh_arr_each(AstTyped *, node, overloads) {
         if (bh_imap_has(all_overloads, (u64) *node)) continue;