added stix_deletedic() and Dictionary>>removeKey: and its derivatives
This commit is contained in:
parent
6e335cd4fb
commit
064d02d031
@ -259,6 +259,16 @@ class Apex(nil)
|
|||||||
^false
|
^false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method notError
|
||||||
|
{
|
||||||
|
^true
|
||||||
|
}
|
||||||
|
|
||||||
|
method(#class) notError
|
||||||
|
{
|
||||||
|
^true
|
||||||
|
}
|
||||||
|
|
||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
|
|
||||||
@ -320,32 +330,37 @@ class Apex(nil)
|
|||||||
* ------------------------------------------------------------------ *)
|
* ------------------------------------------------------------------ *)
|
||||||
method primitiveFailed
|
method primitiveFailed
|
||||||
{
|
{
|
||||||
self class primitiveFailed.
|
^self class primitiveFailed.
|
||||||
}
|
|
||||||
|
|
||||||
method doesNotUnderstand: messageSymbol
|
|
||||||
{
|
|
||||||
self class doesNotUnderstand: messageSymbol
|
|
||||||
}
|
|
||||||
|
|
||||||
method index: index outOfRange: ubound
|
|
||||||
{
|
|
||||||
self class index: index outOfRange: ubound.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
method cannotInstantiate
|
method cannotInstantiate
|
||||||
{
|
{
|
||||||
self class cannotInstantiate
|
^self class cannotInstantiate
|
||||||
}
|
}
|
||||||
|
|
||||||
method subclassResponsibility: message_name
|
method doesNotUnderstand: messageSymbol
|
||||||
{
|
{
|
||||||
self class subclassResponsibility: message_name
|
^self class doesNotUnderstand: messageSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
method index: index outOfRange: ubound
|
||||||
|
{
|
||||||
|
^self class index: index outOfRange: ubound.
|
||||||
|
}
|
||||||
|
|
||||||
|
method subclassResponsibility: method_name
|
||||||
|
{
|
||||||
|
^self class subclassResponsibility: method_name
|
||||||
|
}
|
||||||
|
|
||||||
|
method notImplemented: method_name
|
||||||
|
{
|
||||||
|
^self class notImplemented: method_name
|
||||||
}
|
}
|
||||||
|
|
||||||
method cannotExceptionizeError
|
method cannotExceptionizeError
|
||||||
{
|
{
|
||||||
self class cannotExceptionizeError
|
^self class cannotExceptionizeError
|
||||||
}
|
}
|
||||||
|
|
||||||
method(#class) error: msgText
|
method(#class) error: msgText
|
||||||
@ -413,6 +428,11 @@ class Error(Apex)
|
|||||||
^true
|
^true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method notError
|
||||||
|
{
|
||||||
|
^false
|
||||||
|
}
|
||||||
|
|
||||||
method asInteger
|
method asInteger
|
||||||
{
|
{
|
||||||
<primitive: #_error_as_integer>
|
<primitive: #_error_as_integer>
|
||||||
|
@ -145,7 +145,7 @@ class Set(Collection)
|
|||||||
|
|
||||||
[(ass := self.bucket at: index) notNil]
|
[(ass := self.bucket at: index) notNil]
|
||||||
whileTrue: [
|
whileTrue: [
|
||||||
[key == ass key] ifTrue: [ (* TODO: change it to equality??? *)
|
(key = ass key) ifTrue: [
|
||||||
(* found *)
|
(* found *)
|
||||||
upsert ifTrue: [ass value: value].
|
upsert ifTrue: [ass value: value].
|
||||||
^ass
|
^ass
|
||||||
@ -153,7 +153,7 @@ class Set(Collection)
|
|||||||
index := (index + 1) rem: bs.
|
index := (index + 1) rem: bs.
|
||||||
].
|
].
|
||||||
|
|
||||||
upsert ifFalse: [^nil].
|
upsert ifFalse: [^ErrorCode.NOENT].
|
||||||
|
|
||||||
ntally := self.tally + 1.
|
ntally := self.tally + 1.
|
||||||
(ntally >= bs) ifTrue: [
|
(ntally >= bs) ifTrue: [
|
||||||
@ -187,29 +187,42 @@ class Set(Collection)
|
|||||||
{
|
{
|
||||||
| ass |
|
| ass |
|
||||||
ass := self __find: key or_upsert: false with: nil.
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
(ass notNil) ifTrue: [^ass value].
|
(ass isError) ifTrue: [^ass].
|
||||||
^ErrorCode.NOENT
|
^ass value
|
||||||
}
|
}
|
||||||
|
|
||||||
method at: key ifAbsent: error_block
|
method at: key ifAbsent: error_block
|
||||||
{
|
{
|
||||||
| ass |
|
| ass |
|
||||||
ass := self __find: key or_upsert: false with: nil.
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
(ass notNil) ifTrue: [^ass value].
|
(ass isError) ifTrue: [^error_block value].
|
||||||
^error_block value.
|
^ass value
|
||||||
|
}
|
||||||
|
|
||||||
|
method associationAt: key
|
||||||
|
{
|
||||||
|
^self __find: key or_upsert: false with: nil.
|
||||||
|
}
|
||||||
|
|
||||||
|
method associationAt: key ifAbsent: error_block
|
||||||
|
{
|
||||||
|
| ass |
|
||||||
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
|
(ass isError) ifTrue: [^error_block value].
|
||||||
|
^ass
|
||||||
}
|
}
|
||||||
|
|
||||||
method at: key put: value
|
method at: key put: value
|
||||||
{
|
{
|
||||||
self __find: key or_upsert: true with: value.
|
(* returns the affected/inserted association *)
|
||||||
^value
|
^self __find: key or_upsert: true with: value.
|
||||||
}
|
}
|
||||||
|
|
||||||
method includesKey: key
|
method includesKey: key
|
||||||
{
|
{
|
||||||
| ass |
|
| ass |
|
||||||
ass := self __find: key or_upsert: false with: nil.
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
^ass notNil
|
^ass notError
|
||||||
}
|
}
|
||||||
|
|
||||||
method includesAssociation: assoc
|
method includesAssociation: assoc
|
||||||
@ -226,18 +239,98 @@ class Set(Collection)
|
|||||||
^ass key = key and: [ass value = value]
|
^ass key = key and: [ass value = value]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method __find_index: key
|
||||||
|
{
|
||||||
|
| bs ass index |
|
||||||
|
|
||||||
|
bs := self.bucket size.
|
||||||
|
index := (key hash) rem: bs.
|
||||||
|
|
||||||
|
[(ass := self.bucket at: index) notNil]
|
||||||
|
whileTrue: [
|
||||||
|
(key = ass key) ifTrue: [^index].
|
||||||
|
index := (index + 1) rem: bs.
|
||||||
|
].
|
||||||
|
|
||||||
|
^ErrorCode.NOENT.
|
||||||
|
}
|
||||||
|
|
||||||
|
method __remove_at: index
|
||||||
|
{
|
||||||
|
| bs x y i v |
|
||||||
|
|
||||||
|
bs := self.bucket size.
|
||||||
|
v := self.bucket basicAt: index.
|
||||||
|
|
||||||
|
x := index.
|
||||||
|
y := index.
|
||||||
|
i := 0.
|
||||||
|
[i < self.tally] whileTrue: [
|
||||||
|
| ass z |
|
||||||
|
|
||||||
|
y := (y + 1) rem: bs.
|
||||||
|
|
||||||
|
ass := self.bucket at: i.
|
||||||
|
(ass isNil)
|
||||||
|
ifTrue: [
|
||||||
|
(* done. the slot at the current index is nil *)
|
||||||
|
i := self.tally
|
||||||
|
]
|
||||||
|
ifFalse: [
|
||||||
|
(* get the natural hash index *)
|
||||||
|
z := (ass key hash) rem: bs.
|
||||||
|
|
||||||
|
(* move an element if necessary *)
|
||||||
|
((y > x and: [(z <= x) or: [z > y]]) or:
|
||||||
|
[(y < x) and: [(z <= x) and: [z > y]]]) ifTrue: [
|
||||||
|
self.bucket at: x put: (self.bucket at: y).
|
||||||
|
x := y.
|
||||||
|
].
|
||||||
|
|
||||||
|
i := i + 1
|
||||||
|
].
|
||||||
|
].
|
||||||
|
|
||||||
|
self.bucket at: x put: nil.
|
||||||
|
self.tally := self.tally - 1.
|
||||||
|
|
||||||
|
(* return the affected association *)
|
||||||
|
^v
|
||||||
|
}
|
||||||
|
|
||||||
method removeKey: key
|
method removeKey: key
|
||||||
{
|
{
|
||||||
(* TODO: *)
|
| index |
|
||||||
self subclassResponsbility: #removeKey
|
index := self __find_index: key.
|
||||||
|
(index isError) ifTrue: [ ^index ].
|
||||||
|
^self __remove_at: index.
|
||||||
}
|
}
|
||||||
|
|
||||||
method removeKey: key ifAbsent: error_block
|
method removeKey: key ifAbsent: error_block
|
||||||
{
|
{
|
||||||
(* TODO: *)
|
| index |
|
||||||
self subclassResponsbility: #removeKey
|
index := self __find_index: key.
|
||||||
|
(index isError) ifTrue: [ ^error_block value ].
|
||||||
|
^self __remove_at: index.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
method removeAllKeys
|
||||||
|
{
|
||||||
|
(* remove all items from a dictionary *)
|
||||||
|
| bs |
|
||||||
|
bs := self.bucket size.
|
||||||
|
0 priorTo: bs do: [:i | self.bucket at: i put: nil ].
|
||||||
|
self.tally := 0
|
||||||
|
}
|
||||||
|
|
||||||
|
(* TODO: ... keys is an array of keys.
|
||||||
|
method removeAllKeys: keys
|
||||||
|
{
|
||||||
|
self notImplemented: #removeAllKeys:
|
||||||
|
}
|
||||||
|
*)
|
||||||
|
|
||||||
method remove: assoc
|
method remove: assoc
|
||||||
{
|
{
|
||||||
^self removeKey: (assoc key)
|
^self removeKey: (assoc key)
|
||||||
@ -248,6 +341,7 @@ self subclassResponsbility: #removeKey
|
|||||||
^self removeKey: (assoc key) ifAbsent: error_block
|
^self removeKey: (assoc key) ifAbsent: error_block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
method do: block
|
method do: block
|
||||||
{
|
{
|
||||||
| bs |
|
| bs |
|
||||||
|
@ -351,6 +351,10 @@ thisContext isExceptionContext dump.
|
|||||||
|
|
||||||
|
|
||||||
##============================================================================
|
##============================================================================
|
||||||
|
class PrimitiveFailureException(Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
class InstantiationFailureException(Exception)
|
class InstantiationFailureException(Exception)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -359,10 +363,6 @@ class NoSuchMessageException(Exception)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrimitiveFailureException(Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
class IndexOutOfRangeException(Exception)
|
class IndexOutOfRangeException(Exception)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -371,7 +371,7 @@ class SubclassResponsibilityException(Exception)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvalidArgumentException(Exception)
|
class NotImplementedException(Exception)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,6 +379,10 @@ class ErrorExceptionizationFailureException(Exception)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InvalidArgumentException(Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
extend Apex
|
extend Apex
|
||||||
{
|
{
|
||||||
method(#class) primitiveFailed
|
method(#class) primitiveFailed
|
||||||
@ -414,9 +418,14 @@ ctx := thisContext.
|
|||||||
IndexOutOfRangeException signal: 'Out of range'.
|
IndexOutOfRangeException signal: 'Out of range'.
|
||||||
}
|
}
|
||||||
|
|
||||||
method(#class) subclassResponsibility: message_name
|
method(#class) subclassResponsibility: method_name
|
||||||
{
|
{
|
||||||
SubclassResponsibilityException signal: ('Subclass must implment ' & message_name).
|
SubclassResponsibilityException signal: ('Subclass must implement ' & method_name).
|
||||||
|
}
|
||||||
|
|
||||||
|
method(#class) notImplemented: method_name
|
||||||
|
{
|
||||||
|
NotImplementedException signal: (method_name & ' not implemented by ' & (self name)).
|
||||||
}
|
}
|
||||||
|
|
||||||
method(#class) cannotExceptionizeError
|
method(#class) cannotExceptionizeError
|
||||||
|
@ -261,6 +261,72 @@ stix_oop_association_t stix_lookupdic (stix_t* stix, stix_oop_set_t dic, const s
|
|||||||
return lookup (stix, dic, name);
|
return lookup (stix, dic, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int stix_deletedic (stix_t* stix, stix_oop_set_t dic, const stix_oocs_t* name)
|
||||||
|
{
|
||||||
|
stix_ooi_t tally;
|
||||||
|
stix_oow_t hv, index, bs, i, x, y, z;
|
||||||
|
stix_oop_association_t ass;
|
||||||
|
|
||||||
|
STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->tally) == stix->_small_integer);
|
||||||
|
STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->bucket) == stix->_array);
|
||||||
|
|
||||||
|
tally = STIX_OOP_TO_SMOOI(dic->tally);
|
||||||
|
|
||||||
|
bs = STIX_OBJ_GET_SIZE(dic->bucket);
|
||||||
|
hv = stix_hashoochars(name->ptr, name->len) % bs;
|
||||||
|
index = hv % bs;
|
||||||
|
|
||||||
|
/* find */
|
||||||
|
while (dic->bucket->slot[index] != stix->_nil)
|
||||||
|
{
|
||||||
|
ass = (stix_oop_association_t)dic->bucket->slot[index];
|
||||||
|
|
||||||
|
STIX_ASSERT (stix, STIX_CLASSOF(stix,ass) == stix->_association);
|
||||||
|
STIX_ASSERT (stix, STIX_CLASSOF(stix,ass->key) == stix->_symbol);
|
||||||
|
|
||||||
|
if (name->len == STIX_OBJ_GET_SIZE(ass->key) &&
|
||||||
|
stix_equaloochars(name->ptr, ((stix_oop_char_t)ass->key)->slot, name->len))
|
||||||
|
{
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = (index + 1) % bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
stix->errnum = STIX_ENOENT;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
found:
|
||||||
|
/* compact the cluster */
|
||||||
|
for (i = 0, x = index, y = index; i < tally; i++)
|
||||||
|
{
|
||||||
|
y = (y + 1) % bs;
|
||||||
|
|
||||||
|
/* done if the slot at the current index is empty */
|
||||||
|
if (dic->bucket->slot[y] == stix->_nil) break;
|
||||||
|
|
||||||
|
/* get the natural hash index for the data in the slot at
|
||||||
|
* the current hash index */
|
||||||
|
ass = (stix_oop_association_t)dic->bucket->slot[y];
|
||||||
|
z = stix_hashoochars(((stix_oop_char_t)ass->key)->slot, STIX_OBJ_GET_SIZE(ass->key)) % bs;
|
||||||
|
|
||||||
|
/* move an element if necesary */
|
||||||
|
if ((y > x && (z <= x || z > y)) ||
|
||||||
|
(y < x && (z <= x && z > y)))
|
||||||
|
{
|
||||||
|
dic->bucket->slot[x] = dic->bucket->slot[y];
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dic->bucket->slot[x] = stix->_nil;
|
||||||
|
|
||||||
|
tally--;
|
||||||
|
dic->tally = STIX_SMOOI_TO_OOP(tally);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
stix_oop_set_t stix_makedic (stix_t* stix, stix_oop_t cls, stix_oow_t size)
|
stix_oop_set_t stix_makedic (stix_t* stix, stix_oop_t cls, stix_oow_t size)
|
||||||
{
|
{
|
||||||
stix_oop_set_t dic;
|
stix_oop_set_t dic;
|
||||||
|
@ -985,6 +985,12 @@ stix_oop_association_t stix_lookupdic (
|
|||||||
const stix_oocs_t* name
|
const stix_oocs_t* name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int stix_deletedic (
|
||||||
|
stix_t* stix,
|
||||||
|
stix_oop_set_t dic,
|
||||||
|
const stix_oocs_t* name
|
||||||
|
);
|
||||||
|
|
||||||
stix_oop_set_t stix_makedic (
|
stix_oop_set_t stix_makedic (
|
||||||
stix_t* stix,
|
stix_t* stix,
|
||||||
stix_oop_t cls,
|
stix_oop_t cls,
|
||||||
|
Loading…
Reference in New Issue
Block a user