/*
 *  yachead.h from ObjectProDSP 0.1
 *  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, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
#ifndef YACHEAD_DOT_H
#define YACHEAD_DOT_H
#include <iostream.h>
#include <complex.h>

#include "ObjProArith/hrdarth.h"
#include "ObjProDSP/portable.h"
#include "ObjProGen/slist.h"
#include "ObjProDSP/dectype.h"

class ArrayData ;


const char * DecTypeToString(DecType) ;

enum DeclClass {DeclNot, DeclEntity, DeclBasic, DeclProcedure, DeclMember,
	DoDeclEntity, DoDeclBasic, DoDeclProcedure} ;

const char * DeclClassToString(DeclClass) ;


// if the object is not declared or part of a declaration
// then DeclNot is set 
// The next two are for objects already declared
// The next two are for an object that is being declared

union Declaration {
	class UserEntity * Entity ; 
	class SimpleUserObject * Basic ;
	class InteractiveEntity * EntityClass ; 
	class UserBasicObjects * BasicClass ;
	Declaration (UserEntity *Ent) {Entity = Ent;}
	Declaration (SimpleUserObject *Bas) {Basic = Bas;}
	Declaration (InteractiveEntity *Ent) {EntityClass = Ent;}
	Declaration (UserBasicObjects *Bas) {BasicClass = Bas;}
	Declaration () {Entity=0;}
	void Dump(class OutTokens&,DeclClass Class,class ValueTypeList *) ;
} ;

class Procedure ;

union DataValue {
	double ValFloat;
	int32 ValInt;
	void * ValBuiltInClass ;
	Procedure * ValProcedure ;
	const char * ValName;
	class UserEntity * ValEnt ;
	struct SimpleUserObject * Obj;
	class ParameterList * ValParam ;
	

	DataValue (double v) {ValFloat = v;}
	DataValue (int32 v) {ValInt =v ;}
	DataValue (const char * nm) {ValName = nm;}
	DataValue (SimpleUserObject *ob) {Obj = ob;}
	DataValue (ParameterList * list) {ValParam = list;}
	DataValue (Procedure * proc) {ValProcedure = proc;}
	DataValue (UserEntity * ent) {ValEnt = ent;}
	DataValue (void * GenPtr) {ValBuiltInClass = GenPtr;}
	DataValue () {Obj = 0;}
	~DataValue();
	MachWord * GetMachWord() const
			{return (MachWord *) ValBuiltInClass;}
	CxMachWord * GetCxMachWord() const
			{return (CxMachWord *) ValBuiltInClass;}
	AccMachWord * GetAccMachWord() const
			{return (AccMachWord *) ValBuiltInClass;}
	CxAccMachWord * GetCxAccMachWord() const
			{return (CxAccMachWord *) ValBuiltInClass;}
	complex * GetComplex() const
			{ return (complex *) ValBuiltInClass;}
	
	void Dump(OutTokens&,DecType,class ValueTypeList *) ;
	int CppList(OutTokens&, int i = -1) ;
} ;

struct ValueType {
	DecType Type ;
	union DataValue Value ;
		// for member objects ValProcedure
		// or a new union option points to the member
		// Declaration points to the UserEnity instance
	DeclClass Class ;
	int ValueDefined ;
	union Declaration Declared ;
	ValueType(DecType Typ, DataValue Val)
		{Type=Typ;Value=Val;Class=DeclNot;ValueDefined=0;
			Declared=(UserEntity *)0;}
	ValueType(DecType Typ,DataValue Val,DeclClass cls)
		{Type=Typ;Value=Val;Class=cls;ValueDefined=0;
			Declared=(UserEntity *)0;}
	ValueType(DecType Typ,DataValue Val,DeclClass cls,Declaration Dec)
		{Type=Typ;Value=Val;Class=cls;Declared =Dec;ValueDefined=0;}
	ValueType(ValueType * Clone)
		{Type = Clone->Type; Value = Clone->Value; Class = Clone->Class;
		Declared = Clone->Declared;ValueDefined=0;}
	ValueType(DecType Typ) {Class = DeclNot;ValueDefined=0;Type=Typ;
			Declared=(UserEntity *)0;}
	ValueType() {Class = DeclNot;ValueDefined=0;Type=DecInvalid;
			Declared=(UserEntity *)0;}
	~ValueType ();
	void Dump(class OutTokens&,class ValueTypeList*) ;
	int CppList(OutTokens&) ;
	int CppList(OutTokens& Out, int i) ;
	void ArrayElementDump(class OutTokens& Out,int Index) ;
	int CheckValueDefined() ;
	int IsScalar();
	int32 GetArraySize();
	void * GetArrayData();
	int32 GetIntMemberValue() const ;
	double GetDoubleMemberValue() const ;
	const char * GetClassName() const ;
	InteractiveEntity * interactive_entity() const ;
	ArrayData * array_data();
	double double_value(DecType typ);
	void double_assign(double value);
} ;

class ValueTypeList: public SingleList {
public:
	ErrCode Insert(ValueType *nt) {return SingleList::Insert(nt);}
	ErrCode Append(ValueType  *nt) {return SingleList::Append(nt);}
	ValueType  * Get()   {return (ValueType  *) SingleList::Get();}
	ValueTypeList(){;}
	int Size(){return SingleList::Size();}
	int Dump(OutTokens&,ValueTypeList*) ;
} ;

class ValueTypeListIterator: public SingleListIterator {
public:
	ValueTypeListIterator(ValueTypeList& df):
		SingleListIterator((SingleList&) df){}
	ValueType * operator()()
		{return (ValueType *) Next();}
};
const char * NameOfObj(ValueType * Obj) ;

void * DoubleConvert(DecType Type, double * Temp) ;
void * ComplexConvert(DecType Type, complex * Temp) ;

int DoubleAssign(void * Dest, int index, DecType Type, double * Temp) ;
int DoubleAssign(ValueType * Dest, DecType Type, double * Temp) ;

inline int DoubleAssign(void * Dest, DecType Type, double * Temp)
{
	return DoubleAssign(Dest,0,Type,Temp);
}


int ComplexAssign(void * Dest, int index, DecType Type, complex * Temp) ;
int ComplexAssign(ValueType * Dest, DecType Type,complex * Temp) ;

inline int ComplexAssign(void * Dest,DecType Type, complex * Temp)
{
	return ComplexAssign(Dest,0,Type,Temp);
}

#endif /* #ifdef YACHEAD_DOT_H */
