renamed SymbolSet to SymbolTable.
added some exception classes to use when something is not found. renamed Set to AssociativeCollection and started writing a new Set class
This commit is contained in:
parent
913f5f6918
commit
b9500933b8
@ -351,16 +351,10 @@ class OrderedCollection(SequenceableCollection)
|
||||
|
||||
method(#class) new: capacity
|
||||
{
|
||||
## super basicNew initWithCapacity: capacity.
|
||||
^super new initWithCapacity: capacity.
|
||||
^super new __init_with_capacity: capacity.
|
||||
}
|
||||
|
||||
##method initialize
|
||||
##{
|
||||
## ^super initialize.
|
||||
##}
|
||||
|
||||
method initWithCapacity: capacity
|
||||
method __init_with_capacity: capacity
|
||||
{
|
||||
self.buffer := Array new: capacity.
|
||||
self.firstIndex := capacity bitShift: -1.
|
||||
@ -706,15 +700,128 @@ class Set(Collection)
|
||||
|
||||
method(#class) new: size
|
||||
{
|
||||
^self new initialize: size.
|
||||
^self new __initialize_with_size: size.
|
||||
}
|
||||
|
||||
method initialize
|
||||
{
|
||||
^self initialize: 128. (* TODO: default initial size *)
|
||||
^self __initialize_with_size: 128. (* TODO: default initial size *)
|
||||
}
|
||||
|
||||
method initialize: size
|
||||
method __initialize_with_size: size
|
||||
{
|
||||
if (size <= 0) { size := 2 }.
|
||||
self.tally := 0.
|
||||
self.bucket := Array new: size.
|
||||
}
|
||||
|
||||
method __make_expanded_bucket: bs
|
||||
{
|
||||
| newbuc newsz ass index i |
|
||||
|
||||
(* expand the bucket *)
|
||||
newsz := bs + 128.
|
||||
newbuc := Array new: newsz.
|
||||
i := 0.
|
||||
while (i < bs)
|
||||
{
|
||||
ass := self.bucket at: i.
|
||||
if (ass notNil)
|
||||
{
|
||||
index := (ass hash) rem: newsz.
|
||||
while ((newbuc at: index) notNil) { index := (index + 1) rem: newsz }.
|
||||
newbuc at: index put: ass
|
||||
}.
|
||||
i := i + 1.
|
||||
}.
|
||||
|
||||
^newbuc.
|
||||
}
|
||||
|
||||
method __find_index: anObject
|
||||
{
|
||||
| bs ass index |
|
||||
|
||||
bs := self.bucket size.
|
||||
index := (anObject hash) rem: bs.
|
||||
|
||||
while ((ass := self.bucket at: index) notNil)
|
||||
{
|
||||
if (anObject = ass) { ^index }.
|
||||
index := (index + 1) rem: bs.
|
||||
}.
|
||||
|
||||
^index. ## the item at this index is nil.
|
||||
}
|
||||
|
||||
method add: anObject
|
||||
{
|
||||
| index absent bs |
|
||||
if (anObject isNil) { ^anObject }.
|
||||
|
||||
index := self __find_index: anObject.
|
||||
absent := (self.bucket at: index) isNil.
|
||||
self.bucket at: index put: anObject.
|
||||
|
||||
if (absent)
|
||||
{
|
||||
self.tally := self.tally + 1.
|
||||
bs := self.bucket size.
|
||||
if (self.tally > (bs * 3 div: 4)) { self.bucket := self __make_expanded_bucket: bs }.
|
||||
}.
|
||||
^anObject.
|
||||
}
|
||||
|
||||
method remove: oldObject ifAbsent: anExceptionBlock
|
||||
{
|
||||
}
|
||||
|
||||
method includes: anObject
|
||||
{
|
||||
}
|
||||
|
||||
method isEmpty
|
||||
{
|
||||
^self.tally == 0
|
||||
}
|
||||
|
||||
method = aSet
|
||||
{
|
||||
ifnot (self class == aSet class) { ^false }.
|
||||
if (self == aSet){ ^true }.
|
||||
ifnot (self.tally = aSet size) { ^false }.
|
||||
self do: [ :el | ifnot (aSet includes: el) { ^false } ].
|
||||
^true
|
||||
}
|
||||
|
||||
method do: aBlock
|
||||
{
|
||||
| bs i obj |
|
||||
bs := self.bucket size.
|
||||
i := 0.
|
||||
while (i < bs)
|
||||
{
|
||||
if ((obj := self.bucket at: i) notNil) { aBlock value: obj }.
|
||||
i := i + 1.
|
||||
}.
|
||||
}
|
||||
}
|
||||
|
||||
class AssociativeCollection(Collection)
|
||||
{
|
||||
var tally, bucket.
|
||||
|
||||
method(#class) new: size
|
||||
{
|
||||
^self new __initialize_with_size: size.
|
||||
}
|
||||
|
||||
method initialize
|
||||
{
|
||||
^self __initialize_with_size: 128. (* TODO: default initial size *)
|
||||
}
|
||||
|
||||
method __initialize_with_size: size
|
||||
{
|
||||
if (size <= 0) { size := 2 }.
|
||||
self.tally := 0.
|
||||
@ -728,12 +835,14 @@ class Set(Collection)
|
||||
|
||||
method __make_expanded_bucket: bs
|
||||
{
|
||||
| newbuc newsz ass index |
|
||||
| newbuc newsz ass index i |
|
||||
|
||||
(* expand the bucket *)
|
||||
newsz := bs + 128. (* TODO: keep this growth policy in sync with VM(dic.c) *)
|
||||
newbuc := Array new: newsz.
|
||||
0 priorTo: bs do: [:i |
|
||||
i := 0.
|
||||
while (i < bs)
|
||||
{
|
||||
ass := self.bucket at: i.
|
||||
if (ass notNil)
|
||||
{
|
||||
@ -741,12 +850,12 @@ class Set(Collection)
|
||||
while ((newbuc at: index) notNil) { index := (index + 1) rem: newsz }.
|
||||
newbuc at: index put: ass
|
||||
}.
|
||||
].
|
||||
i := i + 1.
|
||||
}.
|
||||
|
||||
^newbuc.
|
||||
}
|
||||
|
||||
|
||||
method __find: key or_upsert: upsert with: value
|
||||
{
|
||||
| hv ass bs index ntally |
|
||||
@ -789,7 +898,7 @@ class Set(Collection)
|
||||
{
|
||||
| ass |
|
||||
ass := self __find: key or_upsert: false with: nil.
|
||||
if (ass isError) { ^ass }.
|
||||
if (ass isError) { ^KeyNotFoundException signal }.
|
||||
^ass value
|
||||
}
|
||||
|
||||
@ -898,7 +1007,7 @@ class Set(Collection)
|
||||
{
|
||||
| index |
|
||||
index := self __find_index: key.
|
||||
if (index isError) { ^index }.
|
||||
if (index isError) { ^KeyNotFoundException signal. }.
|
||||
^self __remove_at: index.
|
||||
}
|
||||
|
||||
@ -973,11 +1082,11 @@ class Set(Collection)
|
||||
}
|
||||
}
|
||||
|
||||
class SymbolSet(Set)
|
||||
class SymbolTable(AssociativeCollection)
|
||||
{
|
||||
}
|
||||
|
||||
class Dictionary(Set)
|
||||
class Dictionary(AssociativeCollection)
|
||||
{
|
||||
(* [NOTE]
|
||||
* VM require Dictionary to implement new: and __put_assoc
|
||||
@ -1000,7 +1109,7 @@ class Dictionary(Set)
|
||||
*
|
||||
* it must return self for the way VM works.
|
||||
*)
|
||||
method put_assoc: assoc
|
||||
method __put_assoc: assoc
|
||||
{
|
||||
| hv ass bs index ntally key |
|
||||
|
||||
@ -1046,7 +1155,7 @@ class Dictionary(Set)
|
||||
(* Namespace is marked with #limited. If a compiler is writeen in moo itself, it must
|
||||
* call a primitive to instantiate a new namespace rather than sending the new message
|
||||
* to Namespace *)
|
||||
class(#limited) Namespace(Set)
|
||||
class(#limited) Namespace(AssociativeCollection)
|
||||
{
|
||||
var name, nsup.
|
||||
|
||||
@ -1073,11 +1182,11 @@ class(#limited) Namespace(Set)
|
||||
}
|
||||
}
|
||||
|
||||
class PoolDictionary(Set)
|
||||
class PoolDictionary(AssociativeCollection)
|
||||
{
|
||||
}
|
||||
|
||||
class MethodDictionary(Dictionary)
|
||||
class MethodDictionary(AssociativeCollection)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -454,6 +454,22 @@ class ProhibitedMessageException(Exception)
|
||||
{
|
||||
}
|
||||
|
||||
class NotFoundException(Exception)
|
||||
{
|
||||
}
|
||||
|
||||
class KeyNotFoundException(NotFoundException)
|
||||
{
|
||||
}
|
||||
|
||||
class ValueNotFoundException(NotFoundException)
|
||||
{
|
||||
}
|
||||
|
||||
class IndexNotFoundException(NotFoundException)
|
||||
{
|
||||
}
|
||||
|
||||
extend Apex
|
||||
{
|
||||
method(#dual,#liberal) primitiveFailed(method)
|
||||
@ -527,6 +543,11 @@ System logNl: '== END OF BACKTRACE =='.
|
||||
SubclassResponsibilityException signal: ('Subclass must implement ' & method_name).
|
||||
}
|
||||
|
||||
method(#dual) shouldNotImplement: method_name
|
||||
{
|
||||
SubclassResponsibilityException signal: ('Message should not be implemented - ' & method_name).
|
||||
}
|
||||
|
||||
method(#dual) notImplemented: method_name
|
||||
{
|
||||
| class_name |
|
||||
|
16
moo/lib/gc.c
16
moo/lib/gc.c
@ -173,14 +173,14 @@ static kernel_class_info_t kernel_classes[] =
|
||||
MOO_OBJ_TYPE_BYTE,
|
||||
MOO_OFFSETOF(moo_t, _byte_array) },
|
||||
|
||||
{ 9,
|
||||
{ 'S','y','m','b','o','l','S','e','t' },
|
||||
{ 11,
|
||||
{ 'S','y','m','b','o','l','T','a','b','l','e' },
|
||||
0,
|
||||
0,
|
||||
MOO_DIC_NAMED_INSTVARS,
|
||||
0,
|
||||
MOO_OBJ_TYPE_OOP,
|
||||
MOO_OFFSETOF(moo_t, _symbol_set) },
|
||||
MOO_OFFSETOF(moo_t, _symbol_table) },
|
||||
|
||||
{ 10,
|
||||
{ 'D','i','c','t','i','o','n','a','r','y' },
|
||||
@ -468,7 +468,7 @@ static int ignite_2 (moo_t* moo)
|
||||
if (!moo->_true || !moo->_false) return -1;
|
||||
|
||||
/* Create the symbol table */
|
||||
tmp = moo_instantiate (moo, moo->_symbol_set, MOO_NULL, 0);
|
||||
tmp = moo_instantiate (moo, moo->_symbol_table, MOO_NULL, 0);
|
||||
if (!tmp) return -1;
|
||||
moo->symtab = (moo_oop_dic_t)tmp;
|
||||
|
||||
@ -478,18 +478,18 @@ static int ignite_2 (moo_t* moo)
|
||||
* The pointer 'moo->symtab; can change in moo_instantiate() and the
|
||||
* target address of assignment may get set before moo_instantiate()
|
||||
* is called. */
|
||||
tmp = moo_instantiate (moo, moo->_array, MOO_NULL, moo->option.dfl_symtab_size);
|
||||
tmp = moo_instantiate(moo, moo->_array, MOO_NULL, moo->option.dfl_symtab_size);
|
||||
if (!tmp) return -1;
|
||||
moo->symtab->bucket = (moo_oop_oop_t)tmp;
|
||||
|
||||
/* Create the system dictionary */
|
||||
tmp = (moo_oop_t)moo_makensdic (moo, moo->_namespace, moo->option.dfl_sysdic_size);
|
||||
tmp = (moo_oop_t)moo_makensdic(moo, moo->_namespace, moo->option.dfl_sysdic_size);
|
||||
if (!tmp) return -1;
|
||||
moo->sysdic = (moo_oop_nsdic_t)tmp;
|
||||
|
||||
/* Create a nil process used to simplify nil check in GC.
|
||||
* only accessible by VM. not exported via the global dictionary. */
|
||||
tmp = (moo_oop_t)moo_instantiate (moo, moo->_process, MOO_NULL, 0);
|
||||
tmp = (moo_oop_t)moo_instantiate(moo, moo->_process, MOO_NULL, 0);
|
||||
if (!tmp) return -1;
|
||||
moo->nil_process = (moo_oop_process_t)tmp;
|
||||
moo->nil_process->sp = MOO_SMOOI_TO_OOP(-1);
|
||||
@ -515,7 +515,7 @@ static int ignite_3 (moo_t* moo)
|
||||
/* Register kernel classes manually created so far to the system dictionary */
|
||||
static moo_ooch_t str_processor[] = { 'P', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r' };
|
||||
static moo_ooch_t str_dicnew[] = { 'n', 'e', 'w', ':' };
|
||||
static moo_ooch_t str_dicputassoc[] = { 'p', 'u', 't', '_', 'a', 's', 's', 'o', 'c', ':' };
|
||||
static moo_ooch_t str_dicputassoc[] = { '_','_','p', 'u', 't', '_', 'a', 's', 's', 'o', 'c', ':' };
|
||||
|
||||
moo_oow_t i;
|
||||
moo_oop_t sym;
|
||||
|
@ -1390,7 +1390,7 @@ struct moo_t
|
||||
moo_oop_class_t _symbol; /* Symbol */
|
||||
moo_oop_class_t _array; /* Array */
|
||||
moo_oop_class_t _byte_array; /* ByteArray */
|
||||
moo_oop_class_t _symbol_set; /* SymbolSet */
|
||||
moo_oop_class_t _symbol_table; /* SymbolTable */
|
||||
moo_oop_class_t _dictionary;
|
||||
|
||||
moo_oop_class_t _namespace; /* Namespace */
|
||||
|
Loading…
Reference in New Issue
Block a user