/* CoreFlat.h
	*/
	
# ifndef CoreFlat
# define CoreFlat

#include "CoreBasics.h"
#include "Core.h"

#define CellTypePathSize 64
#define WirePathSize 32

/* Types */
	
	typedef struct InstancePathRec {
		Nat length;  /* in bits */
		Bool bits[CellTypePathSize];
		} InstancePathRec;
		
	typedef InstancePathRec *InstancePath;
		
	typedef struct FlatCellTypeRec {
		InstancePathRec path;
		Nat recastCount;
		} FlatCellTypeRec;
		
	typedef FlatCellTypeRec *FlatCellType;
		
	typedef enum WireRoot {internal, public, actual} WireRoot;
		
	typedef struct WirePathRec {
		Nat length;  /* in bits */
		Bool bits[WirePathSize];
		} WirePathRec;
		
	typedef WirePathRec *WirePath;
		
	typedef struct FlatWireRec {
		FlatCellTypeRec flatCell;
		Nat instanceIndex;
		WireRoot wireRoot;
		Bool validPath;
		WirePathRec path;
		Wire wire;
		} FlatWireRec;
		
	typedef FlatWireRec *FlatWire;
		
	extern FlatCellTypeRec rootCellType;
		
	extern FlatCellTypeRec allFlatCells;
		
	extern WirePathRec rootWirePath;
		
/* Flat Instance */
	
	extern Bool InstancePathEqualRec();
		/* equal, InstancePathRec one, InstancePathRec other */
		
	extern Nat InstancePathHashRec();
		/* hash, InstancePathRec path */
		
	extern void ExtendPath();
		/* InstancePath newPath, InstancePathRec currentPath, Nat index, RecordCellType rct */
		/* Note that newPath is modified */
		
	extern HashTable BindInstance();
		/* newBindings, FlatCellTypeRec parent, WireSeq actual, WireSeq public, HashTable bindings */
		
/* Flat Wire */
	
	extern FlatWire CreateFlatWire();
		/* flatWire, FlatCellTypeRec flatCell=rootCellType, Nat instanceIndex=0, WireRoot wireRoot=internal, Bool validPath=false, WirePathRec path=rootWirePath, Wire wire=nil */
		
	extern Bool FlatWireEqual();
		/* EqualProc */
		
	extern Nat FlatWireHash();
		/* HashProc */
		
/* Enumeration */
	
	typedef void (* UnboundFlatCellProc)();
		/* CellType cell, FlatCellType target=allFlatCells, FlatCellType flatCell=rootCellType, CellInstance instance=nil, Nat index=NatLast, CellType parent=nil, FlatCellType flatParent=rootCellType, Ref data=nil */
		
	extern void NextUnboundCellType();
		/* CellType cell, FlatCellType target, FlatCellType flatCell, CellInstance instance, Nat index, CellType parent, FlatCellType flatParent, Ref data, UnboundFlatCellProc proc */
		
	typedef void (* BoundFlatCellProc)();
		/* CellType cell, FlatCellTypeRec target=allFlatCells, FlatCellTypeRec flatCell=rootCellType, CellInstance instance=nil, Nat index=NatLast, CellType parent=nil, FlatCellTypeRec flatParent=rootCellType, Ref data=nil, HashTable bindings=nil */
		
	extern void NextBoundCellType();
		/* CellType cell, FlatCellTypeRec target, FlatCellTypeRec flatCell, CellInstance instance, Nat index, CellType parent, FlatCellTypeRec flatParent, Ref data, HashTable bindings, BoundFlatCellProc proc */
		
	extern HashTable InitialBindingTable();
		/* bindings, CellType root */
		
/* Initialization */
	
	extern void CoreFlatInitialize();
		/*  */
		
# endif