xref: /original-bsd/usr.bin/window/parser3.c (revision 183db9ee)
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