Skip to content

Commit

Permalink
Get typed hashes working in dispatch and have assignments to them typ…
Browse files Browse the repository at this point in the history
…ed-checked. Calling methods on them is still broken; need a few more things to become Perl6MultiSub.
  • Loading branch information
jnthn committed Apr 8, 2009
1 parent 2ae3181 commit 0a9dd6d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
9 changes: 6 additions & 3 deletions src/classes/Associative.pir
Expand Up @@ -52,10 +52,11 @@ Returns a list element or slice.

=cut

.sub 'postcircumfix:{ }' :method
.sub 'postcircumfix:{ }' :method :outer('_associative_role_body')
.param pmc args :slurpy
.param pmc options :slurpy :named
.local pmc result
.local pmc result, type
type = find_lex 'T'
if args goto do_index
## return complete invocant as a list
.tailcall self.'list'()
Expand All @@ -66,7 +67,8 @@ Returns a list element or slice.
$S0 = args[0]
result = self[$S0]
unless null result goto end
result = new 'Failure'
result = 'undef'()
setprop result, 'type', type
self[$S0] = result
goto end
slice:
Expand All @@ -78,6 +80,7 @@ Returns a list element or slice.
elem = self[$S0]
unless null elem goto slice_elem
elem = 'undef'()
setprop elem, 'type', type
self[$S0] = elem
slice_elem:
push result, elem
Expand Down
28 changes: 27 additions & 1 deletion src/classes/Hash.pir
Expand Up @@ -110,8 +110,17 @@ Store a value into a hash.
.param pmc source
## we create a new hash here instead of emptying self in case
## the source argument contains self or elements of self.
.local pmc hash, it
.local pmc hash, it, type
hash = new 'Perl6Hash'

## Need to preserve typing.
type = self.'of'()
if type == "Object" goto untyped
$P0 = get_hll_global 'Associative'
$P0 = $P0.'!select'(type)
'infix:does'(hash, $P0)
untyped:
source = 'list'(source)
it = iter source
iter_loop:
Expand All @@ -130,6 +139,8 @@ Store a value into a hash.
key = elem.'key'()
value = elem.'value'()
iter_kv:
$I0 = type.'ACCEPTS'(value)
unless $I0 goto type_error
value = '!CALLMETHOD'('Scalar', value)
hash[key] = value
goto iter_loop
Expand All @@ -140,6 +151,8 @@ Store a value into a hash.
unless hashiter goto hashiter_done
$S0 = shift hashiter
value = elem[$S0]
$I0 = type.'ACCEPTS'(value)
unless $I0 goto type_error
value = '!CALLMETHOD'('Scalar', value)
value = clone value
hash[$S0] = value
Expand All @@ -148,10 +161,23 @@ Store a value into a hash.
goto iter_loop
iter_done:
copy self, hash
# Since copy calls clone which is deep and loses properties, need to now
# re-apply type.
it = iter self
prop_set_loop:
unless it goto prop_set_loop_end
$S0 = shift it
value = self[$S0]
setprop value, 'type', type
goto prop_set_loop
prop_set_loop_end:
.return (self)
err_odd_list:
die "Odd number of elements found where hash expected"
type_error:
'die'("Type mismatch in assignment to Hash.")
.end
Expand Down

0 comments on commit 0a9dd6d

Please sign in to comment.