%{
/*---------------------------------------------------------------------------*
  Project:  NitroSDK - tools - makelcf
  File:     tlcf.y

  Copyright 2003,2004 Nintendo.  All rights reserved.

  These coded instructions, statements, and computer programs contain
  proprietary information of Nintendo of America Inc. and/or Nintendo
  Company Ltd., and are protected by Federal copyright law.  They may
  not be disclosed to third parties or copied or duplicated in any form,
  in whole or in part, without the prior written consent of Nintendo.

  $Log: tlcf.y,v $
  Revision 1.10  2004/07/10 04:06:17  yasu
  Support command 'Library'
  Support modifier ':x' on template
  Fix up line continue '\'

  Revision 1.9  2004/07/02 07:34:53  yasu
  Support OBJECT( )

  Revision 1.8  2004/06/24 07:18:54  yasu
  Support keyword "Autoload"

  Revision 1.7  2004/06/14 11:28:45  yasu
  support section filter "FOREACH.STATIC.OBJECTS=.sectionName"

  Revision 1.6  2004/02/13 07:13:03  yasu
  support SDK_IRQ_STACKSIZE

  Revision 1.5  2004/02/05 07:09:03  yasu
  change SDK prefix iris -> nitro

  Revision 1.4  2004/01/15 10:47:56  yasu
  Mount Static StackSize

  Revision 1.3  2004/01/14 12:38:08  yasu
  Change OverlayName->OverlayDefs

  Revision 1.2  2004/01/07 13:10:17  yasu
  fix all warning at compile -Wall

  Revision 1.1  2004/01/05 02:32:59  yasu
  Initial version

  $NoKeywords: $
 *---------------------------------------------------------------------------*/
#include	<stdio.h>
#include	"makelcf.h"

tTokenBuffer		tokenBuffer[TOKEN_LEN];
int			tokenBufferEnd = 0;
static  tLoopStack	loop_stack[LOOP_STACK_MAX];
static	int		loop_stack_level = 0;

static BOOL  StoreToken( int id, const char *str )
{
	if ( tokenBufferEnd >= TOKEN_LEN )
	{
		tlcf_yyerror( "Out of token buffer" );
		return FALSE;
	}
	tokenBuffer[tokenBufferEnd].id     = id;
	tokenBuffer[tokenBufferEnd].string = str;
	tokenBufferEnd ++;
	return TRUE;
}

static BOOL  PushLoopStack( int id, const char* sectionName )
{
	if ( loop_stack_level >= LOOP_STACK_MAX )
	{
		tlcf_yyerror( "Out of stack level" );
		return FALSE;
	}
	loop_stack[loop_stack_level].id    = id;
	loop_stack[loop_stack_level].start = tokenBufferEnd;
	loop_stack_level ++;
	return StoreToken( id, sectionName );
}

static BOOL  PopLoopStack( int id )
{
	int start;
	
	loop_stack_level --;
	if ( loop_stack_level < 0 || id != loop_stack[loop_stack_level].id )
	{
		tlcf_yyerror( "Unmatched foreach-end" );
		return FALSE;
	}
	start = loop_stack[loop_stack_level].start;
	tokenBuffer[start].loop_end = tokenBufferEnd-1;
	
	// Don't store 'END' token to TokenBuffer
	return TRUE;
}

BOOL  GetLoopStackLevel( void )
{
	return loop_stack_level;
}


%}

%token	tSTATIC_NAME
%token	tSTATIC_ADDRESS
%token	tSTATIC_OBJECT
%token	tSTATIC_STACKSIZE
%token	tSTATIC_IRQSTACKSIZE
%token	tFOREACH_STATIC_OBJECTS
%token	tEND_STATIC_OBJECTS
%token	tFOREACH_STATIC_LIBRARIES
%token	tEND_STATIC_LIBRARIES

%token	tAUTOLOAD_ID
%token	tAUTOLOAD_NAME
%token	tAUTOLOAD_ADDRESS
%token	tAUTOLOAD_OBJECT
%token	tNUMBER_AUTOLOADS
%token	tFOREACH_AUTOLOADS
%token	tEND_AUTOLOADS
%token	tFOREACH_AUTOLOAD_OBJECTS
%token	tEND_AUTOLOAD_OBJECTS
%token	tFOREACH_AUTOLOAD_LIBRARIES
%token	tEND_AUTOLOAD_LIBRARIES

%token	tOVERLAY_ID
%token	tOVERLAY_NAME
%token	tOVERLAY_ADDRESS
%token	tOVERLAY_OBJECT
%token	tNUMBER_OVERLAYS
%token	tFOREACH_OVERLAYS
%token	tEND_OVERLAYS
%token	tFOREACH_OVERLAY_OBJECTS
%token	tEND_OVERLAY_OBJECTS
%token	tFOREACH_OVERLAY_LIBRARIES
%token	tEND_OVERLAY_LIBRARIES

%token	tPROPERTY_OVERLAYDEFS
%token	tPROPERTY_OVERLAYTABLE
%token	tPROPERTY_SURFFIX

%union
{
	char	*string;
};

%token	<string>	tSTRING
%token	<string>	tSTATIC_OBJECT
%token	<string>	tSTATIC_LIBRARY
%token	<string>	tFOREACH_STATIC_OBJECTS
%token	<string>	tFOREACH_STATIC_LIBRARIES
%token	<string>	tAUTOLOAD_OBJECT
%token	<string>	tAUTOLOAD_LIBRARY
%token	<string>	tFOREACH_AUTOLOAD_OBJECTS
%token	<string>	tFOREACH_AUTOLOAD_LIBRARIES
%token	<string>	tOVERLAY_OBJECT
%token	<string>	tOVERLAY_LIBRARY
%token	<string>	tFOREACH_OVERLAY_OBJECTS
%token	<string>	tFOREACH_OVERLAY_LIBRARIES
%%

/*=========================================================================*
      ConfigFile
 *=========================================================================*/

tlcfFile	: tokens
		;

tokens		: /*NULL*/
		| tokens token
		;

token		: tSTRING			{ if (!StoreToken( tSTRING,                $1   )) YYABORT; }
		| tSTATIC_NAME			{ if (!StoreToken( tSTATIC_NAME,           NULL )) YYABORT; }
		| tSTATIC_ADDRESS		{ if (!StoreToken( tSTATIC_ADDRESS,        NULL )) YYABORT; }
		| tSTATIC_OBJECT		{ if (!StoreToken( tSTATIC_OBJECT,         $1   )) YYABORT; }
		| tSTATIC_LIBRARY		{ if (!StoreToken( tSTATIC_LIBRARY,        $1   )) YYABORT; }
		| tSTATIC_STACKSIZE		{ if (!StoreToken( tSTATIC_STACKSIZE,      NULL )) YYABORT; }
		| tSTATIC_IRQSTACKSIZE		{ if (!StoreToken( tSTATIC_IRQSTACKSIZE,   NULL )) YYABORT; }
		| tFOREACH_STATIC_OBJECTS	{ if (!PushLoopStack( tFOREACH_STATIC_OBJECTS, $1   )) YYABORT; }
		| tEND_STATIC_OBJECTS    	{ if (!PopLoopStack ( tFOREACH_STATIC_OBJECTS       )) YYABORT; }
		| tFOREACH_STATIC_LIBRARIES	{ if (!PushLoopStack( tFOREACH_STATIC_LIBRARIES, $1 )) YYABORT; }
		| tEND_STATIC_LIBRARIES    	{ if (!PopLoopStack ( tFOREACH_STATIC_LIBRARIES     )) YYABORT; }
		| tAUTOLOAD_ID			{ if (!StoreToken( tAUTOLOAD_ID,           NULL )) YYABORT; }
		| tAUTOLOAD_NAME		{ if (!StoreToken( tAUTOLOAD_NAME,         NULL )) YYABORT; }
		| tAUTOLOAD_ADDRESS		{ if (!StoreToken( tAUTOLOAD_ADDRESS,      NULL )) YYABORT; }
		| tAUTOLOAD_OBJECT		{ if (!StoreToken( tAUTOLOAD_OBJECT,       $1   )) YYABORT; }
		| tAUTOLOAD_LIBRARY		{ if (!StoreToken( tAUTOLOAD_LIBRARY,      $1   )) YYABORT; }
		| tNUMBER_AUTOLOADS		{ if (!StoreToken( tNUMBER_AUTOLOADS,      NULL )) YYABORT; }
		| tFOREACH_AUTOLOADS		{ if (!PushLoopStack( tFOREACH_AUTOLOADS, NULL      )) YYABORT; }
		| tEND_AUTOLOADS		{ if (!PopLoopStack ( tFOREACH_AUTOLOADS            )) YYABORT; }
		| tFOREACH_AUTOLOAD_OBJECTS	{ if (!PushLoopStack( tFOREACH_AUTOLOAD_OBJECTS, $1 )) YYABORT; }
		| tEND_AUTOLOAD_OBJECTS		{ if (!PopLoopStack ( tFOREACH_AUTOLOAD_OBJECTS     )) YYABORT; }
		| tFOREACH_AUTOLOAD_LIBRARIES	{ if (!PushLoopStack( tFOREACH_AUTOLOAD_LIBRARIES, $1 )) YYABORT; }
		| tEND_AUTOLOAD_LIBRARIES	{ if (!PopLoopStack ( tFOREACH_AUTOLOAD_LIBRARIES     )) YYABORT; }
		| tOVERLAY_ID			{ if (!StoreToken( tOVERLAY_ID,            NULL )) YYABORT; }
		| tOVERLAY_NAME			{ if (!StoreToken( tOVERLAY_NAME,          NULL )) YYABORT; }
		| tOVERLAY_ADDRESS		{ if (!StoreToken( tOVERLAY_ADDRESS,       NULL )) YYABORT; }
		| tOVERLAY_OBJECT		{ if (!StoreToken( tOVERLAY_OBJECT,        $1   )) YYABORT; }
		| tOVERLAY_LIBRARY		{ if (!StoreToken( tOVERLAY_LIBRARY,       $1   )) YYABORT; }
		| tNUMBER_OVERLAYS		{ if (!StoreToken( tNUMBER_OVERLAYS,       NULL )) YYABORT; }
		| tFOREACH_OVERLAYS		{ if (!PushLoopStack( tFOREACH_OVERLAYS, NULL      )) YYABORT; }
		| tEND_OVERLAYS			{ if (!PopLoopStack ( tFOREACH_OVERLAYS            )) YYABORT; }
		| tFOREACH_OVERLAY_OBJECTS	{ if (!PushLoopStack( tFOREACH_OVERLAY_OBJECTS, $1 )) YYABORT; }
		| tEND_OVERLAY_OBJECTS		{ if (!PopLoopStack ( tFOREACH_OVERLAY_OBJECTS     )) YYABORT; }
		| tFOREACH_OVERLAY_LIBRARIES	{ if (!PushLoopStack( tFOREACH_OVERLAY_LIBRARIES, $1 )) YYABORT; }
		| tEND_OVERLAY_LIBRARIES	{ if (!PopLoopStack ( tFOREACH_OVERLAY_LIBRARIES     )) YYABORT; }
		| tPROPERTY_OVERLAYDEFS		{ if (!StoreToken( tPROPERTY_OVERLAYDEFS,  NULL )) YYABORT; }
		| tPROPERTY_OVERLAYTABLE	{ if (!StoreToken( tPROPERTY_OVERLAYTABLE, NULL )) YYABORT; }
		| tPROPERTY_SURFFIX		{ if (!StoreToken( tPROPERTY_SURFFIX,      NULL )) YYABORT; }
		;
%%
