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:
hyunghwan.chung 2018-06-20 18:01:04 +00:00
parent 913f5f6918
commit b9500933b8
4 changed files with 166 additions and 36 deletions

View File

@ -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,25 +835,27 @@ 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)
{
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
}.
].
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)
{
}

View File

@ -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 |

View File

@ -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;

View File

@ -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 */