/*  typemap.c   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
#include <string.h>
#include "yachead.h"
#include "typemap.h"
#include "intfc.h"
#include "yacintfc.h"
#include "cgidbg.h"
#include "user.h"

/*
 * enum DecType{ DecFloat, DecInt, DecName, DecString, DecComplex,
 *	DecMachWord, DecCxMachWord, DecAccMachWord, DecCxAccMachWord,
 *	DecProcedure, DecDspPP, DecParam, DecEnt}; 
 *
 * const char * DecTypeToString(DecType) ;
 *
 * enum DeclClass {DeclNot, DeclEntity, DeclBasic, DeclProcedure, DeclMember,
 *	DoDeclEntity, DoDeclBasic, DoDeclProcedure} ;
 *
 */

struct DeclaredTypes {
	DecType Type;
	const char * TypeName ;
};

DeclaredTypes TheDeclaredTypes[] = {
	{DecFloat,"double"},
	{DecFloat,"float"},
	{DecInt,"int"},
	{DecInt,"int16"},
	{DecInt,"int32"},
	{DecString,"char*"},
	{DecComplex,"complex"},
	{DecMachWord,"MachWord"},
	{DecCxMachWord,"CxMachWord"},
	{DecAccMachWord,"AccMachWord"},
	{DecCxAccMachWord,"CxAccMachWord"},
	{(DecType)0,0}
};

const char * get_dec_type_name(DecType tp)
{
	for (DeclaredTypes * typ = TheDeclaredTypes; typ->TypeName; typ++)
		if (typ->Type == tp) return typ->TypeName;
	return 0 ;
}
	
DecType GetDecType(const char * Type)
{
	for (DeclaredTypes * TheTypes = TheDeclaredTypes; TheTypes->TypeName;
		TheTypes++) if (!strobjcmp(Type,TheTypes->TypeName))
		return TheTypes->Type;
	return DecInvalid;
}


ValueType * MakeReturnValue(ValueType * Object, const char * Type)
{
	if (!Type) return 0;
	// LogOut << "MakeReturnValue: Type = " << Type << "\n" ;
	if (!strcmp(Type,"void")) return 0;
	DecType WantType = GetDecType(Type);
	if (WantType != DecInvalid) {
		if (!ReturnCheckConvert(Object,WantType)) {
			State.Error("illegal return value");
			return 0;
		} 
 		// Make a complete ValueType suitable for downstream processing
		Object->Class = DeclBasic ;
		Object->Declared.Basic = 0 ;
		return Object ;
	} 
	if(Object->Type !=DecEnt) {
		State.Error("bad return type");
		return 0 ;
	}

	// LogOut << "Past initial Check\n" ;
	UserEntity * ThisEntity = Object->Value.ValEnt ;
	if (!ThisEntity) DbgError("MakeReturnValue","bad entity");
	const char * ObjectName = ThisEntity->GetName() ;

	InteractiveEntity * ThisType =
		AllEntityLists->GetInteractiveEntityFromObj(ObjectName);
	if (!ThisType) {
		State.Error("unknown return type");
		return 0;
	}
	InteractiveEntity * IntEnt = GetBaseType(ThisType,Type);
	if (!IntEnt) {
		State.Error("cannot make a ",Type," from a ",
			ThisType->GetClassName());
		return 0;
	}
	// LogOut << "Past all Check\n" ;
	Object->Class = DoDeclEntity ;
	Object->Declared.EntityClass = ThisType ;
/*
 *	LogOut << "Object->Class = " << Object->Class << "\n" ;
 *	LogOut << "Object->Declared.EntityClass = " <<
 *		hex((long) Object->Declared.EntityClass) << "\n" ;
 *	LogOut << "About to return\n" ;
 */
	return Object ;
}

/*
 * UserEntity * MakeDeclaredEntity(UserEntity * Ent, InteractiveEntity *Declar)
 * {
 *	ValueType * Temp = new ValueType (DecEnt,Ent,DoDeclEntity,Declar);
 *	Temp->ValueDefined=1;
 *	Ent->SetClass(Temp);
 *	delete Temp ;
 *	return Ent ;
 * }
 */


