static VALUE *eval5(void) { VALUE *l, *r, *v; l = eval6(); while (nextarg(":")) { G.args++; r = eval6(); v = docolon(l, r); freev(l); freev(r); l = v; } return l; }
void assem() { union token ttok; while(1) { readop(); if(tok.u != TOKFILE && tok.u != '<') { if(checkeos()) goto ealoop; ttok.u = tok.u; if(tok.u == TOKINT) { ttok.u = 2; agetw(); numval = tok.u; } readop(); switch(tok.u) { case '=': doequal(&ttok); goto ealoop; case ':': docolon(&ttok); continue; default: savop = tok.u; tok.u = ttok.u; break; } } opline(); dotmax(); ealoop: if(tok.u == '\n') ++line; if(DEBUG) printf("\nLine %d: ",line); if(tok.u == TOKEOF) return; } }
static VALUE *eval6(void) { static const char keywords[] ALIGN1 = "quote\0""length\0""match\0""index\0""substr\0"; VALUE *r, *i1, *i2; static VALUE *l = NULL; static VALUE *v = NULL; int key = *G.args ? index_in_strings(keywords, *G.args) + 1 : 0; if (key == 0) /* not a keyword */ return eval7(); G.args++; /* We have a valid token, so get the next argument. */ if (key == 1) { /* quote */ if (!*G.args) bb_error_msg_and_die("syntax error"); return str_value(*G.args++); } if (key == 2) { /* length */ r = eval6(); tostring(r); v = int_value(strlen(r->u.s)); freev(r); } else l = eval6(); if (key == 3) { /* match */ r = eval6(); v = docolon(l, r); freev(l); freev(r); } if (key == 4) { /* index */ r = eval6(); tostring(l); tostring(r); v = int_value(strcspn(l->u.s, r->u.s) + 1); if (v->u.i == (arith_t) strlen(l->u.s) + 1) v->u.i = 0; freev(l); freev(r); } if (key == 5) { /* substr */ i1 = eval6(); i2 = eval6(); tostring(l); if (!toarith(i1) || !toarith(i2) || i1->u.i > (arith_t) strlen(l->u.s) || i1->u.i <= 0 || i2->u.i <= 0) v = str_value(""); else { v = xmalloc(sizeof(VALUE)); v->type = STRING; v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); } freev(l); freev(i1); freev(i2); } return v; }