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