xref: /csrg-svn/usr.bin/window/parser5.c (revision 16714)
115853Sedward #ifndef lint
2*16714Sedward static char sccsid[] = "@(#)parser5.c	3.7 07/13/84";
315853Sedward #endif
415853Sedward 
515853Sedward #include "parser.h"
615864Sedward #include "var.h"
715853Sedward 
815853Sedward /*
9*16714Sedward  * unary $ $? + - ! ~
1015853Sedward  */
1115853Sedward p_expr11(v, flag)
1215853Sedward register struct value *v;
1315853Sedward char flag;
1415853Sedward {
1515853Sedward 	int op;
1615853Sedward 	char *opname;
1715853Sedward 
1815853Sedward 	switch (token) {
1915853Sedward 	case T_DOLLAR:
2015853Sedward 		opname = "$";
2115853Sedward 		break;
22*16714Sedward 	case T_DQ:
23*16714Sedward 		opname = "$?";
24*16714Sedward 		break;
2515853Sedward 	case T_PLUS:
2615853Sedward 		opname = "unary +";
2715853Sedward 		break;
2815853Sedward 	case T_MINUS:
2915853Sedward 		opname = "unary -";
3015853Sedward 		break;
3115853Sedward 	case T_NOT:
3215853Sedward 		opname = "!";
3315853Sedward 		break;
3415853Sedward 	case T_COMP:
3515853Sedward 		opname = "~";
3615853Sedward 		break;
3715853Sedward 	default:
3815853Sedward 		return p_expr12(v, flag);
3915853Sedward 	}
4015853Sedward 	op = token;
4115853Sedward 	(void) s_gettok();
4215853Sedward 	if (p_expr11(v, flag) < 0)
4315853Sedward 		return -1;
4415853Sedward 	switch (v->v_type) {
4515853Sedward 	case V_NUM:
4615853Sedward 		break;
4715853Sedward 	case V_STR:
4815853Sedward 		switch (op) {
4915853Sedward 		case T_MINUS:
5015853Sedward 		case T_NOT:
5115853Sedward 		case T_COMP:
52*16714Sedward 			p_error("%s: Numeric operand required.", opname);
5315853Sedward 			str_free(v->v_str);
5415853Sedward 			v->v_type = V_ERR;
5515853Sedward 			return 0;
5615853Sedward 		}
5715853Sedward 		break;
5815853Sedward 	case V_ERR:
5915853Sedward 		return 0;
6015853Sedward 	}
6115853Sedward 	switch (op) {
62*16714Sedward 	case T_DOLLAR:
63*16714Sedward 	case T_DQ:
6416449Sedward 		if (v->v_type == V_NUM) {
65*16714Sedward 			int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
66*16714Sedward 				v->v_num > 0 && v->v_num <= cx.x_narg;
67*16714Sedward 			if (op == T_DQ)
68*16714Sedward 				v->v_num = tmp;
69*16714Sedward 			else if (tmp)
70*16714Sedward 				*v = cx.x_arg[v->v_num - 1];
71*16714Sedward 			else {
7216449Sedward 				p_error("%d: No such argument.", v->v_num);
7316449Sedward 				v->v_type = V_ERR;
7416449Sedward 			}
7516449Sedward 		} else {
76*16714Sedward 			char *name = v->v_str;
77*16714Sedward 			struct var *r = var_lookup(name);
78*16714Sedward 			if (op == T_DQ) {
79*16714Sedward 				v->v_type = V_NUM;
80*16714Sedward 				v->v_num = r != 0;
81*16714Sedward 			} else if (r != 0)
82*16714Sedward 				*v = r->r_val;
83*16714Sedward 			else {
84*16714Sedward 				p_error("%s: Undefined variable.", name);
8516449Sedward 				v->v_type = V_ERR;
8616449Sedward 			}
87*16714Sedward 			str_free(name);
8815853Sedward 		}
89*16714Sedward 		if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
9016449Sedward 			p_memerror();
9116449Sedward 			return -1;
9215853Sedward 		}
9315853Sedward 		break;
9415853Sedward 	case T_MINUS:
9515853Sedward 		v->v_num = - v->v_num;
9615853Sedward 		break;
9715853Sedward 	case T_NOT:
9815853Sedward 		v->v_num = ! v->v_num;
9915853Sedward 		break;
10015853Sedward 	case T_COMP:
10115853Sedward 		v->v_num = ~ v->v_num;
10215853Sedward 		break;
10315853Sedward 	}
10415853Sedward 	return 0;
10515853Sedward }
10615853Sedward 
10715853Sedward /*
10815853Sedward  * string, number, ( expr )
10915853Sedward  * Plus function calls.
11015853Sedward  * Also we map % into string.
11115853Sedward  *
11215853Sedward  * Always return v_type == V_ERR when flag == 0.
11315853Sedward  */
11415853Sedward p_expr12(v, flag)
11515853Sedward register struct value *v;
11615853Sedward char flag;
11715853Sedward {
11815853Sedward 	v->v_type = V_ERR;
11915853Sedward 	switch (token) {
12015853Sedward 	case T_MOD:
12115853Sedward 		if (flag) {
12215853Sedward 			v->v_type = V_STR;
12315853Sedward 			v->v_str = str_cpy("%");
12415853Sedward 		}
12515853Sedward 		(void) s_gettok();
12615853Sedward 		break;
12715853Sedward 	case T_NUM:
12815853Sedward 		if (flag) {
12915853Sedward 			v->v_type = V_NUM;
13015853Sedward 			v->v_num = token_num;
13115853Sedward 		}
13215853Sedward 		(void) s_gettok();
13315853Sedward 		break;
13415853Sedward 	case T_STR:
13515853Sedward 		if (flag) {
13615853Sedward 			v->v_type = V_STR;
13715853Sedward 			v->v_str = token_str;
13815853Sedward 		} else
13915853Sedward 			str_free(token_str);
14015853Sedward 		(void) s_gettok();
14115853Sedward 		break;
14215853Sedward 	case T_LP:
14315853Sedward 		(void) s_gettok();
14415853Sedward 		if (p_expr(v, flag) < 0) {
14515853Sedward 			p_synerror();
14615853Sedward 			return -1;
14715853Sedward 		}
14815853Sedward 		if (token != T_RP) {
14915853Sedward 			p_synerror();
15015853Sedward 			val_free(*v);
15115853Sedward 			return -1;
15215853Sedward 		}
15315853Sedward 		(void) s_gettok();
15415853Sedward 		break;
15515853Sedward 	default:
15615853Sedward 		return -1;
15715853Sedward 	}
15815853Sedward 	while (token == T_LP) {
15915853Sedward 		char *cmd;
16015853Sedward 
16115853Sedward 		(void) s_gettok();
16216449Sedward 		if (p_convstr(v) < 0)
16316449Sedward 			return -1;
16416449Sedward 		cmd = v->v_type == V_STR ? v->v_str : 0;
16515853Sedward 		if (p_function(cmd, v, flag) < 0) {
16616298Sedward 			if (cmd)
16716298Sedward 				str_free(cmd);
16815853Sedward 			return -1;
16915853Sedward 		}
17016298Sedward 		if (cmd)
17116298Sedward 			str_free(cmd);
17215853Sedward 		if (token != T_RP) {
17315853Sedward 			p_synerror();
17415853Sedward 			val_free(*v);
17515853Sedward 			return -1;
17615853Sedward 		}
17715853Sedward 		(void) s_gettok();
17815853Sedward 	}
17915853Sedward 	return 0;
18015853Sedward }
181