/*
    Clif - A C-like Interpreter Framework
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 T. Hruz, L. Koren

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    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 the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

/* 
 * channel_y
 *
 * grammar for channel compiler
 */
%union {
	int myint;
	double mydouble;
	char *mystring;
	}
%token <myint> NUMBERI 		/* integer constant */
%token <mydouble> NUMBERD 	/* double constant */
%token <mystring> STRING
%token FIELDS TYPE PRINT_FORMAT DIRECTION START_TIME DURATION_TIME 
%token W_RESOLUTION LOWER UPPER STYLE AUTOMATIC ON_LEAVE_WINDOW
%start list_stat_0

	/* precedence information about the operators */
%right '='
%{
#include "global.h"
#include "mystdio.h"
#include "channel_maint.h"
#include "allocx.h"
#include "printfx.h"

int yylex PROTO((void));
char *string PROTO((char *));
int yyerror PROTO((char *));

int yyerror(s)
    char *s;
{
   return(0);;
}
%}
%% /* beginnig of rules section */

list_stat_0 : list_stat_0  stat_0

	    |
	    ;

stat_0 : FIELDS '=' NUMBERI
		{int cnt;
		 /* 
	 	  * Defaults filling
	 	  * FIELDS must be specified 
	 	  */
		 channel[channel_handle].fields = $3;
		 if (channel[channel_handle].fields > 0)
		   {
		     channel[channel_handle].cnt = 0;
		     channel[channel_handle].global_cnt = 0;
		     channel[channel_handle].w_resolution[0] = 256;
		     channel[channel_handle].w_resolution[1] = 256;
		     channel[channel_handle].start_time = 0.;
		     channel[channel_handle].s_time = 0;
		     channel[channel_handle].duration_time = 1000.;
		     channel[channel_handle].d_time = 0.;
		     channel[channel_handle].print_format = string ("line");
		     channel[channel_handle].type = string ("graphic");
		     channel[channel_handle].on_leave_w = string ("noevent");
		     channel[channel_handle].list = 
		       (struct LIST *)allocate (sizeof (struct LIST), PERM);
		     channel[channel_handle].list_tmp = 
		       (struct LIST *)allocate (sizeof (struct LIST), PERM);
		     channel[channel_handle].member =
		       (struct FIELD *)allocate (channel[channel_handle].fields 
						 * sizeof (struct FIELD), PERM);
		     for (cnt = 0; cnt < channel[channel_handle].fields; cnt++)
		       {
			 channel[channel_handle].member[cnt].style = 0xffffffL;
			 channel[channel_handle].member[cnt].upper = 1;
			 channel[channel_handle].member[cnt].lower = -1;
			}}}

	| TYPE '=' STRING
		{
#if 0
		  free (channel[channel_handle].type);
#endif
		  channel[channel_handle].type = $3;}

	| PRINT_FORMAT '=' STRING
		{
#if 0
		  free (channel[channel_handle].print_format);
#endif
		  channel[channel_handle].print_format = $3;}

	| ON_LEAVE_WINDOW '=' STRING
		{
#if 0
		  free (channel[channel_handle].on_leave_w);
#endif
		  channel[channel_handle].on_leave_w = $3;}

	| DIRECTION '=' STRING
		{if (0 == (strcmp ($3, "input")))
		   channel[channel_handle].direction = 0;
		 else
		   {
		     if (0 == (strcmp ($3, "output")))
		       channel[channel_handle].direction = 1;
		     else
		       {
			 fprintfx (stderr, "bad direction\n");
			 exit (0);
			}
		}}

	| START_TIME '=' s_time

	| DURATION_TIME '=' d_time

	| W_RESOLUTION '=' NUMBERI NUMBERI
		{channel[channel_handle].w_resolution[0] = $3; channel[channel_handle].w_resolution[1] = $4;}

	| LOWER '(' NUMBERI ')' '=' NUMBERD
		{if (channel[channel_handle].fields > $3)
		   channel[channel_handle].member[$3].lower = $6;
		 else
		   {
		     fprintfx (stderr, "invalid subscript\n");
		     exit (0);
		   }}

	| UPPER '(' NUMBERI ')' '=' NUMBERD
		{if (channel[channel_handle].fields > $3)
		   channel[channel_handle].member[$3].upper = $6;
		 else
		   {
		     fprintfx (stderr, "invalid subscript\n");
		     exit (0);
		   }}

	| STYLE '(' NUMBERI ')' '=' NUMBERI
		{if (channel[channel_handle].fields > $3)
		   channel[channel_handle].member[$3].style=(unsigned long)$6;
		 else
		   {
		     fprintfx (stderr,"invalid subscript\n");
		     exit (0);
		   }}

	| error
		{fprintfx (stderr,"error in opening channel\n"); return (-2);}

	;

d_time : NUMBERD 
		{channel[channel_handle].duration_time = $1; channel[channel_handle].d_time = 0.;}

	| AUTOMATIC
		{channel[channel_handle].duration_time = 16.; channel[channel_handle].d_time = 1.;}

	;

s_time : NUMBERD
		{channel[channel_handle].start_time = $1; channel[channel_handle].s_time = 0;}

	| AUTOMATIC
		{channel[channel_handle].s_time = 1;}

	;

%%
