/*
 *  mknodel.C from ObjectProDSP
 *  Copyright (C) 1994, 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, librarys and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
#include <stream.h>
#include "mknodelx.h"
#include <string.h>
#include "portable.h"
#include "domknode.h"
#include "lexnum.h"
#include "stdyac.h"
#include "stdyacp.h"
#include "warn.h"
#include "includ.h"

int last_lex_state = 0 ;
void EmbeddedLine() 
{
	cerr << "Newline within one line description at line " << LineNumber <<
		".\n" ;
}


void FoundInt(int32 val)
{
	// cout << "Found integer value " << val << ".\n" ;
}

struct Double * MakeDouble(const char * text)
{
	// cout << "MakeDouble of `" << text << "'\n" ;
	return new Double(FloatConvert(text),MakeLitString(text));
}

enum LexReturnType {LexReturnTerminal=0, LexReturnCode, LexReturnName};

struct LexReservedWords {
	const char * Name ;
	int Terminal ;
	NewStateOption NewState ;
	LexReturnType ReturnType ;
	int ReturnCode ;
	int C_Type ;
	int IsCppType() {return C_Type && C_Type < 3 ;}
};


LexReservedWords TheReservedWords[] = {
	{ "NoDefault",		NO_DEFAULT },
	{ "public",		PUBLIC },
	{ "private",		PRIVATE },
	{ "protected",		PROTECTED },
	{ "operator",		OPERATOR },
	{ "Wait",			WAIT},
	{"HelpDefaultFile", HELP_DEF_FILE},
	{ "ScaledMachWord",	SC_MACH_WORD },
	{ "ScaledAccMachWord",	SC_ACC_MACH_WORD },
	{ "ScaledCxMachWord",	SC_CX_MACH_WORD },
	{ "ScaledCxAccMachWord",SC_CX_ACC_MACH_WORD },
	{ "MachWord",		MACH_WORD, BeginNull, LexReturnTerminal, 0, 2 },
	{ "AccMachWord",	ACC_MACH_WORD, BeginNull, LexReturnTerminal, 0, 2 },
	{ "CxMachWord",		CX_MACH_WORD, BeginNull, LexReturnTerminal, 0, 2 },
	{ "Base",		BASE },
	{ "CxAccMachWord",	CX_ACC_MACH_WORD, BeginNull, LexReturnTerminal, 0, 2 },
	{ "Changeable",		CHANGEABLE },
	{ "NoDefaultInstance",	NO_DEFAULT_INSTANCE },
	{ "FirstDefault",	FIRST_DEFAULT },
	{ "complex",		COMPLEX, BeginNull, LexReturnTerminal, 0, 1 },
	{ "double",		DOUBLE,	 BeginNull, LexReturnTerminal, 0, 1 },
	{ "int",		INT,	 BeginNull, LexReturnTerminal, 0, 1 },
	{ "int16",		INT16,	 BeginNull, LexReturnTerminal, 0, 1 },
	{ "int32",		INT32,	 BeginNull, LexReturnTerminal, 0, 1 },
	{ "void",		VOID,	 BeginNull, LexReturnTerminal, 0, 1 },
	{ "string",		STRING },
	{ "new",		NEW },
	{ "InteractiveEntityList",INTERACTIVE_LIST},
	{ "TheNetworkReference",	NETWORK_REF},
	{ "NetworkStateControl",	NETWORK_STATE},
	{ "Class",		CLASS,			BeginCpp},
	{ "StateEmit",		STATE_EMIT,		BeginCpp},
	{ "Kernel",		KERNEL,			BeginCpp},
	{ "StaticInit",		STATIC_INIT,		BeginCpp},
	{ "StaticDeclare",	STATIC_DECLARE},
	{ "Constructor",	CONSTRUCTOR,		BeginCpp},
	{ "Destructor",		DESTRUCTOR,		BeginCpp},
	{ "SafeDelete",		SAFE_DELETE,		BeginCpp},
	{ "CheckParameter",	CHECK_PARAMETER,	BeginCpp},
	{ "ParameterValue",	PARAMETER_VALUE, 	BeginParamValue},
	{ "Timing",		TIMING,			BeginTimeParam},
	{ "MenuLine",		MENU_LINE,		BeginMenuName},
	{ "Description",	DESCRIPTION,		BeginEmbedded},
	{ "BaseDescription",	BASE_DESCRIPTION,	BeginEmbedded},
	{ "Instance",		INSTANCE},
	{ "HelpFile",		HELP_FILE},
	{ "MAX",		MAX},
	{ "MIN",		MIN},
	{ "MIN_POS",		MIN_POS},
	{ "MAX_NEG",		MAX_NEG},
	{ "UserCopyright",			USER_COPYRIGHT},
	{ "TargetFileOnly",	TARGET_TYPE,		BeginNull,
				LexReturnCode,		TargetFileOnly},
	{ "InteractiveFileOnly",TARGET_TYPE,		BeginNull,
				LexReturnCode,		InteractiveFileOnly},
	{ 0,			NAME,			BeginNull,LexReturnName}
};

const char * TerminalToCppType(int terminal)
{
	for (LexReservedWords * WrdPtr = TheReservedWords;
		WrdPtr->Name ; WrdPtr++) if (WrdPtr->IsCppType())
		if (terminal == WrdPtr->Terminal) return WrdPtr->Name ;
	return 0 ;
}

const char * TerminalToString(int terminal)
{
	for (LexReservedWords * WrdPtr = TheReservedWords;
		WrdPtr->Name ; WrdPtr++)
		if (terminal == WrdPtr->Terminal) return WrdPtr->Name ;
	return 0 ;
}

const char * TerminalToCType(int terminal)
{
	for (LexReservedWords * WrdPtr = TheReservedWords;
		WrdPtr->Name ; WrdPtr++) if (WrdPtr->C_Type==1)
		if (terminal == WrdPtr->Terminal) return WrdPtr->Name ;
	return 0 ;
}


LexReturn& FoundName(const char * Text, YYSTYPE& yylval)
{
	for (LexReservedWords * WrdPtr = TheReservedWords;
		WrdPtr->Name ; WrdPtr++) {
		// cerr << "Comparing:: " << WrdPtr->Name << "\n" ;
		if (!strcmp(WrdPtr->Name,Text)) break ;
	}
	static LexReturn Return(0,BeginNull) ;
	Return = LexReturn(WrdPtr->Terminal,WrdPtr->NewState);
	switch (WrdPtr->ReturnType) {
case LexReturnTerminal:
		yylval.Terminal = WrdPtr->Terminal ;
		break ;
case LexReturnCode:
		yylval.Int = WrdPtr->ReturnCode ;
		break ;
case LexReturnName:
		yylval.Name = MakeName(Text);
		break ;
	}
/*
 *	cerr << "FoundName returning \"" << Text << "\", Token = " <<
 *		Return.Terminal << "\n" ;
 */
	return Return ;
}
struct IncludeMap {
	const char * Name ;
	int Terminal ;
};

IncludeMap TheIncludeMaps[] = {
	{ "#Cinclude", C_INCLUDE },
	{ "#Hinclude", H_INCLUDE },
	{ "#cinclude", c_INCLUDE },
	{ "#hinclude", h_INCLUDE },
	{ "#ICinclude", IC_INCLUDE },
	{ "#IHinclude", IH_INCLUDE },
	{ "#Icinclude", Ic_INCLUDE },
	{ "#Ihinclude", Ih_INCLUDE },
	{ "#TCinclude", TC_INCLUDE },
	{ "#THinclude", TH_INCLUDE },
	{ "#Tcinclude", Tc_INCLUDE },
	{ "#Thinclude", Th_INCLUDE },
	{ 0, 0}
};

int GetIncludeType(const char * yytext)
{
	for (IncludeMap * TheMap = TheIncludeMaps; TheMap->Name; TheMap++)
		if (!strcmp(TheMap->Name,yytext)) break ;
	if (TheMap->Name) return TheMap->Terminal ;
	GiveWarning("bad preprocessor command or command placement");
	return C_INCLUDE ;
}

