exit(1);
}
} else
- ss = s;
+ ss = s; // NOTEST
parse_oceani(ss->code, &context.config, dotrace ? stderr : NULL);
if (!context.prog) {
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 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)
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)
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)
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;
case Vbool:
val->bool = 0;
break;
- case Vlabel: // NOTEST
- val->label = NULL; // NOTEST
- break; // NOTEST
+ case Vlabel:
+ val->label = NULL;
+ break;
}
}
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 ||
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;
}
}
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)
{
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.