From: NeilBrown Date: Sun, 17 Oct 2021 02:35:58 +0000 (+1100) Subject: oceani: add parse_context arg to all interp functions, and a few others. X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=commitdiff_plain;h=63a5c13d3ae31de4cc0814e83feffed6d56e0da6 oceani: add parse_context arg to all interp functions, and a few others. When I switch variables to use a stack frame, I'll need the parse_context available more broadly (as it will hold the stack). So add it to a selection of functions now. Signed-off-by: NeilBrown --- diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index 0de2988..8faff44 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -105,6 +105,7 @@ structures can be used. ###### Parser: header ## macros + struct parse_context; ## ast struct parse_context { struct token_config config; @@ -242,7 +243,7 @@ structures can be used. 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); @@ -429,7 +430,7 @@ Named type are stored in a simple linked list. Objects of each type are 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, @@ -533,12 +534,13 @@ Named type are stored in a simple linked list. Objects of each type are 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) @@ -1421,11 +1423,12 @@ in `rval`. 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) @@ -1435,9 +1438,10 @@ in `rval`. 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; @@ -1446,7 +1450,7 @@ in `rval`. 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; @@ -1529,7 +1533,8 @@ with a const size by whether they are prepared at parse time or not. ###### 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) @@ -1711,8 +1716,8 @@ with a const size by whether they are prepared at parse time or not. 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); @@ -1919,7 +1924,7 @@ function will be needed. { 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; @@ -2008,8 +2013,8 @@ function will be needed. 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 ${ @@ -2017,7 +2022,7 @@ function will be needed. $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 @@ -2483,11 +2488,11 @@ there. 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; @@ -2600,27 +2605,27 @@ evaluate the second expression if not necessary. ###### 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; @@ -2728,8 +2733,8 @@ expression operator, and the `CMPop` non-terminal will match one of them. 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) { @@ -2903,30 +2908,30 @@ should only insert brackets were needed for precedence. ###### 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)); @@ -2938,24 +2943,24 @@ should only insert brackets were needed for precedence. 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; @@ -3177,7 +3182,7 @@ is in-place. 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; @@ -3266,7 +3271,7 @@ same solution. 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) @@ -3397,8 +3402,8 @@ it is declared, and error will be raised as the name is created as ###### 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); @@ -3414,11 +3419,11 @@ it is declared, and error will be raised as the name is created as 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; } @@ -3446,7 +3451,7 @@ function. 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; } } @@ -3470,7 +3475,7 @@ function. ###### interp binode cases case Use: - rv = interp_exec(b->right, &rvtype); + rv = interp_exec(c, b->right, &rvtype); break; ### The Conditional Statement @@ -3900,44 +3905,44 @@ defined. 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: @@ -4053,8 +4058,8 @@ searching through for the Nth constant for decreasing N. 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); } } }$ @@ -4203,7 +4208,7 @@ analysis is a bit more interesting at this level. 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; @@ -4225,7 +4230,7 @@ analysis is a bit more interesting at this level. 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); @@ -4234,7 +4239,7 @@ analysis is a bit more interesting at this level. 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); }