]> ocean-lang.org Git - ocean/commitdiff
ocean: change program to receive argc and argv
authorNeilBrown <neil@brown.name>
Sat, 30 Oct 2021 03:23:46 +0000 (14:23 +1100)
committerNeilBrown <neil@brown.name>
Sun, 7 Nov 2021 00:19:48 +0000 (11:19 +1100)
Rather than a list of strings, a "program" now receives and arg count,
and an array of strings with that size.

Signed-off-by: NeilBrown <neil@brown.name>
csrc/oceani-tests.mdc
csrc/oceani.mdc

index d5541e9c3e21ea27ddb418d666789d8062c60beb..55e8477468518ee120591502b99ae489c5d94d95 100644 (file)
@@ -282,9 +282,10 @@ Here I break it into two parts, keeping the array code separate.
 
 ###### test: sayhello
 
-       program As Bs astr bbools:
-               A := $As; B := $Bs
-               bbool := bbools == "True"
+       program ac av:
+               A := $av[1]; B := $av[2]
+               astr := av[3]
+               bbool := av[ac-1] == "True"
                print "Hello World, what lovely oceans you have!"
                /* When a variable is defined in both branches of an 'if',
                 * and used afterwards, the variables are merged.
index 879aa6e38824564dd0b915d323e72931924f4be7..65790ec985469c5268208cd68bb38a8fc116f1df 100644 (file)
@@ -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);
 
@@ -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.