115853Sedward #ifndef lint 2*16714Sedward static char sccsid[] = "@(#)parser5.c 3.7 07/13/84"; 315853Sedward #endif 415853Sedward 515853Sedward #include "parser.h" 615864Sedward #include "var.h" 715853Sedward 815853Sedward /* 9*16714Sedward * unary $ $? + - ! ~ 1015853Sedward */ 1115853Sedward p_expr11(v, flag) 1215853Sedward register struct value *v; 1315853Sedward char flag; 1415853Sedward { 1515853Sedward int op; 1615853Sedward char *opname; 1715853Sedward 1815853Sedward switch (token) { 1915853Sedward case T_DOLLAR: 2015853Sedward opname = "$"; 2115853Sedward break; 22*16714Sedward case T_DQ: 23*16714Sedward opname = "$?"; 24*16714Sedward break; 2515853Sedward case T_PLUS: 2615853Sedward opname = "unary +"; 2715853Sedward break; 2815853Sedward case T_MINUS: 2915853Sedward opname = "unary -"; 3015853Sedward break; 3115853Sedward case T_NOT: 3215853Sedward opname = "!"; 3315853Sedward break; 3415853Sedward case T_COMP: 3515853Sedward opname = "~"; 3615853Sedward break; 3715853Sedward default: 3815853Sedward return p_expr12(v, flag); 3915853Sedward } 4015853Sedward op = token; 4115853Sedward (void) s_gettok(); 4215853Sedward if (p_expr11(v, flag) < 0) 4315853Sedward return -1; 4415853Sedward switch (v->v_type) { 4515853Sedward case V_NUM: 4615853Sedward break; 4715853Sedward case V_STR: 4815853Sedward switch (op) { 4915853Sedward case T_MINUS: 5015853Sedward case T_NOT: 5115853Sedward case T_COMP: 52*16714Sedward p_error("%s: Numeric operand required.", opname); 5315853Sedward str_free(v->v_str); 5415853Sedward v->v_type = V_ERR; 5515853Sedward return 0; 5615853Sedward } 5715853Sedward break; 5815853Sedward case V_ERR: 5915853Sedward return 0; 6015853Sedward } 6115853Sedward switch (op) { 62*16714Sedward case T_DOLLAR: 63*16714Sedward case T_DQ: 6416449Sedward if (v->v_type == V_NUM) { 65*16714Sedward int tmp = cx.x_type == X_BUF && cx.x_arg != 0 && 66*16714Sedward v->v_num > 0 && v->v_num <= cx.x_narg; 67*16714Sedward if (op == T_DQ) 68*16714Sedward v->v_num = tmp; 69*16714Sedward else if (tmp) 70*16714Sedward *v = cx.x_arg[v->v_num - 1]; 71*16714Sedward else { 7216449Sedward p_error("%d: No such argument.", v->v_num); 7316449Sedward v->v_type = V_ERR; 7416449Sedward } 7516449Sedward } else { 76*16714Sedward char *name = v->v_str; 77*16714Sedward struct var *r = var_lookup(name); 78*16714Sedward if (op == T_DQ) { 79*16714Sedward v->v_type = V_NUM; 80*16714Sedward v->v_num = r != 0; 81*16714Sedward } else if (r != 0) 82*16714Sedward *v = r->r_val; 83*16714Sedward else { 84*16714Sedward p_error("%s: Undefined variable.", name); 8516449Sedward v->v_type = V_ERR; 8616449Sedward } 87*16714Sedward str_free(name); 8815853Sedward } 89*16714Sedward if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) { 9016449Sedward p_memerror(); 9116449Sedward return -1; 9215853Sedward } 9315853Sedward break; 9415853Sedward case T_MINUS: 9515853Sedward v->v_num = - v->v_num; 9615853Sedward break; 9715853Sedward case T_NOT: 9815853Sedward v->v_num = ! v->v_num; 9915853Sedward break; 10015853Sedward case T_COMP: 10115853Sedward v->v_num = ~ v->v_num; 10215853Sedward break; 10315853Sedward } 10415853Sedward return 0; 10515853Sedward } 10615853Sedward 10715853Sedward /* 10815853Sedward * string, number, ( expr ) 10915853Sedward * Plus function calls. 11015853Sedward * Also we map % into string. 11115853Sedward * 11215853Sedward * Always return v_type == V_ERR when flag == 0. 11315853Sedward */ 11415853Sedward p_expr12(v, flag) 11515853Sedward register struct value *v; 11615853Sedward char flag; 11715853Sedward { 11815853Sedward v->v_type = V_ERR; 11915853Sedward switch (token) { 12015853Sedward case T_MOD: 12115853Sedward if (flag) { 12215853Sedward v->v_type = V_STR; 12315853Sedward v->v_str = str_cpy("%"); 12415853Sedward } 12515853Sedward (void) s_gettok(); 12615853Sedward break; 12715853Sedward case T_NUM: 12815853Sedward if (flag) { 12915853Sedward v->v_type = V_NUM; 13015853Sedward v->v_num = token_num; 13115853Sedward } 13215853Sedward (void) s_gettok(); 13315853Sedward break; 13415853Sedward case T_STR: 13515853Sedward if (flag) { 13615853Sedward v->v_type = V_STR; 13715853Sedward v->v_str = token_str; 13815853Sedward } else 13915853Sedward str_free(token_str); 14015853Sedward (void) s_gettok(); 14115853Sedward break; 14215853Sedward case T_LP: 14315853Sedward (void) s_gettok(); 14415853Sedward if (p_expr(v, flag) < 0) { 14515853Sedward p_synerror(); 14615853Sedward return -1; 14715853Sedward } 14815853Sedward if (token != T_RP) { 14915853Sedward p_synerror(); 15015853Sedward val_free(*v); 15115853Sedward return -1; 15215853Sedward } 15315853Sedward (void) s_gettok(); 15415853Sedward break; 15515853Sedward default: 15615853Sedward return -1; 15715853Sedward } 15815853Sedward while (token == T_LP) { 15915853Sedward char *cmd; 16015853Sedward 16115853Sedward (void) s_gettok(); 16216449Sedward if (p_convstr(v) < 0) 16316449Sedward return -1; 16416449Sedward cmd = v->v_type == V_STR ? v->v_str : 0; 16515853Sedward if (p_function(cmd, v, flag) < 0) { 16616298Sedward if (cmd) 16716298Sedward str_free(cmd); 16815853Sedward return -1; 16915853Sedward } 17016298Sedward if (cmd) 17116298Sedward str_free(cmd); 17215853Sedward if (token != T_RP) { 17315853Sedward p_synerror(); 17415853Sedward val_free(*v); 17515853Sedward return -1; 17615853Sedward } 17715853Sedward (void) s_gettok(); 17815853Sedward } 17915853Sedward return 0; 18015853Sedward } 181