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
|
method(#class) new: capacity
|
||||||
{
|
{
|
||||||
## super basicNew initWithCapacity: capacity.
|
^super new __init_with_capacity: capacity.
|
||||||
^super new initWithCapacity: capacity.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
##method initialize
|
method __init_with_capacity: capacity
|
||||||
##{
|
|
||||||
## ^super initialize.
|
|
||||||
##}
|
|
||||||
|
|
||||||
method initWithCapacity: capacity
|
|
||||||
{
|
{
|
||||||
self.buffer := Array new: capacity.
|
self.buffer := Array new: capacity.
|
||||||
self.firstIndex := capacity bitShift: -1.
|
self.firstIndex := capacity bitShift: -1.
|
||||||
@ -706,15 +700,128 @@ class Set(Collection)
|
|||||||
|
|
||||||
method(#class) new: size
|
method(#class) new: size
|
||||||
{
|
{
|
||||||
^self new initialize: size.
|
^self new __initialize_with_size: size.
|
||||||
}
|
}
|
||||||
|
|
||||||
method initialize
|
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 }.
|
if (size <= 0) { size := 2 }.
|
||||||
self.tally := 0.
|
self.tally := 0.
|
||||||
@ -728,25 +835,27 @@ class Set(Collection)
|
|||||||
|
|
||||||
method __make_expanded_bucket: bs
|
method __make_expanded_bucket: bs
|
||||||
{
|
{
|
||||||
| newbuc newsz ass index |
|
| newbuc newsz ass index i |
|
||||||
|
|
||||||
(* expand the bucket *)
|
(* expand the bucket *)
|
||||||
newsz := bs + 128. (* TODO: keep this growth policy in sync with VM(dic.c) *)
|
newsz := bs + 128. (* TODO: keep this growth policy in sync with VM(dic.c) *)
|
||||||
newbuc := Array new: newsz.
|
newbuc := Array new: newsz.
|
||||||
0 priorTo: bs do: [:i |
|
i := 0.
|
||||||
|
while (i < bs)
|
||||||
|
{
|
||||||
ass := self.bucket at: i.
|
ass := self.bucket at: i.
|
||||||
if (ass notNil)
|
if (ass notNil)
|
||||||
{
|
{
|
||||||
index := (ass key hash) rem: newsz.
|
index := (ass key hash) rem: newsz.
|
||||||
while ((newbuc at: index) notNil) { index := (index + 1) rem: newsz }.
|
while ((newbuc at: index) notNil) { index := (index + 1) rem: newsz }.
|
||||||
newbuc at: index put: ass
|
newbuc at: index put: ass
|
||||||
}.
|
}.
|
||||||
].
|
i := i + 1.
|
||||||
|
}.
|
||||||
|
|
||||||
^newbuc.
|
^newbuc.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
method __find: key or_upsert: upsert with: value
|
method __find: key or_upsert: upsert with: value
|
||||||
{
|
{
|
||||||
| hv ass bs index ntally |
|
| hv ass bs index ntally |
|
||||||
@ -789,7 +898,7 @@ class Set(Collection)
|
|||||||
{
|
{
|
||||||
| ass |
|
| ass |
|
||||||
ass := self __find: key or_upsert: false with: nil.
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
if (ass isError) { ^ass }.
|
if (ass isError) { ^KeyNotFoundException signal }.
|
||||||
^ass value
|
^ass value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,7 +1007,7 @@ class Set(Collection)
|
|||||||
{
|
{
|
||||||
| index |
|
| index |
|
||||||
index := self __find_index: key.
|
index := self __find_index: key.
|
||||||
if (index isError) { ^index }.
|
if (index isError) { ^KeyNotFoundException signal. }.
|
||||||
^self __remove_at: index.
|
^self __remove_at: index.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,11 +1082,11 @@ class Set(Collection)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SymbolSet(Set)
|
class SymbolTable(AssociativeCollection)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class Dictionary(Set)
|
class Dictionary(AssociativeCollection)
|
||||||
{
|
{
|
||||||
(* [NOTE]
|
(* [NOTE]
|
||||||
* VM require Dictionary to implement new: and __put_assoc
|
* 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.
|
* it must return self for the way VM works.
|
||||||
*)
|
*)
|
||||||
method put_assoc: assoc
|
method __put_assoc: assoc
|
||||||
{
|
{
|
||||||
| hv ass bs index ntally key |
|
| 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
|
(* 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
|
* call a primitive to instantiate a new namespace rather than sending the new message
|
||||||
* to Namespace *)
|
* to Namespace *)
|
||||||
class(#limited) Namespace(Set)
|
class(#limited) Namespace(AssociativeCollection)
|
||||||
{
|
{
|
||||||
var name, nsup.
|
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
|
extend Apex
|
||||||
{
|
{
|
||||||
method(#dual,#liberal) primitiveFailed(method)
|
method(#dual,#liberal) primitiveFailed(method)
|
||||||
@ -527,6 +543,11 @@ System logNl: '== END OF BACKTRACE =='.
|
|||||||
SubclassResponsibilityException signal: ('Subclass must implement ' & method_name).
|
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
|
method(#dual) notImplemented: method_name
|
||||||
{
|
{
|
||||||
| class_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_OBJ_TYPE_BYTE,
|
||||||
MOO_OFFSETOF(moo_t, _byte_array) },
|
MOO_OFFSETOF(moo_t, _byte_array) },
|
||||||
|
|
||||||
{ 9,
|
{ 11,
|
||||||
{ 'S','y','m','b','o','l','S','e','t' },
|
{ 'S','y','m','b','o','l','T','a','b','l','e' },
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
MOO_DIC_NAMED_INSTVARS,
|
MOO_DIC_NAMED_INSTVARS,
|
||||||
0,
|
0,
|
||||||
MOO_OBJ_TYPE_OOP,
|
MOO_OBJ_TYPE_OOP,
|
||||||
MOO_OFFSETOF(moo_t, _symbol_set) },
|
MOO_OFFSETOF(moo_t, _symbol_table) },
|
||||||
|
|
||||||
{ 10,
|
{ 10,
|
||||||
{ 'D','i','c','t','i','o','n','a','r','y' },
|
{ '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;
|
if (!moo->_true || !moo->_false) return -1;
|
||||||
|
|
||||||
/* Create the symbol table */
|
/* 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;
|
if (!tmp) return -1;
|
||||||
moo->symtab = (moo_oop_dic_t)tmp;
|
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
|
* The pointer 'moo->symtab; can change in moo_instantiate() and the
|
||||||
* target address of assignment may get set before moo_instantiate()
|
* target address of assignment may get set before moo_instantiate()
|
||||||
* is called. */
|
* 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;
|
if (!tmp) return -1;
|
||||||
moo->symtab->bucket = (moo_oop_oop_t)tmp;
|
moo->symtab->bucket = (moo_oop_oop_t)tmp;
|
||||||
|
|
||||||
/* Create the system dictionary */
|
/* 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;
|
if (!tmp) return -1;
|
||||||
moo->sysdic = (moo_oop_nsdic_t)tmp;
|
moo->sysdic = (moo_oop_nsdic_t)tmp;
|
||||||
|
|
||||||
/* Create a nil process used to simplify nil check in GC.
|
/* Create a nil process used to simplify nil check in GC.
|
||||||
* only accessible by VM. not exported via the global dictionary. */
|
* 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;
|
if (!tmp) return -1;
|
||||||
moo->nil_process = (moo_oop_process_t)tmp;
|
moo->nil_process = (moo_oop_process_t)tmp;
|
||||||
moo->nil_process->sp = MOO_SMOOI_TO_OOP(-1);
|
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 */
|
/* 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_processor[] = { 'P', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r' };
|
||||||
static moo_ooch_t str_dicnew[] = { 'n', 'e', 'w', ':' };
|
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_oow_t i;
|
||||||
moo_oop_t sym;
|
moo_oop_t sym;
|
||||||
|
@ -1390,7 +1390,7 @@ struct moo_t
|
|||||||
moo_oop_class_t _symbol; /* Symbol */
|
moo_oop_class_t _symbol; /* Symbol */
|
||||||
moo_oop_class_t _array; /* Array */
|
moo_oop_class_t _array; /* Array */
|
||||||
moo_oop_class_t _byte_array; /* ByteArray */
|
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 _dictionary;
|
||||||
|
|
||||||
moo_oop_class_t _namespace; /* Namespace */
|
moo_oop_class_t _namespace; /* Namespace */
|
||||||
|
Loading…
Reference in New Issue
Block a user