]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani.mdc
oceani: improve test coverage
[ocean] / csrc / oceani.mdc
index 879aa6e38824564dd0b915d323e72931924f4be7..415c024e2dd55cd086b765c5bb4c93493c548cb9 100644 (file)
@@ -226,7 +226,7 @@ structures can be used.
                                exit(1);
                        }
                } else
-                       ss = s;
+                       ss = s;                         // NOTEST
                parse_oceani(ss->code, &context.config, dotrace ? stderr : NULL);
 
                if (!context.prog) {
@@ -243,7 +243,7 @@ structures can be used.
                                fprintf(stderr, "oceani: type error in program - not running.\n");
                                exit(1);
                        }
-                       interp_prog(&context, context.prog, argv+optind+1);
+                       interp_prog(&context, context.prog, argc - optind, argv+optind);
                }
                free_exec(context.prog);
 
@@ -494,7 +494,7 @@ Named type are stored in a simple linked list.  Objects of each type are
        static void type_print(struct type *type, FILE *f)
        {
                if (!type)
-                       fputs("*unknown*type*", f);
+                       fputs("*unknown*type*", f);     // NOTEST
                else if (type->name.len)
                        fprintf(f, "%.*s", type->name.len, type->name.txt);
                else if (type->print_type)
@@ -509,7 +509,7 @@ Named type are stored in a simple linked list.  Objects of each type are
                        type->init(type, val);
        }
 
-       static void dup_value(struct type *type, 
+       static void dup_value(struct type *type,
                              struct value *vold, struct value *vnew)
        {
                if (type && type->dup)
@@ -523,7 +523,7 @@ Named type are stored in a simple linked list.  Objects of each type are
                        return tl->cmp_order(tl, tr, left, right);
                if (tl && tl->cmp_eq)
                        return tl->cmp_eq(tl, tr, left, right);
-               return -1;
+               return -1;                              // NOTEST
        }
 
        static void print_value(struct type *type, struct value *v)
@@ -619,7 +619,7 @@ A separate function encoding these cases will simplify some code later.
        static void _free_value(struct type *type, struct value *v)
        {
                if (!v)
-                       return;
+                       return;         // NOTEST
                switch (type->vtype) {
                case Vnone: break;
                case Vstr: free(v->str.txt); break;
@@ -645,9 +645,9 @@ A separate function encoding these cases will simplify some code later.
                case Vbool:
                        val->bool = 0;
                        break;
-               case Vlabel:                    // NOTEST
-                       val->label = NULL;      // NOTEST
-                       break;                  // NOTEST
+               case Vlabel:
+                       val->label = NULL;
+                       break;
                }
        }
 
@@ -970,7 +970,7 @@ need to be freed.  For this we need to be able to find it, so assume that
 
                if (primary->merged)
                        // shouldn't happen
-                       primary = primary->merged;
+                       primary = primary->merged;      // NOTEST
 
                for (v = primary->previous; v; v=v->previous)
                        if (v == secondary || v == secondary->merged ||
@@ -1214,8 +1214,8 @@ is started, so there is no need to allocate until the size is known.
                        if (!c->local || !v->type)
                                return NULL;
                        if (v->frame_pos + v->type->size > c->local_size) {
-                               printf("INVALID frame_pos\n"); // NOTEST
-                               exit(2);
+                               printf("INVALID frame_pos\n");  // NOTEST
+                               exit(2);                        // NOTEST
                        }
                        return c->local + v->frame_pos;
                }
@@ -1349,8 +1349,8 @@ from the `exec_types` enum.
                }
                if (loc->type == Xbinode)
                        return __fput_loc(cast(binode,loc)->left, f) ||
-                              __fput_loc(cast(binode,loc)->right, f);
-               return 0;
+                              __fput_loc(cast(binode,loc)->right, f);  // NOTEST
+               return 0;                       // NOTEST
        }
        static void fput_loc(struct exec *loc, FILE *f)
        {
@@ -4272,45 +4272,57 @@ analysis is a bit more interesting at this level.
 
        static int analyse_prog(struct exec *prog, struct parse_context *c)
        {
-               struct binode *b = cast(binode, prog);
+               struct binode *bp = cast(binode, prog);
+               struct binode *b;
                int ok = 1;
+               int arg = 0;
+               struct type *argv_type;
+               struct text argv_type_name = { " argv", 5 };
 
-               if (!b)
+               if (!bp)
                        return 0;       // NOTEST
-               do {
-                       ok = 1;
-                       propagate_types(b->right, c, &ok, Tnone, 0);
-               } while (ok == 2);
-               if (!ok)
-                       return 0;
 
-               for (b = cast(binode, b->left); b; b = cast(binode, b->right)) {
-                       struct var *v = cast(var, b->left);
-                       if (!v->var->type) {
-                               v->var->where_set = b;
-                               v->var->type = Tstr;
+               argv_type = add_type(c, argv_type_name, &array_prototype);
+               argv_type->array.member = Tstr;
+
+               for (b = cast(binode, bp->left); b; b = cast(binode, b->right)) {
+                       struct var *v;
+                       ok = 1;
+                       switch (arg++) {
+                       case 0: /* argc */
+                               v = cast(var, b->left);
+                               argv_type->array.vsize = v->var;
+                               propagate_types(b->left, c, &ok, Tnum, 0);
+                               break;
+                       case 1: /* argv */
+                               propagate_types(b->left, c, &ok, argv_type, 0);
+                               break;
+                       default: /* invalid */
+                               propagate_types(b->left, c, &ok, Tnone, 0);
                        }
                }
-               b = cast(binode, prog);
+
                do {
                        ok = 1;
-                       propagate_types(b->right, c, &ok, Tnone, 0);
+                       propagate_types(bp->right, c, &ok, Tnone, 0);
                } while (ok == 2);
                if (!ok)
                        return 0;
 
                /* Make sure everything is still consistent */
-               propagate_types(b->right, c, &ok, Tnone, 0);
+               propagate_types(bp->right, c, &ok, Tnone, 0);
                if (!ok)
                        return 0;
                scope_finalize(c);
                return 1;
        }
 
-       static void interp_prog(struct parse_context *c, struct exec *prog, char **argv)
+       static void interp_prog(struct parse_context *c, struct exec *prog, 
+                               int argc, char **argv)
        {
                struct binode *p = cast(binode, prog);
                struct binode *al;
+               int anum = 0;
                struct value v;
                struct type *vtype;
 
@@ -4321,23 +4333,34 @@ analysis is a bit more interesting at this level.
                        struct var *v = cast(var, al->left);
                        struct value *vl = var_value(c, v->var);
                        struct value arg;
-
-                       if (argv[0] == NULL) {
-                               printf("Not enough args\n");
-                               exit(1);
-                       }
-                       if (v->var->type != Tstr) {
-                               printf("Arg not string!!\n"); // NOTEST
-                               exit(2);                      // NOTEST
+                       struct type *t;
+                       mpq_t argcq;
+                       int i;
+
+                       switch (anum++) {
+                       case 0: /* argc */
+                               if (v->var->type == Tnum) {
+                                       mpq_init(argcq);
+                                       mpq_set_ui(argcq, argc, 1);
+                                       memcpy(vl, &argcq, sizeof(argcq));
+                               }
+                               break;
+                       case 1: /* argv */
+                               t = v->var->type;
+                               t->prepare_type(c, t, 0);
+                               array_init(v->var->type, vl);
+                               for (i = 0; i < argc; i++) {
+                                       struct value *vl2 = vl->array + i * v->var->type->array.member->size;
+                                       
+
+                                       arg.str.txt = argv[i];
+                                       arg.str.len = strlen(argv[i]);
+                                       free_value(Tstr, vl2);
+                                       dup_value(Tstr, &arg, vl2);
+                               }
+                               break;
                        }
-
-                       arg.str.txt = argv[0];
-                       arg.str.len = strlen(argv[0]);
-                       free_value(Tstr, vl);
-                       dup_value(Tstr, &arg, vl);
-
                        al = cast(binode, al->right);
-                       argv++;
                }
                v = interp_exec(c, p->right, &vtype);
                free_value(vtype, &v);
@@ -4374,12 +4397,12 @@ things which will likely grow as the languages grows.
                name:string
                alive:Boolean
 
-       program Astr Bstr:
+       program argc argv:
                print "Hello World, what lovely oceans you have!"
                print "Are there", five, "?"
                print pi, pie, "but", cake
 
-               A := $Astr; B := $Bstr
+               A := $argv[1]; B := $argv[2]
 
                /* When a variable is defined in both branches of an 'if',
                 * and used afterwards, the variables are merged.