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 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)
{ {
} }

View File

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

View File

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

View File

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