1139969Simp/*	$NetBSD: parser3.c,v 1.5 2002/06/14 01:06:54 wiz Exp $	*/
21556Srgrimes
31556Srgrimes/*
41556Srgrimes * Copyright (c) 1983, 1993
51556Srgrimes *	The Regents of the University of California.  All rights reserved.
61556Srgrimes *
71556Srgrimes * This code is derived from software contributed to Berkeley by
81556Srgrimes * Edward Wang at The University of California, Berkeley.
91556Srgrimes *
101556Srgrimes * Redistribution and use in source and binary forms, with or without
111556Srgrimes * modification, are permitted provided that the following conditions
121556Srgrimes * are met:
131556Srgrimes * 1. Redistributions of source code must retain the above copyright
141556Srgrimes *    notice, this list of conditions and the following disclaimer.
151556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
161556Srgrimes *    notice, this list of conditions and the following disclaimer in the
171556Srgrimes *    documentation and/or other materials provided with the distribution.
181556Srgrimes * 3. Neither the name of the University nor the names of its contributors
191556Srgrimes *    may be used to endorse or promote products derived from this software
201556Srgrimes *    without specific prior written permission.
211556Srgrimes *
221556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
231556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
241556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
251556Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
261556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
271556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
281556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
291556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
301556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
311556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
321556Srgrimes * SUCH DAMAGE.
331556Srgrimes */
3427958Ssteve
351556Srgrimes#include <sys/cdefs.h>
361556Srgrimes#ifndef lint
3727967Ssteve#if 0
3827967Sstevestatic char sccsid[] = "@(#)parser3.c	8.1 (Berkeley) 6/6/93";
3990153Smarkm#else
4027967Ssteve__RCSID("$NetBSD: parser3.c,v 1.5 2002/06/14 01:06:54 wiz Exp $");
4127967Ssteve#endif
4290153Smarkm#endif /* not lint */
4327967Ssteve
4499109Sobrien#include "defs.h"
4599109Sobrien#include "parser.h"
461556Srgrimes
471556Srgrimes/*
481556Srgrimes * =
491556Srgrimes * ? :
50105832Srwatson * ||
511556Srgrimes * &&
521556Srgrimes * |
531556Srgrimes * ^
541556Srgrimes * &
551556Srgrimes * == !=
5690878Simp * <= >=
57114583Smarkm * << >>
5850050Ssheldonh * + -
5950050Ssheldonh * * / %
6090878Simp * unary - + ~ !
611556Srgrimes */
621556Srgrimesint
631556Srgrimesp_expr(struct value *v, char flag)
6461289Sache{
6561268Sjoe	struct value t;
6661289Sache	int ret;
6761289Sache
6861268Sjoe	if (p_expr0(&t, flag) < 0)
691556Srgrimes		return -1;
701556Srgrimes
711556Srgrimes	if (token != T_ASSIGN) {
721556Srgrimes		*v = t;
7350050Ssheldonh		return 0;
7450050Ssheldonh	}
7550050Ssheldonh	switch (t.v_type) {
7650050Ssheldonh	case V_NUM:
7750050Ssheldonh		p_error("%d: Not a variable.", t.v_num);
7850051Ssheldonh	case V_ERR:
7950050Ssheldonh		t.v_str = 0;
80114583Smarkm		break;
81114583Smarkm	}
82114583Smarkm	ret = p_assign(t.v_str, v, flag);
83114583Smarkm	if (t.v_str != 0)
84114583Smarkm		str_free(t.v_str);
85114583Smarkm	return ret;
86114583Smarkm}
87114583Smarkm
88114583Smarkm/*
89114583Smarkm * ? :
90114583Smarkm */
91114583Smarkmint
92114583Smarkmp_expr0(struct value *v, char flag)
93114583Smarkm{
94114583Smarkm	struct value t;
95114583Smarkm	char true = 0;
96103726Swollman
9790110Simp	if (p_expr1(v, flag) < 0)
981556Srgrimes		return -1;
99114583Smarkm	if (token != T_QUEST)
10090110Simp		return 0;
1011556Srgrimes	switch (v->v_type) {
1021556Srgrimes	case V_NUM:
1031556Srgrimes		true = v->v_num != 0;
1041556Srgrimes		break;
1051556Srgrimes	case V_STR:
10690150Smarkm		p_error("?: Numeric left operand required.");
10790150Smarkm		str_free(v->v_str);
10890150Smarkm		v->v_type = V_ERR;
10990150Smarkm	case V_ERR:
11090150Smarkm		flag = 0;
11190150Smarkm		break;
11290150Smarkm	}
113152469Sru	(void) s_gettok();
11490150Smarkm	v->v_type = V_ERR;
11590150Smarkm	if ((flag && true ? p_expr1(v, 1) : p_expr1(&t, 0)) < 0)
11690150Smarkm		return -1;
11790150Smarkm	if (token != T_COLON) {
11890150Smarkm		val_free(*v);
11990150Smarkm		p_synerror();
12090150Smarkm		return -1;
12190150Smarkm	}
12290150Smarkm	(void) s_gettok();
12390150Smarkm	return flag && !true ? p_expr1(v, 1) : p_expr1(&t, 0);
12490150Smarkm}
12590150Smarkm
12696892Stjr/*
12796892Stjr * ||
12890150Smarkm */
129114583Smarkmint
13090150Smarkmp_expr1(struct value *v, char flag)
131146924Sdd{
13290150Smarkm	char true = 0;
13390150Smarkm
134105832Srwatson	if (p_expr2(v, flag) < 0)
13561268Sjoe		return -1;
13690150Smarkm	if (token != T_OROR)
13761271Sjoe		return 0;
13861271Sjoe	for (;;) {
13961271Sjoe		switch (v->v_type) {
14061271Sjoe		case V_NUM:
14188583Sjoe			v->v_num = true = true || v->v_num != 0;
14288583Sjoe			break;
14361268Sjoe		case V_STR:
1441556Srgrimes			p_error("||: Numeric operands required.");
14590150Smarkm			str_free(v->v_str);
14617852Sadam			v->v_type = V_ERR;
1471556Srgrimes		case V_ERR:
14890110Simp			flag = 0;
1491556Srgrimes			break;
15088602Sjoe		}
1511556Srgrimes		if (token != T_OROR)
1521556Srgrimes			return 0;
1531556Srgrimes		(void) s_gettok();
15461271Sjoe		if (p_expr2(v, flag && !true) < 0)
15588602Sjoe			return -1;
15688602Sjoe	}
15761271Sjoe}
15861271Sjoe
15961271Sjoe/*
16088602Sjoe * &&
16111808Sache */
1621556Srgrimesint
1631556Srgrimesp_expr2(struct value *v, char flag)
16497803Stjr{
16597803Stjr	char true = 1;
16697803Stjr
16797803Stjr	if (p_expr3_10(3, v, flag) < 0)
16897803Stjr		return -1;
1691556Srgrimes	if (token != T_ANDAND)
17090150Smarkm		return 0;
1715158Sjoerg	for (;;) {
1721556Srgrimes		switch (v->v_type) {
1735158Sjoerg		case V_NUM:
17490150Smarkm			v->v_num = true = true && v->v_num != 0;
17590150Smarkm			break;
1765158Sjoerg		case V_STR:
1775158Sjoerg			p_error("&&: Numeric operands required.");
1781556Srgrimes			str_free(v->v_str);
1791556Srgrimes			v->v_type = V_ERR;
180146924Sdd		case V_ERR:
181152256Smux			flag = 0;
1821556Srgrimes			break;
1831556Srgrimes		}
18496892Stjr		if (token != T_ANDAND)
18596892Stjr			return 0;
1861556Srgrimes		(void) s_gettok();
1871556Srgrimes		if (p_expr3_10(3, v, flag && true) < 0)
1881556Srgrimes			return -1;
18990150Smarkm	}
19096892Stjr	/*NOTREACHED*/
1911556Srgrimes}
19235417Sdes