1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)parser3.c 3.7 (Berkeley) 06/29/88"; 20 #endif /* not lint */ 21 22 #include "parser.h" 23 24 /* 25 * = 26 * ? : 27 * || 28 * && 29 * | 30 * ^ 31 * & 32 * == != 33 * <= >= 34 * << >> 35 * + - 36 * * / % 37 * unary - + ~ ! 38 */ 39 p_expr(v, flag) 40 register struct value *v; 41 char flag; 42 { 43 struct value t; 44 int ret; 45 46 if (p_expr0(&t, flag) < 0) 47 return -1; 48 49 if (token != T_ASSIGN) { 50 *v = t; 51 return 0; 52 } 53 switch (t.v_type) { 54 case V_NUM: 55 p_error("%d: Not a variable.", t.v_num); 56 case V_ERR: 57 t.v_str = 0; 58 break; 59 } 60 ret = p_assign(t.v_str, v, flag); 61 if (t.v_str != 0) 62 str_free(t.v_str); 63 return ret; 64 } 65 66 /* 67 * ? : 68 */ 69 p_expr0(v, flag) 70 register struct value *v; 71 char flag; 72 { 73 struct value t; 74 char true; 75 76 if (p_expr1(v, flag) < 0) 77 return -1; 78 if (token != T_QUEST) 79 return 0; 80 switch (v->v_type) { 81 case V_NUM: 82 true = v->v_num != 0; 83 break; 84 case V_STR: 85 p_error("?: Numeric left operand required."); 86 str_free(v->v_str); 87 v->v_type = V_ERR; 88 case V_ERR: 89 flag = 0; 90 break; 91 } 92 (void) s_gettok(); 93 v->v_type = V_ERR; 94 if ((flag && true ? p_expr1(v, 1) : p_expr1(&t, 0)) < 0) 95 return -1; 96 if (token != T_COLON) { 97 val_free(*v); 98 p_synerror(); 99 return -1; 100 } 101 (void) s_gettok(); 102 return flag && !true ? p_expr1(v, 1) : p_expr1(&t, 0); 103 } 104 105 /* 106 * || 107 */ 108 p_expr1(v, flag) 109 register struct value *v; 110 char flag; 111 { 112 char true = 0; 113 114 if (p_expr2(v, flag) < 0) 115 return -1; 116 if (token != T_OROR) 117 return 0; 118 for (;;) { 119 switch (v->v_type) { 120 case V_NUM: 121 v->v_num = true = true || v->v_num != 0; 122 break; 123 case V_STR: 124 p_error("||: Numeric operands required."); 125 str_free(v->v_str); 126 v->v_type = V_ERR; 127 case V_ERR: 128 flag = 0; 129 break; 130 } 131 if (token != T_OROR) 132 return 0; 133 (void) s_gettok(); 134 if (p_expr2(v, flag && !true) < 0) 135 return -1; 136 } 137 } 138 139 /* 140 * && 141 */ 142 p_expr2(v, flag) 143 register struct value *v; 144 char flag; 145 { 146 char true = 1; 147 148 if (p_expr3_10(3, v, flag) < 0) 149 return -1; 150 if (token != T_ANDAND) 151 return 0; 152 for (;;) { 153 switch (v->v_type) { 154 case V_NUM: 155 v->v_num = true = true && v->v_num != 0; 156 break; 157 case V_STR: 158 p_error("&&: Numeric operands required."); 159 str_free(v->v_str); 160 v->v_type = V_ERR; 161 case V_ERR: 162 flag = 0; 163 break; 164 } 165 if (token != T_ANDAND) 166 return 0; 167 (void) s_gettok(); 168 if (p_expr3_10(3, v, flag && true) < 0) 169 return -1; 170 } 171 /*NOTREACHED*/ 172 } 173