1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Edward Wang at The University of California, Berkeley. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)parser3.c 3.9 (Berkeley) 06/06/90"; 13 #endif /* not lint */ 14 15 #include "parser.h" 16 17 /* 18 * = 19 * ? : 20 * || 21 * && 22 * | 23 * ^ 24 * & 25 * == != 26 * <= >= 27 * << >> 28 * + - 29 * * / % 30 * unary - + ~ ! 31 */ 32 p_expr(v, flag) 33 register struct value *v; 34 char flag; 35 { 36 struct value t; 37 int ret; 38 39 if (p_expr0(&t, flag) < 0) 40 return -1; 41 42 if (token != T_ASSIGN) { 43 *v = t; 44 return 0; 45 } 46 switch (t.v_type) { 47 case V_NUM: 48 p_error("%d: Not a variable.", t.v_num); 49 case V_ERR: 50 t.v_str = 0; 51 break; 52 } 53 ret = p_assign(t.v_str, v, flag); 54 if (t.v_str != 0) 55 str_free(t.v_str); 56 return ret; 57 } 58 59 /* 60 * ? : 61 */ 62 p_expr0(v, flag) 63 register struct value *v; 64 char flag; 65 { 66 struct value t; 67 char true; 68 69 if (p_expr1(v, flag) < 0) 70 return -1; 71 if (token != T_QUEST) 72 return 0; 73 switch (v->v_type) { 74 case V_NUM: 75 true = v->v_num != 0; 76 break; 77 case V_STR: 78 p_error("?: Numeric left operand required."); 79 str_free(v->v_str); 80 v->v_type = V_ERR; 81 case V_ERR: 82 flag = 0; 83 break; 84 } 85 (void) s_gettok(); 86 v->v_type = V_ERR; 87 if ((flag && true ? p_expr1(v, 1) : p_expr1(&t, 0)) < 0) 88 return -1; 89 if (token != T_COLON) { 90 val_free(*v); 91 p_synerror(); 92 return -1; 93 } 94 (void) s_gettok(); 95 return flag && !true ? p_expr1(v, 1) : p_expr1(&t, 0); 96 } 97 98 /* 99 * || 100 */ 101 p_expr1(v, flag) 102 register struct value *v; 103 char flag; 104 { 105 char true = 0; 106 107 if (p_expr2(v, flag) < 0) 108 return -1; 109 if (token != T_OROR) 110 return 0; 111 for (;;) { 112 switch (v->v_type) { 113 case V_NUM: 114 v->v_num = true = true || v->v_num != 0; 115 break; 116 case V_STR: 117 p_error("||: Numeric operands required."); 118 str_free(v->v_str); 119 v->v_type = V_ERR; 120 case V_ERR: 121 flag = 0; 122 break; 123 } 124 if (token != T_OROR) 125 return 0; 126 (void) s_gettok(); 127 if (p_expr2(v, flag && !true) < 0) 128 return -1; 129 } 130 } 131 132 /* 133 * && 134 */ 135 p_expr2(v, flag) 136 register struct value *v; 137 char flag; 138 { 139 char true = 1; 140 141 if (p_expr3_10(3, v, flag) < 0) 142 return -1; 143 if (token != T_ANDAND) 144 return 0; 145 for (;;) { 146 switch (v->v_type) { 147 case V_NUM: 148 v->v_num = true = true && v->v_num != 0; 149 break; 150 case V_STR: 151 p_error("&&: Numeric operands required."); 152 str_free(v->v_str); 153 v->v_type = V_ERR; 154 case V_ERR: 155 flag = 0; 156 break; 157 } 158 if (token != T_ANDAND) 159 return 0; 160 (void) s_gettok(); 161 if (p_expr3_10(3, v, flag && true) < 0) 162 return -1; 163 } 164 /*NOTREACHED*/ 165 } 166