]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani: use new slice syntax for argv argument.
[ocean] / csrc / oceani.mdc
index 1ec640f1b4ed6520b17723d36d00d15c1e3a011d..a3574ea24e91167880aa12d2cff4bcefc1a1e412 100644 (file)
@@ -2468,15 +2468,11 @@ with a const size by whether they are prepared at parse time or not.
                /* Both are arrays, so we can look at details */
                if (!type_compat(require->array.member, have->array.member, 0))
                        return 0;
-               if (have->array.unspec && require->array.unspec) {
-                       if (have->array.vsize && require->array.vsize &&
-                           have->array.vsize != require->array.vsize)  // UNTESTED
-                               /* sizes might not be the same */
-                               return 0;       // UNTESTED
-                       return 1;
-               }
+               if (have->array.unspec && require->array.unspec &&
+                   have->array.size != require->array.size)
+                       return 0;       // UNTESTED
                if (have->array.unspec || require->array.unspec)
-                       return 1;       // UNTESTED
+                       return 1;
                if (require->array.vsize == NULL && have->array.vsize == NULL)
                        return require->array.size == have->array.size;
 
@@ -2554,29 +2550,18 @@ with a const size by whether they are prepared at parse time or not.
                $0->array.vsize = v;
        } }$
 
-###### Grammar
-       $*type
-       OptType -> Type ${ $0 = $<1; }$
-               | ${ $0 = NULL; }$
-
 ###### formal type grammar
 
-       | [ IDENTIFIER :: OptType ] Type ${ {
-               struct variable *v = var_decl(c, $ID.txt);
-
-               v->type = $<OT;
-               v->constant = 1;
-               if (!v->type)
-                       v->type = Tnum;
-               $0 = add_anon_type(c, &array_prototype, "array[var]");
-               $0->array.member = $<6;
+       | [ ] Type ${ {
+               $0 = add_anon_type(c, &array_prototype, "array[]");
+               $0->array.member = $<Type;
                $0->array.size = 0;
                $0->array.unspec = 1;
-               $0->array.vsize = v;
+               $0->array.vsize = NULL;
        } }$
 
 ###### Binode types
-       Index,
+       Index, Length,
 
 ###### term grammar
 
@@ -2588,6 +2573,13 @@ with a const size by whether they are prepared at parse time or not.
                $0 = b;
        } }$
 
+       | Term [ ] ${ {
+               struct binode *b = new(binode);
+               b->op = Length;
+               b->left = $<Term;
+               $0 = b;
+       } }$
+
 ###### print binode cases
        case Index:
                print_exec(b->left, -1, bracket);
@@ -2596,6 +2588,11 @@ with a const size by whether they are prepared at parse time or not.
                printf("]");
                break;
 
+       case Length:
+               print_exec(b->left, -1, bracket);
+               printf("[]");
+               break;
+
 ###### propagate binode cases
        case Index:
                /* left must be an array, right must be a number,
@@ -2615,6 +2612,20 @@ with a const size by whether they are prepared at parse time or not.
                }
                break;
 
+       case Length:
+               /* left must be an array, result is a number
+                */
+               t = propagate_types(b->left, c, perr, NULL, 0);
+               if (!t || t->compat != array_compat) {
+                       type_err(c, "error: %1 cannot provide length", prog, t, 0, NULL);
+                       return NULL;
+               }
+               if (!type_compat(type, Tnum, rules))
+                       type_err(c, "error: have %1 but need %2", prog,
+                                        Tnum, rules, type);
+               return Tnum;
+               break;
+
 ###### interp binode cases
        case Index: {
                mpz_t q;
@@ -2640,6 +2651,13 @@ with a const size by whether they are prepared at parse time or not.
                ltype = NULL;
                break;
        }
+       case Length: {
+               lleft = linterp_exec(c, b->left, &ltype);
+               mpq_set_ui(rv.num, ltype->array.size, 1);
+               ltype = NULL;
+               rvtype = Tnum;
+               break;
+       }
 
 #### Structs
 
@@ -3327,7 +3345,7 @@ anything in the heap or on the stack.  A reference can be assigned
 ###### Expressions: dereference
 
 ###### Binode types
-       Deref,
+       Deref, AddressOf,
 
 ###### term grammar
 
@@ -3343,6 +3361,9 @@ anything in the heap or on the stack.  A reference can be assigned
                print_exec(b->left, -1, bracket);
                printf("@");
                break;
+       case AddressOf:
+               print_exec(b->left, -1, bracket);
+               break;
 
 ###### propagate binode cases
        case Deref:
@@ -3356,13 +3377,30 @@ anything in the heap or on the stack.  A reference can be assigned
                        return t->reference.referent;
                break;
 
+       case AddressOf:
+               /* left must be lval, we create reference to it */
+               if (!type || type->free != reference_free)
+                       t = propagate_types(b->left, c, perr, type, 0); // UNTESTED
+               else
+                       t = propagate_types(b->left, c, perr,
+                                           type->reference.referent, 0);
+               if (t)
+                       t = find_anon_type(c, &reference_prototype, "@%.*s",
+                                       t->name.len, t->name.txt);
+               return t;
+
 ###### interp binode cases
-       case Deref: {
+       case Deref:
                left = interp_exec(c, b->left, &ltype);
                lrv = left.ref;
                rvtype = ltype->reference.referent;
                break;
-       }
+
+       case AddressOf:
+               rv.ref = linterp_exec(c, b->left, &rvtype);
+               rvtype = find_anon_type(c, &reference_prototype, "@%.*s",
+                                       rvtype->name.len, rvtype->name.txt);
+               break;
 
 
 #### Functions
@@ -3462,6 +3500,14 @@ further detailed when Expression Lists are introduced.
                return 0;
        }
 
+       static struct exec *take_addr(struct exec *e)
+       {
+               struct binode *rv = new(binode);
+               rv->op = AddressOf;
+               rv->left = e;
+               return rv;
+       }
+
        static void function_check_args(struct parse_context *c, enum prop_err *perr,
                                        struct type *require, struct exec *args)
        {
@@ -3473,13 +3519,22 @@ further detailed when Expression Lists are introduced.
 
                while (param) {
                        struct var *pv = cast(var, param->left);
+                       struct type *t = pv->var->type, *t2;
                        if (!arg) {
                                type_err(c, "error: insufficient arguments to function.",
                                         args, NULL, 0, NULL);
                                break;
                        }
                        *perr = 0;
-                       propagate_types(arg->left, c, perr, pv->var->type, 0);
+                       t2 = propagate_types(arg->left, c, perr, t, Rrefok);
+                       if (t->free == reference_free &&
+                           t->reference.referent == t2 &&
+                           !(*perr & Erval)) {
+                               arg->left = take_addr(arg->left);
+                       } else if (!(*perr & Efail) && !type_compat(t2, t, 0)) {
+                               type_err(c, "error: cannot pass rval when reference expected",
+                                        arg->left, NULL, 0, NULL);
+                       }
                        param = cast(binode, param->right);
                        arg = cast(binode, arg->right);
                }
@@ -5880,15 +5935,12 @@ is a bit more interesting at this level.
                        struct value *vl = var_value(c, v->var);
                        struct value arg;
                        struct type *t;
-                       mpq_t argcq;
                        int i;
 
                        switch (anum++) {
                        case 0: /* argv */
                                t = v->var->type;
-                               mpq_init(argcq);
-                               mpq_set_ui(argcq, argc, 1);
-                               memcpy(var_value(c, t->array.vsize), &argcq, sizeof(argcq));
+                               t->array.size = argc;
                                t->prepare_type(c, t, 0);
                                array_init(v->var->type, vl);
                                for (i = 0; i < argc; i++) {
@@ -5942,7 +5994,7 @@ things which will likely grow as the languages grows.
                name:string
                alive:Boolean
 
-       func main(argv:[argc::]string)
+       func main(argv:[]string)
                print "Hello World, what lovely oceans you have!"
                print "Are there", five, "?"
                print pi, pie, "but", cake