xref: /csrg-svn/usr.bin/window/parser5.c (revision 18754)
115853Sedward #ifndef lint
2*18754Sedward static char sccsid[] = "@(#)parser5.c	3.9 04/24/85";
315853Sedward #endif
415853Sedward 
5*18754Sedward /*
6*18754Sedward  * Copyright (c) 1983 Regents of the University of California,
7*18754Sedward  * All rights reserved.  Redistribution permitted subject to
8*18754Sedward  * the terms of the Berkeley Software License Agreement.
9*18754Sedward  */
10*18754Sedward 
1115853Sedward #include "parser.h"
1215864Sedward #include "var.h"
1315853Sedward 
1415853Sedward /*
1516714Sedward  * unary $ $? + - ! ~
1615853Sedward  */
1715853Sedward p_expr11(v, flag)
1815853Sedward register struct value *v;
1915853Sedward char flag;
2015853Sedward {
2115853Sedward 	int op;
2215853Sedward 	char *opname;
2315853Sedward 
2415853Sedward 	switch (token) {
2515853Sedward 	case T_DOLLAR:
2615853Sedward 		opname = "$";
2715853Sedward 		break;
2816714Sedward 	case T_DQ:
2916714Sedward 		opname = "$?";
3016714Sedward 		break;
3115853Sedward 	case T_PLUS:
3215853Sedward 		opname = "unary +";
3315853Sedward 		break;
3415853Sedward 	case T_MINUS:
3515853Sedward 		opname = "unary -";
3615853Sedward 		break;
3715853Sedward 	case T_NOT:
3815853Sedward 		opname = "!";
3915853Sedward 		break;
4015853Sedward 	case T_COMP:
4115853Sedward 		opname = "~";
4215853Sedward 		break;
4315853Sedward 	default:
4415853Sedward 		return p_expr12(v, flag);
4515853Sedward 	}
4615853Sedward 	op = token;
4715853Sedward 	(void) s_gettok();
4815853Sedward 	if (p_expr11(v, flag) < 0)
4915853Sedward 		return -1;
5015853Sedward 	switch (v->v_type) {
5115853Sedward 	case V_NUM:
5215853Sedward 		break;
5315853Sedward 	case V_STR:
5415853Sedward 		switch (op) {
5515853Sedward 		case T_MINUS:
5615853Sedward 		case T_NOT:
5715853Sedward 		case T_COMP:
5816714Sedward 			p_error("%s: Numeric operand required.", opname);
5915853Sedward 			str_free(v->v_str);
6015853Sedward 			v->v_type = V_ERR;
6115853Sedward 			return 0;
6215853Sedward 		}
6315853Sedward 		break;
6415853Sedward 	case V_ERR:
6515853Sedward 		return 0;
6615853Sedward 	}
6715853Sedward 	switch (op) {
6816714Sedward 	case T_DOLLAR:
6916714Sedward 	case T_DQ:
7016449Sedward 		if (v->v_type == V_NUM) {
7116714Sedward 			int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
7216714Sedward 				v->v_num > 0 && v->v_num <= cx.x_narg;
7316714Sedward 			if (op == T_DQ)
7416714Sedward 				v->v_num = tmp;
7516714Sedward 			else if (tmp)
7616714Sedward 				*v = cx.x_arg[v->v_num - 1];
7716714Sedward 			else {
7816449Sedward 				p_error("%d: No such argument.", v->v_num);
7916449Sedward 				v->v_type = V_ERR;
8016449Sedward 			}
8116449Sedward 		} else {
8216714Sedward 			char *name = v->v_str;
8316714Sedward 			struct var *r = var_lookup(name);
8416714Sedward 			if (op == T_DQ) {
8516714Sedward 				v->v_type = V_NUM;
8616714Sedward 				v->v_num = r != 0;
8716714Sedward 			} else if (r != 0)
8816714Sedward 				*v = r->r_val;
8916714Sedward 			else {
9016714Sedward 				p_error("%s: Undefined variable.", name);
9116449Sedward 				v->v_type = V_ERR;
9216449Sedward 			}
9316714Sedward 			str_free(name);
9415853Sedward 		}
9516714Sedward 		if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
9616449Sedward 			p_memerror();
9716449Sedward 			return -1;
9815853Sedward 		}
9915853Sedward 		break;
10015853Sedward 	case T_MINUS:
10115853Sedward 		v->v_num = - v->v_num;
10215853Sedward 		break;
10315853Sedward 	case T_NOT:
10415853Sedward 		v->v_num = ! v->v_num;
10515853Sedward 		break;
10615853Sedward 	case T_COMP:
10715853Sedward 		v->v_num = ~ v->v_num;
10815853Sedward 		break;
10915853Sedward 	}
11015853Sedward 	return 0;
11115853Sedward }
11215853Sedward 
11315853Sedward /*
11415853Sedward  * string, number, ( expr )
11515853Sedward  * Plus function calls.
11615853Sedward  *
11715853Sedward  * Always return v_type == V_ERR when flag == 0.
11815853Sedward  */
11915853Sedward p_expr12(v, flag)
12015853Sedward register struct value *v;
12115853Sedward char flag;
12215853Sedward {
12315853Sedward 	v->v_type = V_ERR;
12415853Sedward 	switch (token) {
12515853Sedward 	case T_NUM:
12615853Sedward 		if (flag) {
12715853Sedward 			v->v_type = V_NUM;
12815853Sedward 			v->v_num = token_num;
12915853Sedward 		}
13015853Sedward 		(void) s_gettok();
13115853Sedward 		break;
13215853Sedward 	case T_STR:
13315853Sedward 		if (flag) {
13415853Sedward 			v->v_type = V_STR;
13515853Sedward 			v->v_str = token_str;
13615853Sedward 		} else
13715853Sedward 			str_free(token_str);
13815853Sedward 		(void) s_gettok();
13915853Sedward 		break;
14015853Sedward 	case T_LP:
14115853Sedward 		(void) s_gettok();
14215853Sedward 		if (p_expr(v, flag) < 0) {
14315853Sedward 			p_synerror();
14415853Sedward 			return -1;
14515853Sedward 		}
14615853Sedward 		if (token != T_RP) {
14715853Sedward 			p_synerror();
14815853Sedward 			val_free(*v);
14915853Sedward 			return -1;
15015853Sedward 		}
15115853Sedward 		(void) s_gettok();
15215853Sedward 		break;
15315853Sedward 	default:
15415853Sedward 		return -1;
15515853Sedward 	}
15615853Sedward 	while (token == T_LP) {
15715853Sedward 		char *cmd;
15815853Sedward 
15916449Sedward 		if (p_convstr(v) < 0)
16016449Sedward 			return -1;
16116449Sedward 		cmd = v->v_type == V_STR ? v->v_str : 0;
16215853Sedward 		if (p_function(cmd, v, flag) < 0) {
16316298Sedward 			if (cmd)
16416298Sedward 				str_free(cmd);
16515853Sedward 			return -1;
16615853Sedward 		}
16716298Sedward 		if (cmd)
16816298Sedward 			str_free(cmd);
16915853Sedward 	}
17015853Sedward 	return 0;
17115853Sedward }
172