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