changed VM to emulate 'Dictionary new: ..' for MAKE_DICTIONARY

changed VM to emulate 'dic put_assoc: assoc' for POP_INTO_DICTIONARY
This commit is contained in:
hyunghwan.chung
2017-02-10 07:38:29 +00:00
parent 46f3e8635e
commit b1c28d03d7
6 changed files with 106 additions and 85 deletions

View File

@ -130,7 +130,7 @@ class Set(Collection)
{
dcl tally bucket.
method new: size
method(#class) new: size
{
^self new initialize: size.
}
@ -211,45 +211,6 @@ class Set(Collection)
^ass
}
(* __put_assoc: is a special internal method used by VM to add an association
* to a dictionary with the dictionary/association expression notation.
* :{ :( 1, 20 ), :( #moo, 999) } *)
method __put_assoc: assoc
{
| hv ass bs index ntally key |
key := assoc key.
bs := self.bucket size.
hv := key hash.
index := hv rem: bs.
while ((ass := self.bucket at: index) notNil)
{
if (key = ass key)
{
(* found *)
self.bucket at: index put: assoc.
^self. ## it must return self for the instructions generated by the compiler.
}.
index := (index + 1) rem: bs.
}.
(* not found *)
ntally := self.tally + 1.
if (ntally >= bs)
{
self.bucket := self __make_expanded_bucket: bs.
bs := self.bucket size.
index := hv rem: bs.
while ((self.bucket at: index) notNil) { index := (index + 1) rem: bs }.
}.
self.tally := ntally.
self.bucket at: index put: assoc.
^self. ## it must return self for the instructions generated by the compiler.
}
method at: key
{
| ass |
@ -446,6 +407,62 @@ class SymbolSet(Set)
class Dictionary(Set)
{
(* [NOTE]
* VM require Dictionary to implement new: and __put_assoc
* for the dictionary expression notation - :{ }
*)
## TODO: implement Dictionary as a Hashed List/Table or Red-Black Tree
## Do not inherit Set upon reimplementation
##
method(#class) new: size
{
^super new: (size + 10).
}
(* put_assoc: is called internally by VM to add an association
* to a dictionary with the dictionary/association expression notation
* like this:
*
* :{ :( 1, 20 ), :( #moo, 999) }
*
* it must return self for the way VM works.
*)
method put_assoc: assoc
{
| hv ass bs index ntally key |
key := assoc key.
bs := self.bucket size.
hv := key hash.
index := hv rem: bs.
while ((ass := self.bucket at: index) notNil)
{
if (key = ass key)
{
(* found *)
self.bucket at: index put: assoc.
^self. ## it must return self for the instructions generated by the compiler.
}.
index := (index + 1) rem: bs.
}.
(* not found *)
ntally := self.tally + 1.
if (ntally >= bs)
{
self.bucket := self __make_expanded_bucket: bs.
bs := self.bucket size.
index := hv rem: bs.
while ((self.bucket at: index) notNil) { index := (index + 1) rem: bs }.
}.
self.tally := ntally.
self.bucket at: index put: assoc.
^self. ## it must return self for the instructions generated by the compiler.
}
}
pooldic Log
@ -462,7 +479,7 @@ pooldic Log
#FATAL := 16.
}
class SystemDictionary(Dictionary)
class SystemDictionary(Set)
{
## the following methods may not look suitable to be placed
## inside a system dictionary. but they are here for quick and dirty

View File

@ -272,7 +272,7 @@ class MyObject(Object)
method(#class) main
{
|a|
|a i |
a := 100.
## PROBLEM: the following double loop will exhaust the stack
@ -304,19 +304,21 @@ class MyObject(Object)
##:(5, 99),
:('ccc', 890)
}.
(*a removeKey: 'bbb'.
a remove: :(#bbb).*)
1 to: 100 do: [ :i | a at: i put: (i * 2) ].
##1 to: 100 do: [ :i | a at: i put: (i * 2) ].
a keysAndValuesDo: [:k :v |
k dump.
v dump.
'------------' dump.
].
(a associationAt: :(#aaa)) dump.
(a associationAt: :(#aaa)) dump.
(*
while (true)
{
while (true)
@ -324,7 +326,7 @@ class MyObject(Object)
[:j :q | (j + q) dump] value: (if (true) { 20 }) value: (if (true) { break }).
(1 + (if (false) {} else { break })) dump.
}
}
}*)
}
}