xref: /original-bsd/usr.bin/window/parser1.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1983, 1993
3  *	The Regents of the University of California.  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[] = "@(#)parser1.c	8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14 
15 #include "parser.h"
16 
17 p_start()
18 {
19 	char flag = 1;
20 
21 	(void) s_gettok();
22 	for (;;) {
23 		p_statementlist(flag);
24 		if (token == T_EOF || p_abort())
25 			break;
26 		flag = 0;
27 		p_synerror();
28 		while (token != T_EOL && token != T_EOF) {
29 			if (token == T_STR)
30 				str_free(token_str);
31 			(void) s_gettok();
32 		}
33 		if (token == T_EOL)
34 			(void) s_gettok();
35 		p_clearerr();
36 	}
37 }
38 
39 p_statementlist(flag)
40 char flag;
41 {
42 	for (; p_statement(flag) >= 0; p_clearerr())
43 		;
44 }
45 
46 p_statement(flag)
47 char flag;
48 {
49 	switch (token) {
50 	case T_EOL:
51 		(void) s_gettok();
52 		return 0;
53 	case T_IF:
54 		return p_if(flag);
55 	default:
56 		return p_expression(flag);
57 	}
58 }
59 
60 p_if(flag)
61 char flag;
62 {
63 	struct value t;
64 	char true = 0;
65 
66 top:
67 	(void) s_gettok();
68 
69 	if (p_expr(&t, flag) < 0) {
70 		p_synerror();
71 		return -1;
72 	}
73 	switch (t.v_type) {
74 	case V_NUM:
75 		true = !true && t.v_num != 0;
76 		break;
77 	case V_STR:
78 		p_error("if: Numeric value required.");
79 		str_free(t.v_str);
80 	case V_ERR:
81 		flag = 0;
82 		break;
83 	}
84 
85 	if (token != T_THEN) {
86 		p_synerror();
87 		return -1;
88 	}
89 
90 	(void) s_gettok();
91 	p_statementlist(flag && true);
92 	if (p_erred())
93 		return -1;
94 
95 	if (token == T_ELSIF)
96 		goto top;
97 
98 	if (token == T_ELSE) {
99 		(void) s_gettok();
100 		p_statementlist(flag && !true);
101 		if (p_erred())
102 			return -1;
103 	}
104 
105 	if (token == T_ENDIF) {
106 		(void) s_gettok();
107 		return 0;
108 	}
109 
110 	p_synerror();
111 	return -1;
112 }
113 
114 p_expression(flag)
115 char flag;
116 {
117 	struct value t;
118 	char *cmd;
119 	int p_function(), p_assign();
120 
121 	switch (token) {
122 	case T_NUM:
123 		t.v_type = V_NUM;
124 		t.v_num = token_num;
125 		(void) s_gettok();
126 		break;
127 	case T_STR:
128 		t.v_type = V_STR;
129 		t.v_str = token_str;
130 		(void) s_gettok();
131 		break;
132 	default:
133 		if (p_expr(&t, flag) < 0)
134 			return -1;
135 		if (token == T_EOF) {
136 			val_free(t);
137 			return 0;
138 		}
139 	}
140 	if (token != T_ASSIGN && p_convstr(&t) < 0)
141 		return -1;
142 	cmd = t.v_type == V_STR ? t.v_str : 0;
143 	if ((*(token == T_ASSIGN ? p_assign : p_function))(cmd, &t, flag) < 0) {
144 		if (cmd)
145 			str_free(cmd);
146 		return -1;
147 	}
148 	if (cmd)
149 		str_free(cmd);
150 	val_free(t);
151 	if (token == T_EOL)
152 		(void) s_gettok();
153 	else if (token != T_EOF) {
154 		p_synerror();
155 		return -1;
156 	}
157 	return 0;
158 }
159 
160 p_convstr(v)
161 register struct value *v;
162 {
163 	if (v->v_type != V_NUM)
164 		return 0;
165 	if ((v->v_str = str_itoa(v->v_num)) == 0) {
166 		p_memerror();
167 		v->v_type = V_ERR;
168 		return -1;
169 	}
170 	v->v_type = V_STR;
171 	return 0;
172 }
173 
174 p_synerror()
175 {
176 	if (!cx.x_synerred) {
177 		cx.x_synerred = cx.x_erred = 1;
178 		error("Syntax error.");
179 	}
180 }
181 
182 /*VARARGS1*/
183 p_error(msg, a, b, c)
184 char *msg;
185 {
186 	if (!cx.x_erred) {
187 		cx.x_erred = 1;
188 		error(msg, a, b, c);
189 	}
190 }
191 
192 p_memerror()
193 {
194 	cx.x_erred = cx.x_abort = 1;
195 	error("Out of memory.");
196 }
197