- case V_ERR:
- flag = 0;
- break;
- }
- (void) s_gettok();
- if (p_expr1(v, flag && true) < 0)
- return -1;
- if (token != T_COLON) {
- p_synerror();
- return -1;
- }
- (void) s_gettok();
- return p_expr1(v, flag && !true);
-}
-
-/*
- * ||
- */
-p_expr1(v, flag)
-register struct value *v;
-char flag;
-{
- char true = 0;
-
- if (p_expr2(v, flag) < 0)
- return -1;
- if (token != T_OROR)
- return 0;
- for (;;) {
- switch (v->v_type) {
- case V_NUM:
- v->v_num = true = true || v->v_num != 0;
- break;
- case V_STR:
- p_error("Numeric value required for ||.");
- str_free(v->v_str);
- v->v_type = V_ERR;
- case V_ERR:
- flag = 0;
- break;
- }
- if (token != T_OROR)
- return 0;
- (void) s_gettok();
- if (p_expr2(v, flag && !true) < 0)
- return -1;
- }
-}
-
-/*
- * &&
- */
-p_expr2(v, flag)
-register struct value *v;
-char flag;
-{
- char true = 1;
-
- if (p_expr3_10(3, v, flag) < 0)
- return -1;
- if (token != T_ANDAND)
- return 0;
- for (;;) {
- switch (v->v_type) {
- case V_NUM:
- v->v_num = true = true && v->v_num != 0;
- break;
- case V_STR:
- p_error("Numeric value required for &&.");
- str_free(v->v_str);
- v->v_type = V_ERR;
- case V_ERR:
- flag = 0;
- break;
- }
- if (token != T_ANDAND)
- return 0;
- (void) s_gettok();
- if (p_expr3_10(3, v, flag && true) < 0)
- return -1;
- }
- /*NOTREACHED*/
-}
-
-/*
- * | 3
- * ^ 4
- * & 5
- * == != 6
- * < <= > >= 7
- * << >> 8
- * + - 9
- * * / % 10
- */
-p_expr3_10(level, v, flag)
-register struct value *v;
-char flag;
-{
- struct value t;
- int op;
-
- if (level == 10) {
- if (p_expr11(v, flag) < 0)
- return -1;
- } else {
- if (p_expr3_10(level + 1, v, flag) < 0)
- return -1;
- }
- for (;;) {
- switch (level) {
- case 3:
- if (token != T_OR)
- return 0;
- break;
- case 4:
- if (token != T_XOR)
- return 0;
- break;
- case 5:
- if (token != T_AND)
- return 0;
- break;
- case 6:
- if (token != T_EQ && token != T_NE)
- return 0;
- break;
- case 7:
- switch (token) {
- case T_LT:
- case T_LE:
- case T_GT:
- case T_GE:
- break;
- default:
- return 0;
- }
- break;
- case 8:
- if (token != T_LS && token != T_RS)
- return 0;
- break;
- case 9:
- if (token != T_PLUS && token != T_MINUS)
- return 0;
- break;
- case 10:
- switch (token) {
- case T_MUL:
- case T_DIV:
- case T_MOD:
- break;
- default:
- return 0;
- }
- break;
- }
- if (v->v_type == V_ERR)
- flag = 0;
-
- op = token;
- (void) s_gettok();
- if (level == 10) {
- if (p_expr11(&t, flag) < 0)
- return -1;
- } else {
- if (p_expr3_10(level + 1, &t, flag) < 0)
- return -1;
- }
- if (t.v_type == V_ERR) {
- flag = 0;
- v->v_type = V_ERR;
- }
-
- if (!flag)
- return 0;
-
- if (t.v_type != v->v_type) {
- p_error("Type mismatch.");
- v->v_type = V_ERR;
- return 0;
- }
- switch (op) {
- case T_EQ:
- case T_NE:
- case T_LT:
- case T_LE:
- case T_GT:
- case T_GE:
- if (v->v_type == V_STR) {
- int tmp;
- tmp = strcmp(v->v_str, t.v_str);
- str_free(v->v_str);
- str_free(t.v_str);
- v->v_type = V_NUM;
- v->v_num = tmp;
- t.v_num = 0;
- }
- break;
- default:
- if (v->v_type == V_STR) {
- p_error("Numeric value required.");
- str_free(v->v_str);
- str_free(t.v_str);
- v->v_type = V_ERR;
- return 0;
- }
- }
- switch (op) {
- case T_OR:
- v->v_num |= t.v_num;
- break;
- case T_XOR:
- v->v_num ^= t.v_num;
- break;
- case T_AND:
- v->v_num &= t.v_num;
- break;
- case T_EQ:
- v->v_num = v->v_num == t.v_num;
- break;
- case T_NE:
- v->v_num = v->v_num != t.v_num;
- break;
- case T_LT:
- v->v_num = v->v_num < t.v_num;
- break;
- case T_LE:
- v->v_num = v->v_num <= t.v_num;
- break;
- case T_GT:
- v->v_num = v->v_num > t.v_num;
- break;
- case T_GE:
- v->v_num = v->v_num >= t.v_num;
- break;
- case T_LS:
- v->v_num <<= t.v_num;
- break;
- case T_RS:
- v->v_num >>= t.v_num;
- break;
- case T_PLUS:
- v->v_num += t.v_num;
- break;
- case T_MINUS:
- v->v_num -= t.v_num;
- break;
- case T_MUL:
- v->v_num *= t.v_num;
- break;
- case T_DIV:
- v->v_num /= t.v_num;
- break;
- case T_MOD:
- v->v_num %= t.v_num;
- break;
- }
- }
- /*NOTREACHED*/
-}
-
-/*
- * unary $ + - ! ~
- */
-p_expr11(v, flag)
-register struct value *v;
-char flag;
-{
- int op;
-
- switch (token) {
- case T_DOLLAR:
- case T_PLUS:
- case T_MINUS:
- case T_NOT:
- case T_COMP:
- break;
- default:
- return p_expr12(v, flag);
- }
- op = token;
- (void) s_gettok();
- if (p_expr11(v, flag) < 0)
- return -1;
- switch (v->v_type) {
- case V_NUM:
- if (op == T_DOLLAR && (v->v_str = str_itoa(v->v_num)) == 0) {
- p_memerror();
- return -1;
- }
- break;
- case V_STR:
- switch (op) {
- case T_MINUS:
- case T_NOT:
- case T_COMP:
- p_error("Numeric value required.");
- str_free(v->v_str);
- v->v_type = V_ERR;
- return 0;
- }
- break;
- case V_ERR:
- return 0;
- }
- switch (op) {
- case T_DOLLAR: {
- struct var *r;
- if ((r = var_lookup(v->v_str)) == 0) {
- p_error("%s: Undefined variable.", v->v_str);
- str_free(v->v_str);
- v->v_type = V_ERR;
- return 0;
- }
- str_free(v->v_str);
- if (flag) {
- *v = r->r_val;
- if (v->v_type == V_STR
- && (v->v_str = str_cpy(v->v_str)) == 0) {
- p_memerror();
- return -1;
- }
- }
- break;
- }
- case T_MINUS:
- v->v_num = - v->v_num;
- break;
- case T_NOT:
- v->v_num = ! v->v_num;
- break;
- case T_COMP:
- v->v_num = ~ v->v_num;
- break;
- }
- return 0;
-}
-
-/*
- * string, number, ( expr )
- * plus function calls.
- *
- * Always return v_type == V_ERR when flag == 0.
- */
-p_expr12(v, flag)
-register struct value *v;
-char flag;
-{
- v->v_type = V_ERR;
-#ifdef DEBUG
- error("expr12: %d.", flag);
-#endif
- switch (token) {
- case T_NUM:
-#ifdef DEBUG
- error("expr12: NUM %d.", token_num);
-#endif
- if (flag) {
- v->v_type = V_NUM;
- v->v_num = token_num;
- }
- (void) s_gettok();
- break;
- case T_STR:
-#ifdef DEBUG
- error("expr12: STR %s.", token_str);
-#endif
- if (flag) {
- v->v_type = V_STR;
- v->v_str = token_str;
- }
- (void) s_gettok();
- break;
- case T_LP:
- (void) s_gettok();
- if (p_expr(v, flag) < 0) {
- p_synerror();
- return -1;
- }
- if (token != T_RP) {
- p_synerror();
- p_varfree(*v);
- return -1;
- }
- (void) s_gettok();
- break;
- default:
-#ifdef DEBUG
- error("expr12: token %d.", token);
-#endif