]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani: add type entry for new structs early.
[ocean] / csrc / oceani.mdc
index 0f2174de2a8f05aae2f5c0f565df28a97c47785f..e032a7d5a268e76c5f6e459e666859640fbcab22 100644 (file)
@@ -367,14 +367,14 @@ context so indicate that parsing failed.
        static void fput_loc(struct exec *loc, FILE *f);
        static void type_err(struct parse_context *c,
                             char *fmt, struct exec *loc,
-                            struct type *t1, int rules, struct type *t2);
+                            struct type *t1, enum val_rules rules, struct type *t2);
        static void tok_err(struct parse_context *c, char *fmt, struct token *t);
 
 ###### core functions
 
        static void type_err(struct parse_context *c,
                             char *fmt, struct exec *loc,
-                            struct type *t1, int rules, struct type *t2)
+                            struct type *t1, enum val_rules rules, struct type *t2)
        {
                fprintf(stderr, "%s:", c->file_name);
                fput_loc(loc, stderr);
@@ -604,12 +604,12 @@ the value can only be assigned once, when the variable is declared.
 
 ###### forward decls
        static struct type *propagate_types(struct exec *prog, struct parse_context *c, enum prop_err *perr,
-                                           struct type *type, int rules);
+                                           struct type *type, enum val_rules rules);
 ###### core functions
 
        static struct type *__propagate_types(struct exec *prog, struct parse_context *c, enum prop_err *perr,
                                              enum prop_err *perr_local,
-                                             struct type *type, int rules)
+                                             struct type *type, enum val_rules rules)
        {
                struct type *t;
 
@@ -631,7 +631,7 @@ the value can only be assigned once, when the variable is declared.
        }
 
        static struct type *propagate_types(struct exec *prog, struct parse_context *c, enum prop_err *perr,
-                                           struct type *type, int rules)
+                                           struct type *type, enum val_rules rules)
        {
                int pre_err = c->parse_error;
                enum prop_err perr_local = 0;
@@ -991,7 +991,7 @@ which might be reported in error messages.
 ###### forward decls
 
        static void free_value(struct type *type, struct value *v);
-       static int type_compat(struct type *require, struct type *have, int rules);
+       static int type_compat(struct type *require, struct type *have, enum val_rules rules);
        static void type_print(struct type *type, FILE *f);
        static void val_init(struct type *type, struct value *v);
        static void dup_value(struct type *type,
@@ -1056,11 +1056,12 @@ A separate function encoding these cases will simplify some code later.
 
 ###### type functions
 
-       int (*compat)(struct type *this, struct type *other);
+       int (*compat)(struct type *this, struct type *other, enum val_rules rules);
 
 ###### ast functions
 
-       static int type_compat(struct type *require, struct type *have, int rules)
+       static int type_compat(struct type *require, struct type *have,
+                              enum val_rules rules)
        {
                if ((rules & Rboolok) && have == Tbool)
                        return 1;       // NOTEST
@@ -1068,7 +1069,7 @@ A separate function encoding these cases will simplify some code later.
                        return 1;
 
                if (require->compat)
-                       return require->compat(require, have);
+                       return require->compat(require, have, rules);
 
                return require == have;
        }
@@ -2292,9 +2293,7 @@ correctly.
                        *perr |= Eruntime;
                if (v->constant)
                        *perr |= Econst;
-               if (!type)
-                       return v->type;
-               return type;
+               return v->type;
        }
 
 ###### interp exec cases
@@ -2461,7 +2460,8 @@ with a const size by whether they are prepared at parse time or not.
                        free(ptr);
        }
 
-       static int array_compat(struct type *require, struct type *have)
+       static int array_compat(struct type *require, struct type *have,
+                               enum val_rules rules)
        {
                if (have->compat != require->compat)
                        return 0;
@@ -2917,24 +2917,31 @@ function will be needed.
        }
 
 ###### top level grammar
-       DeclareStruct -> struct IDENTIFIER FieldBlock Newlines ${ {
-               struct type *t;
-               t = find_type(c, $ID.txt);
-               if (!t)
-                       t = add_type(c, $ID.txt, &structure_prototype);
-               else if (t->size >= 0) {
+       $*type
+       StructName -> IDENTIFIER ${ {
+               struct type *t = find_type(c, $ID.txt);
+
+               if (t && t->size >= 0) {
                        tok_err(c, "error: type already declared", &$ID);
                        tok_err(c, "info: this is location of declartion", &t->first_use);
-                       /* Create a new one - duplicate */
-                       t = add_type(c, $ID.txt, &structure_prototype);
-               } else {
-                       struct type tmp = *t;
-                       *t = structure_prototype;
-                       t->name = tmp.name;
-                       t->next = tmp.next;
+                       t = NULL;
                }
-               t->structure.field_list = $<FB;
+               if (!t)
+                       t = add_type(c, $ID.txt, NULL);
                t->first_use = $ID;
+               $0 = t;
+       } }$
+       $void
+       DeclareStruct -> struct StructName FieldBlock Newlines ${ {
+               struct type *t = $<SN;
+               struct type tmp = *t;
+
+               *t = structure_prototype;
+               t->name = tmp.name;
+               t->next = tmp.next;
+               t->first_use = tmp.first_use;
+
+               t->structure.field_list = $<FB;
        } }$
 
        $*fieldlist
@@ -3118,7 +3125,8 @@ anything in the heap or on the stack.  A reference can be assigned
                /* Nothing to do here */
        }
 
-       static int reference_compat(struct type *require, struct type *have)
+       static int reference_compat(struct type *require, struct type *have,
+                                   enum val_rules rules)
        {
                if (have->compat != require->compat)
                        return 0;
@@ -3165,8 +3173,8 @@ anything in the heap or on the stack.  A reference can be assigned
        | @ IDENTIFIER ${ {
                struct type *t = find_type(c, $ID.txt);
                if (!t) {
-                       t = add_type(c, $ID.txt, NULL);
-                       t->first_use = $ID;
+                       t = add_type(c, $ID.txt, NULL); // UNTESTED
+                       t->first_use = $ID;     // UNTESTED
                }
                $0 = find_anon_type(c, &reference_prototype, "@%.*s",
                                    $ID.txt.len, $ID.txt.txt);
@@ -3445,7 +3453,8 @@ further detailed when Expression Lists are introduced.
                val->function = NULL;
        }
 
-       static int function_compat(struct type *require, struct type *have)
+       static int function_compat(struct type *require, struct type *have,
+                                  enum val_rules rules)
        {
                // FIXME can I do anything here yet?
                return 0;
@@ -4799,10 +4808,7 @@ be declared at any time.
                        return Tnone;
 
                if (t) {
-                       if (propagate_types(b->right, c, perr_local, t, 0) != t)
-                               if (b->left->type == Xvar)
-                                       type_err(c, "info: variable '%v' was set as %1 here.",
-                                                cast(var, b->left)->var->where_set, t, rules, NULL);
+                       propagate_types(b->right, c, perr_local, t, 0);
                } else {
                        t = propagate_types(b->right, c, perr_local, NULL, 0);
                        if (t)
@@ -4823,6 +4829,9 @@ be declared at any time.
                }
                if (t && t->dup == NULL && !(*perr_local & Emaycopy))
                        type_err(c, "error: cannot assign value of type %1", b, t, 0, NULL);
+               if (b->left->type == Xvar && (*perr_local & Efail))
+                       type_err(c, "info: variable '%v' was set as %1 here.",
+                                cast(var, b->left)->var->where_set, t, rules, NULL);
                return Tnone;
 
                break;
@@ -5657,8 +5666,8 @@ is a bit more interesting at this level.
                        struct value fn = {.function = code};
                        struct type *t;
                        var_block_close(c, CloseFunction, code);
-                       t = add_anon_type(c, &function_prototype, 
-                                         "func %.*s", name->name->name.len, 
+                       t = add_anon_type(c, &function_prototype,
+                                         "func %.*s", name->name->name.len,
                                          name->name->name.txt);
                        name->type = t;
                        t->function.params = reorder_bilist(args);
@@ -5770,7 +5779,7 @@ is a bit more interesting at this level.
                                all_ok = 0;
                        if (!v->type->function.inline_result &&
                            !v->type->function.return_type->dup) {
-                               type_err(c, "error: function cannot return value of type %1", 
+                               type_err(c, "error: function cannot return value of type %1",
                                         v->where_decl, v->type->function.return_type, 0, NULL);
                        }