/*
 *  dsppp_b.y from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
%{
#ifdef __NT_VC__
#include <malloc.h>
#endif
#include <stream.h>
#include "portable.h"
#include "yacintfc.h"
#include "prsdrv.h"
#include "cgidbg.h"
#include "sco_alloca.h"
#define YYDEBUG 1
%}
%union {
	int32 Int ;
	double Float ;
	const char * Name ;
	struct ValueType * Value ;
	} 
%token IF ELSE NET_EDIT_COMMAND
%token <Name> NAME STRING
%token <Int> INTEGER MENU STATIC
%token <Float> FLOATING 
%token <Value> DECL DECL_NAME
%type <Value> Expression Primary Number Variable Name DeclaredName 
%type <Value> ParameterList Declaration DeclObj Lvalue DeclaredLvalue LegalName
%type <Value> String Initiator NonEmptyParameterList Initializer
%right '=' PLUS_EQUAL MINUS_EQUAL 
%left '?' ':'
%left OR
%left AND
%left '|'
%left '^'
%left '&'
%left EQU NEQ
%left '<' '>' LEQ GEQ
%left SHIFT_R SHIFT_L
%left '+' '-'
%left '*' '/' '%'
%left '.' ARROW
%%

ProgramStatement : NET_EDIT_COMMAND CompletedStatement
	
	| CompletedStatement

CompletedStatement : Conditional ';'	{YYACCEPT;}
	| Statement ';'			{NotConditional(); YYACCEPT;}
	| ';'				{NotConditional(); YYACCEPT;}

Statement : Expression 		{/* prevents type clash warning */;}
	| Declaration 			{/* prevents type clash warning */;}
	| Initializer 			{/* prevents type clash warning */;}
	| error 
	| MENU					{/* prevents type clash warning */;}
	| Expression MENU 		{/* prevents type clash warning */;}
	| Declaration MENU 		{/* prevents type clash warning */;}
	| error MENU 			{/* prevents type clash warning */;}

Expression : Lvalue '=' Expression		{ $$=Equal($1,$3); }
	| Lvalue PLUS_EQUAL Expression		{ $$=Equal($1,$3,'+'); }
	| Lvalue MINUS_EQUAL Expression		{ $$=Equal($1,$3,'-'); }
	| Expression '%' Expression		{ $$=BinOp($1,'%',$3); } 
	| Expression '/' Expression		{ $$=BinOp($1,'/',$3); } 
	| Expression '*' Expression		{ $$=BinOp($1,'*',$3); }	
	| Expression '+' Expression		{ $$=BinOp($1,'+',$3); }
	| Expression '-' Expression		{ $$=BinOp($1,'-',$3); } 
	| Expression SHIFT_R Expression		{ $$=BinOp($1,SHIFT_R,$3); }	
	| Expression SHIFT_L Expression		{ $$=BinOp($1,SHIFT_L,$3); }	
	| '+' Primary			%prec '*' {$$ = $2 ;}
	| '-' Primary			%prec '*' {$$ = UnOp('-',$2);}
	| '!' Primary			%prec '.' {$$ = UnOp('!',$2);}
	| Primary

Lvalue : Declaration 
	| DeclaredLvalue
	| LegalName			{$$=DoDeclareLval($1);}

DeclaredLvalue : DECL_NAME			

Primary : Variable
	| Number				
	| '(' Expression ')'			{ $$ = $2 ; }
	| String

Variable : DeclaredName
	| Variable '(' ParameterList ')'	{ $$ = DoProcedure($1,$3);}
	| Variable '[' NonEmptyParameterList ']' 	{ $$ = SelectArrayElement(
							$1,$3);}
	| Variable '.' LegalName		{$$=MemberRef($1,$3);}
	| Variable ARROW LegalName

DeclaredName : DECL_NAME		{$$=InsureValueExists($1);}
	| LegalName			{$$=DoDeclare($1);}

NonEmptyParameterList : Expression 		{$$ = DoParameter($1);}

	| ParameterList ',' Expression	{$$ = DoParameterList($1,$3);}

ParameterList : NonEmptyParameterList 

	|				{$$ = new ValueType(DecParam,
						new ParameterList);}

IfExpression : IF '(' Expression ')' 	{IfPush($3);}

Conditional : IfExpression Statement 	{IfPartEnd();}

	| Else Statement		{IfPop();}

Else : ELSE				{Else();}

Number : INTEGER			{$$ = MakeIntValue($1);}

	| FLOATING				{$$ = MakeFloatValue($1);}

String : STRING				{$$ = ReturnStringValue($1);}

Declaration : Declaration ',' DeclObj	{$$ = CommaDeclare($1,$3);}
	| Ignore DECL DeclObj		{$$ = Declare($2,$3);} 
	| Ignore DECL '&' DeclObj	{SemanticError(ErrorSimpleDeclare);}

Initializer : Ignore DECL Name '[' ']'  '=' Initiator
                    {$$ = DeclarePtr($2,$3,$7);}

Ignore : STATIC 	{/* prevents type clash warning */;}
	|				

Initiator : '{' ParameterList '}'	{$$=$2;}

DeclObj : Name
	| Name '(' ParameterList ')'	{$$ = NameOfList($1,$3);}
	| Name '[' NonEmptyParameterList ']'	{$$ = SetArraySize($1,$3);}

Name : LegalName 
	| DECL_NAME			{$$ = AlreadyDeclared($1); }

LegalName : NAME 			{$$ = CheckLegal(MakeStringValue($1));}
