From a9cd2fcd52ae4ba9c19f775221cc14d2745083b3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 30 Oct 2021 14:23:46 +1100 Subject: [PATCH] ocean: change program to receive argc and argv 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 --- csrc/oceani-tests.mdc | 7 ++-- csrc/oceani.mdc | 93 +++++++++++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/csrc/oceani-tests.mdc b/csrc/oceani-tests.mdc index d5541e9..55e8477 100644 --- a/csrc/oceani-tests.mdc +++ b/csrc/oceani-tests.mdc @@ -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. diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index 879aa6e..65790ec 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -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. -- 2.43.0