Index: generic/tclBdd.c ================================================================== --- generic/tclBdd.c +++ generic/tclBdd.c @@ -66,29 +66,66 @@ do { \ ++((x)->refCount); \ } while(0) #define DecrBddSystemDataRefCount(x) \ do { \ - BddSystemData* sys = x; \ - if ((--(sys->refCount)) <= 0) { \ + BddSystemData* sys = (x); \ + if ((--(sys->refCount)) <= 0) { \ DeleteBddSystemData(sys); \ } \ } while(0) +/* + * Structure that represents a single bead (or a BDD) to TclOO + */ + +typedef struct BddBeadData { + unsigned int refCount; /* Reference count */ + BddSystemData* sdata; /* BDD system data */ + unsigned int bead; /* Bead index */ +} BddBeadData; +#define IncrBddBeadDataRefCount(x) \ + do { \ + ++((x)->refCount); \ + } while(0) +#define DecrBddBeadDataRefCount(x) \ + do { \ + BddBeadData* bdata = (x); \ + if ((--(bdata->refCount)) <= 0) { \ + DeleteBddBeadData(bdata); \ + } \ + } while(0) + /* * Static functions defined within this file */ static void DeletePerInterpData(PerInterpData*); +static int BddBeadConstructor(ClientData, Tcl_Interp*, Tcl_ObjectContext, + int, Tcl_Obj* const[]); static int BddSystemConstructor(ClientData, Tcl_Interp*, Tcl_ObjectContext, int, Tcl_Obj* const[]); +static int CloneBddBeadObject(Tcl_Interp*, ClientData, ClientData*); static int CloneBddSystemObject(Tcl_Interp*, ClientData, ClientData*); static int CloneMethod(Tcl_Interp*, ClientData, ClientData*); +static void DeleteBddBeadData(BddBeadData*); +static void DeleteBddBeadObject(ClientData); static void DeleteBddSystemData(BddSystemData*); static void DeleteBddSystemObject(ClientData); static void DeleteMethod(ClientData); + +/* + * TclOO data types defined within this file + */ + +const static Tcl_ObjectMetadataType BddBeadDataType = { + TCL_OO_METADATA_VERSION_CURRENT, /* version */ + "BddBeadData", /* name */ + DeleteBddBeadObject, /* deleteProc */ + CloneBddBeadObject /* cloneProc */ +}; /* * TclOO data types defined within this file */ @@ -105,10 +142,18 @@ const static Tcl_MethodType BddSystemConstructorType = { TCL_OO_METHOD_VERSION_CURRENT, /* version */ "CONSTRUCTOR", /* name */ BddSystemConstructor, /* callProc */ + DeleteMethod, /* method delete proc */ + CloneMethod /* method clone proc */ +}; + +const static Tcl_MethodType BddSystemBeadConstructorType = { + TCL_OO_METHOD_VERSION_CURRENT, /* version */ + "CONSTRUCTOR", /* name */ + BddBeadConstructor, /* callProc */ DeleteMethod, /* method delete proc */ CloneMethod /* method clone proc */ }; /* @@ -243,10 +288,12 @@ Tcl_SetErrorCode(interp, "BDD", "InitialSize<4", Tcl_GetString(objv[skip]), NULL); return TCL_ERROR; } + Tcl_ObjectContextInvokeNext(interp, objectContext, skip, objv, skip); + /* Create the BDD system */ sdata = (BddSystemData*) ckalloc(sizeof(BddSystemData)); sdata->refCount = 1; sdata->pidata = pidata; @@ -254,10 +301,62 @@ sdata->system = BDD_NewSystem(size); Tcl_ObjectSetMetadata(thisObject, &BddSystemDataType, (ClientData) sdata); return TCL_OK; } + +/* + *----------------------------------------------------------------------------- + * + * BddBeadConstructor -- + * + * Constructs a bead in a Binary Decision Diagram. + * + * Parameters: + * None. + * + * Results: + * Returns a standard Tcl result. + * + *----------------------------------------------------------------------------- + */ + +static int +BddBeadConstructor( + ClientData clientData, /* Pointer to the per-interp data */ + Tcl_Interp* interp, /* Tcl interpreter */ + Tcl_ObjectContext objectContext, /* Object context */ + int objc, /* Parameter count */ + Tcl_Obj *const objv[] /* Parameter vector */ +) { + BddSystemData* sdata = (BddSystemData*) clientData; + /* Per-interp data for the BDD package */ + Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); + /* Current object */ + int skip = Tcl_ObjectContextSkippedArgs(objectContext); + /* Number of leading args to skip */ + BddBeadData* bdata; + + /* Check arguments */ + + if (objc != skip) { + Tcl_WrongNumArgs(interp, skip, objv, ""); + return TCL_ERROR; + } + Tcl_ObjectContextInvokeNext(interp, objectContext, skip, objv, skip); + + /* Create the BDD system */ + + bdata = (BddBeadData*) ckalloc(sizeof(BddBeadData)); + bdata->refCount = 1; + bdata->sdata = sdata; + bdata->bead = 0; + IncrBddSystemDataRefCount(sdata); + + Tcl_ObjectSetMetadata(thisObject, &BddBeadDataType, (ClientData) bdata); + return TCL_OK; +} /* *----------------------------------------------------------------------------- * * CloneBddSystemObject -- @@ -334,10 +433,27 @@ BDD_DeleteSystem(sdata->system); sdata->system = NULL; DecrPerInterpRefCount(sdata->pidata); ckfree(sdata); } + +/* + *----------------------------------------------------------------------------- + * + * DeleteBddBeadObject -- + * + * Cleans up when a bead in a BDD is deleted. + * + *----------------------------------------------------------------------------- + */ + +void +DeleteBddBeadObject( + ClientData clientData +) { + DecrBddBeadDataRefCount((BddBeadData*) clientData); +} /* *----------------------------------------------------------------------------- * * DeleteBddSystemObject -- Index: library/tclbdd.tcl ================================================================== --- library/tclbdd.tcl +++ library/tclbdd.tcl @@ -11,7 +11,33 @@ namespace eval bdd { namespace export system } +oo::class create bdd::System { + variable beadseq + constructor args { + namespace eval Bead {} + set beadseq 0 + bdd::bead create Bead::false [self] + bdd::bead create Bead::true [self] + Bead::true = 1 + } + method false {} { + return [namespace which Bead::false] + } + method true {} { + return [namespace which Bead::true] + } +} oo::class create bdd::system { + superclass bdd::System +} + +oo::class create bdd::Bead { + constructor args { + } +} + +oo::class create bdd::bead { + superclass bdd::Bead }