1 #ifndef lint 2 static char sccsid[] = "@(#)parser5.c 3.6 05/23/84"; 3 #endif 4 5 #include "parser.h" 6 #include "var.h" 7 8 /* 9 * unary $ + - ! ~ 10 */ 11 p_expr11(v, flag) 12 register struct value *v; 13 char flag; 14 { 15 int op; 16 char *opname; 17 18 switch (token) { 19 case T_DOLLAR: 20 opname = "$"; 21 break; 22 case T_PLUS: 23 opname = "unary +"; 24 break; 25 case T_MINUS: 26 opname = "unary -"; 27 break; 28 case T_NOT: 29 opname = "!"; 30 break; 31 case T_COMP: 32 opname = "~"; 33 break; 34 default: 35 return p_expr12(v, flag); 36 } 37 op = token; 38 (void) s_gettok(); 39 if (p_expr11(v, flag) < 0) 40 return -1; 41 switch (v->v_type) { 42 case V_NUM: 43 break; 44 case V_STR: 45 switch (op) { 46 case T_MINUS: 47 case T_NOT: 48 case T_COMP: 49 p_error("Numeric value required for %s.", opname); 50 str_free(v->v_str); 51 v->v_type = V_ERR; 52 return 0; 53 } 54 break; 55 case V_ERR: 56 return 0; 57 } 58 switch (op) { 59 case T_DOLLAR: { 60 struct var *r; 61 if (v->v_type == V_NUM) { 62 v->v_num--; 63 if (cx.x_type != X_BUF || cx.x_arg == 0 || 64 v->v_num < 0 || v->v_num >= cx.x_narg) { 65 p_error("%d: No such argument.", v->v_num); 66 v->v_type = V_ERR; 67 return 0; 68 } 69 if (flag) 70 *v = cx.x_arg[v->v_num]; 71 } else { 72 if ((r = var_lookup(v->v_str)) == 0) { 73 p_error("%s: Undefined variable.", v->v_str); 74 str_free(v->v_str); 75 v->v_type = V_ERR; 76 return 0; 77 } 78 str_free(v->v_str); 79 if (flag) 80 *v = r->r_val; 81 } 82 if (v->v_type == V_STR 83 && (v->v_str = str_cpy(v->v_str)) == 0) { 84 p_memerror(); 85 return -1; 86 } 87 break; 88 } 89 case T_MINUS: 90 v->v_num = - v->v_num; 91 break; 92 case T_NOT: 93 v->v_num = ! v->v_num; 94 break; 95 case T_COMP: 96 v->v_num = ~ v->v_num; 97 break; 98 } 99 return 0; 100 } 101 102 /* 103 * string, number, ( expr ) 104 * Plus function calls. 105 * Also we map % into string. 106 * 107 * Always return v_type == V_ERR when flag == 0. 108 */ 109 p_expr12(v, flag) 110 register struct value *v; 111 char flag; 112 { 113 v->v_type = V_ERR; 114 switch (token) { 115 case T_MOD: 116 if (flag) { 117 v->v_type = V_STR; 118 v->v_str = str_cpy("%"); 119 } 120 (void) s_gettok(); 121 break; 122 case T_NUM: 123 if (flag) { 124 v->v_type = V_NUM; 125 v->v_num = token_num; 126 } 127 (void) s_gettok(); 128 break; 129 case T_STR: 130 if (flag) { 131 v->v_type = V_STR; 132 v->v_str = token_str; 133 } else 134 str_free(token_str); 135 (void) s_gettok(); 136 break; 137 case T_LP: 138 (void) s_gettok(); 139 if (p_expr(v, flag) < 0) { 140 p_synerror(); 141 return -1; 142 } 143 if (token != T_RP) { 144 p_synerror(); 145 val_free(*v); 146 return -1; 147 } 148 (void) s_gettok(); 149 break; 150 default: 151 return -1; 152 } 153 while (token == T_LP) { 154 char *cmd; 155 156 (void) s_gettok(); 157 if (p_convstr(v) < 0) 158 return -1; 159 cmd = v->v_type == V_STR ? v->v_str : 0; 160 if (p_function(cmd, v, flag) < 0) { 161 if (cmd) 162 str_free(cmd); 163 return -1; 164 } 165 if (cmd) 166 str_free(cmd); 167 if (token != T_RP) { 168 p_synerror(); 169 val_free(*v); 170 return -1; 171 } 172 (void) s_gettok(); 173 } 174 return 0; 175 } 176