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);
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;
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);
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.