###### Parser: header
## macros
+ struct parse_context;
## ast
struct parse_context {
struct token_config config;
fprintf(stderr, "oceani: type error in program - not running.\n");
exit(1);
}
- interp_prog(context.prog, argv+optind+1);
+ interp_prog(&context, context.prog, argv+optind+1);
}
free_exec(context.prog);
struct type *next;
int size, align;
void (*init)(struct type *type, struct value *val);
- void (*prepare_type)(struct type *type, int parse_time);
+ void (*prepare_type)(struct parse_context *c, struct type *type, int parse_time);
void (*print)(struct type *type, struct value *val);
void (*print_type)(struct type *type, FILE *f);
int (*cmp_order)(struct type *t1, struct type *t2,
printf("*Unknown*"); // NOTEST
}
- static struct value *val_alloc(struct type *t, struct value *init)
+ static struct value *val_alloc(struct parse_context *c, struct type *t,
+ struct value *init)
{
struct value *ret;
if (t->prepare_type)
- t->prepare_type(t, 0);
+ t->prepare_type(c, t, 0);
ret = calloc(1, t->size);
if (init)
struct value rval, *lval;
};
- static struct lrval _interp_exec(struct exec *e);
+ static struct lrval _interp_exec(struct parse_context *c, struct exec *e);
- static struct value interp_exec(struct exec *e, struct type **typeret)
+ static struct value interp_exec(struct parse_context *c, struct exec *e,
+ struct type **typeret)
{
- struct lrval ret = _interp_exec(e);
+ struct lrval ret = _interp_exec(c, e);
if (!ret.type) abort();
if (typeret)
return ret.rval;
}
- static struct value *linterp_exec(struct exec *e, struct type **typeret)
+ static struct value *linterp_exec(struct parse_context *c, struct exec *e,
+ struct type **typeret)
{
- struct lrval ret = _interp_exec(e);
+ struct lrval ret = _interp_exec(c, e);
if (ret.lval)
*typeret = ret.type;
return ret.lval;
}
- static struct lrval _interp_exec(struct exec *e)
+ static struct lrval _interp_exec(struct parse_context *c, struct exec *e)
{
struct lrval ret;
struct value rv = {}, *lrv = NULL;
###### value functions
- static void array_prepare_type(struct type *type, int parse_time)
+ static void array_prepare_type(struct parse_context *c, struct type *type,
+ int parse_time)
{
mpz_t q;
if (!type->array.vsize || type->array.static_size)
long i;
void *ptr;
- lleft = linterp_exec(b->left, <ype);
- right = interp_exec(b->right, &rtype);
+ lleft = linterp_exec(c, b->left, <ype);
+ right = interp_exec(c, b->right, &rtype);
mpz_init(q);
mpz_tdiv_q(q, mpq_numref(right.num), mpq_denref(right.num));
i = mpz_get_si(q);
{
struct fieldref *f = cast(fieldref, e);
struct type *ltype;
- struct value *lleft = linterp_exec(f->left, <ype);
+ struct value *lleft = linterp_exec(c, f->left, <ype);
lrv = (void*)lleft->ptr + ltype->structure.fields[f->index].offset;
rvtype = ltype->structure.fields[f->index].type;
break;
if (!ok)
c->parse_error = 1;
else {
- struct value vl = interp_exec($5, NULL);
- $0->f.init = val_alloc($0->f.type, &vl);
+ struct value vl = interp_exec(c, $5, NULL);
+ $0->f.init = val_alloc(c, $0->f.type, &vl);
}
} }$
| IDENTIFIER : Type ${
$0->f.name = $1.txt;
$0->f.type = $<3;
if ($0->f.type->prepare_type)
- $0->f.type->prepare_type($0->f.type, 1);
+ $0->f.type->prepare_type(c, $0->f.type, 1);
}$
###### forward decls
case CondExpr: {
struct binode *b2 = cast(binode, b->right);
- left = interp_exec(b->left, <ype);
+ left = interp_exec(c, b->left, <ype);
if (left.bool)
- rv = interp_exec(b2->left, &rvtype);
+ rv = interp_exec(c, b2->left, &rvtype);
else
- rv = interp_exec(b2->right, &rvtype);
+ rv = interp_exec(c, b2->right, &rvtype);
}
break;
###### interp binode cases
case And:
- rv = interp_exec(b->left, &rvtype);
- right = interp_exec(b->right, &rtype);
+ rv = interp_exec(c, b->left, &rvtype);
+ right = interp_exec(c, b->right, &rtype);
rv.bool = rv.bool && right.bool;
break;
case AndThen:
- rv = interp_exec(b->left, &rvtype);
+ rv = interp_exec(c, b->left, &rvtype);
if (rv.bool)
- rv = interp_exec(b->right, NULL);
+ rv = interp_exec(c, b->right, NULL);
break;
case Or:
- rv = interp_exec(b->left, &rvtype);
- right = interp_exec(b->right, &rtype);
+ rv = interp_exec(c, b->left, &rvtype);
+ right = interp_exec(c, b->right, &rtype);
rv.bool = rv.bool || right.bool;
break;
case OrElse:
- rv = interp_exec(b->left, &rvtype);
+ rv = interp_exec(c, b->left, &rvtype);
if (!rv.bool)
- rv = interp_exec(b->right, NULL);
+ rv = interp_exec(c, b->right, NULL);
break;
case Not:
- rv = interp_exec(b->right, &rvtype);
+ rv = interp_exec(c, b->right, &rvtype);
rv.bool = !rv.bool;
break;
case NEql:
{
int cmp;
- left = interp_exec(b->left, <ype);
- right = interp_exec(b->right, &rtype);
+ left = interp_exec(c, b->left, <ype);
+ right = interp_exec(c, b->right, &rtype);
cmp = value_cmp(ltype, rtype, &left, &right);
rvtype = Tbool;
switch (b->op) {
###### interp binode cases
case Plus:
- rv = interp_exec(b->left, &rvtype);
- right = interp_exec(b->right, &rtype);
+ rv = interp_exec(c, b->left, &rvtype);
+ right = interp_exec(c, b->right, &rtype);
mpq_add(rv.num, rv.num, right.num);
break;
case Minus:
- rv = interp_exec(b->left, &rvtype);
- right = interp_exec(b->right, &rtype);
+ rv = interp_exec(c, b->left, &rvtype);
+ right = interp_exec(c, b->right, &rtype);
mpq_sub(rv.num, rv.num, right.num);
break;
case Times:
- rv = interp_exec(b->left, &rvtype);
- right = interp_exec(b->right, &rtype);
+ rv = interp_exec(c, b->left, &rvtype);
+ right = interp_exec(c, b->right, &rtype);
mpq_mul(rv.num, rv.num, right.num);
break;
case Divide:
- rv = interp_exec(b->left, &rvtype);
- right = interp_exec(b->right, &rtype);
+ rv = interp_exec(c, b->left, &rvtype);
+ right = interp_exec(c, b->right, &rtype);
mpq_div(rv.num, rv.num, right.num);
break;
case Rem: {
mpz_t l, r, rem;
- left = interp_exec(b->left, <ype);
- right = interp_exec(b->right, &rtype);
+ left = interp_exec(c, b->left, <ype);
+ right = interp_exec(c, b->right, &rtype);
mpz_init(l); mpz_init(r); mpz_init(rem);
mpz_tdiv_q(l, mpq_numref(left.num), mpq_denref(left.num));
mpz_tdiv_q(r, mpq_numref(right.num), mpq_denref(right.num));
break;
}
case Negate:
- rv = interp_exec(b->right, &rvtype);
+ rv = interp_exec(c, b->right, &rvtype);
mpq_neg(rv.num, rv.num);
break;
case Absolute:
- rv = interp_exec(b->right, &rvtype);
+ rv = interp_exec(c, b->right, &rvtype);
mpq_abs(rv.num, rv.num);
break;
case Bracket:
- rv = interp_exec(b->right, &rvtype);
+ rv = interp_exec(c, b->right, &rvtype);
break;
case Concat:
- left = interp_exec(b->left, <ype);
- right = interp_exec(b->right, &rtype);
+ left = interp_exec(c, b->left, <ype);
+ right = interp_exec(c, b->right, &rtype);
rvtype = Tstr;
rv.str = text_join(left.str, right.str);
break;
case StringConv:
- right = interp_exec(b->right, &rvtype);
+ right = interp_exec(c, b->right, &rvtype);
rtype = Tstr;
rvtype = Tnum;
while (rvtype == Tnone &&
b) {
if (b->left)
- rv = interp_exec(b->left, &rvtype);
+ rv = interp_exec(c, b->left, &rvtype);
b = cast(binode, b->right);
}
break;
if (b->left) {
if (sep)
putchar(sep);
- left = interp_exec(b->left, <ype);
+ left = interp_exec(c, b->left, <ype);
print_value(ltype, &left);
free_value(ltype, &left);
if (b->right)
###### interp binode cases
case Assign:
- lleft = linterp_exec(b->left, <ype);
- right = interp_exec(b->right, &rtype);
+ lleft = linterp_exec(c, b->left, <ype);
+ right = interp_exec(c, b->right, &rtype);
if (lleft) {
free_value(ltype, lleft);
dup_value(ltype, &right, lleft);
free_value(v->type, v->val);
free(v->val);
if (b->right) {
- right = interp_exec(b->right, &rtype);
- v->val = val_alloc(v->type, &right);
+ right = interp_exec(c, b->right, &rtype);
+ v->val = val_alloc(c, v->type, &right);
rtype = Tnone;
} else {
- v->val = val_alloc(v->type, NULL);
+ v->val = val_alloc(c, v->type, NULL);
}
break;
}
if (v->var->type == Tnone) {
/* Convert this to a label */
v->var->type = Tlabel;
- v->var->val = val_alloc(Tlabel, NULL);
+ v->var->val = val_alloc(c, Tlabel, NULL);
v->var->val->label = v->var->val;
}
}
###### interp binode cases
case Use:
- rv = interp_exec(b->right, &rvtype);
+ rv = interp_exec(c, b->right, &rvtype);
break;
### The Conditional Statement
struct value v, cnd;
struct type *vtype, *cndtype;
struct casepart *cp;
- struct cond_statement *c = cast(cond_statement, e);
+ struct cond_statement *cs = cast(cond_statement, e);
- if (c->forpart)
- interp_exec(c->forpart, NULL);
+ if (cs->forpart)
+ interp_exec(c, cs->forpart, NULL);
do {
- if (c->condpart)
- cnd = interp_exec(c->condpart, &cndtype);
+ if (cs->condpart)
+ cnd = interp_exec(c, cs->condpart, &cndtype);
else
cndtype = Tnone;
if (!(cndtype == Tnone ||
(cndtype == Tbool && cnd.bool != 0)))
break;
// cnd is Tnone or Tbool, doesn't need to be freed
- if (c->dopart)
- interp_exec(c->dopart, NULL);
+ if (cs->dopart)
+ interp_exec(c, cs->dopart, NULL);
- if (c->thenpart) {
- rv = interp_exec(c->thenpart, &rvtype);
- if (rvtype != Tnone || !c->dopart)
+ if (cs->thenpart) {
+ rv = interp_exec(c, cs->thenpart, &rvtype);
+ if (rvtype != Tnone || !cs->dopart)
goto Xcond_done;
free_value(rvtype, &rv);
rvtype = Tnone;
}
- } while (c->dopart);
+ } while (cs->dopart);
- for (cp = c->casepart; cp; cp = cp->next) {
- v = interp_exec(cp->value, &vtype);
+ for (cp = cs->casepart; cp; cp = cp->next) {
+ v = interp_exec(c, cp->value, &vtype);
if (value_cmp(cndtype, vtype, &v, &cnd) == 0) {
free_value(vtype, &v);
free_value(cndtype, &cnd);
- rv = interp_exec(cp->action, &rvtype);
+ rv = interp_exec(c, cp->action, &rvtype);
goto Xcond_done;
}
free_value(vtype, &v);
}
free_value(cndtype, &cnd);
- if (c->elsepart)
- rv = interp_exec(c->elsepart, &rvtype);
+ if (cs->elsepart)
+ rv = interp_exec(c, cs->elsepart, &rvtype);
else
rvtype = Tnone;
Xcond_done:
if (!ok)
c->parse_error = 1;
else if (v) {
- struct value res = interp_exec($5, &v->type);
- v->val = val_alloc(v->type, &res);
+ struct value res = interp_exec(c, $5, &v->type);
+ v->val = val_alloc(c, v->type, &res);
}
} }$
return !!ok;
}
- static void interp_prog(struct exec *prog, char **argv)
+ static void interp_prog(struct parse_context *c, struct exec *prog, char **argv)
{
struct binode *p = cast(binode, prog);
struct binode *al;
if (vl)
free_value(v->var->type, vl);
if (!vl) {
- vl = val_alloc(v->var->type, NULL);
+ vl = val_alloc(c, v->var->type, NULL);
v->var->val = vl;
}
free_value(v->var->type, vl);
memcpy(vl->str.txt, argv[0], vl->str.len);
argv++;
}
- v = interp_exec(p->right, &vtype);
+ v = interp_exec(c, p->right, &vtype);
free_value(vtype, &v);
}