Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
262 lines (199 sloc) 4.79 KB
## $Id$
=head1 NAME
src/builtins/guts.pir - subs that are part of the internals, not for users
=head1 SUBS
=over 4
=item !EXPORT(symbols, from :named('from') [, to :named('to')] )
Export symbols in namespace C<from> to the namespace given by C<to>.
If C<to> isn't given, then exports into the HLL global namespace.
This function differs somewhat from Parrot's C<Exporter> PMC in that
it understands how to properly merge C<MultiSub> PMCs.
.namespace []
.sub '!EXPORT'
.param string symbols
.param pmc from :named('from')
.param pmc to :named('to') :optional
.param int has_to :opt_flag
if has_to goto have_to
to = get_hll_namespace
.local pmc list
list = split ' ', symbols
unless list goto list_end
.local string symbol
.local pmc value
symbol = shift list
value = from[symbol]
$I0 = isa value, 'MultiSub'
unless $I0 goto store_value
$P0 = to[symbol]
if null $P0 goto store_value
$I0 = isa $P0, 'MultiSub'
unless $I0 goto err_type_conflict
$I0 = elements $P0
splice $P0, value, $I0, 0
goto list_loop
to[symbol] = value
goto list_loop
.return ()
$S0 = concat "Unable to add Multisub '", symbol
$S0 .= "' to existing value"
die $S0
Checks that the value and the assignee are type-compatible and does the
.param pmc type
.param pmc value
.param pmc result
$I0 = type.'ACCEPTS'(value)
result = $I0
Checks the type of a parameter.
.param pmc type
.param pmc value
$P0 = getinterp
$P0 = $P0['lexpad';1]
if null $P0 goto no_match_to_copy
$P0 = $P0['$/']
.lex "$/", $P0
$I0 = type.'ACCEPTS'(value)
if $I0 goto ok
'die'('Parameter type check failed')
=item !keyword_class(name)
Internal helper method to create a class.
.sub '!keyword_class'
.param string name
.local pmc class, resolve_list, methods, it
# Create class.
class = newclass name
# Set resolve list to include all methods of the class.
methods = inspect class, 'methods'
it = iter methods
resolve_list = new 'ResizableStringArray'
unless it goto resolve_loop_end
$P0 = shift it
push resolve_list, $P0
goto resolve_loop
=item !keyword_role(name)
Internal helper method to create a role.
.sub '!keyword_role'
.param string name
.local pmc info, role
# Need to make sure it ends up attached to the right
# namespace.
info = new 'Hash'
info['name'] = name
$P0 = new 'ResizablePMCArray'
$P0[0] = name
info['namespace'] = $P0
# Create role.
role = new 'Role', info
# Stash in namespace.
$P0 = new 'ResizableStringArray'
set_hll_global $P0, name, role
=item !keyword_grammar(name)
Internal helper method to create a grammar.
.sub '!keyword_grammar'
.param string name
.local pmc info, grammar
# Need to make sure it ends up attached to the right
# namespace.
info = new 'Hash'
info['name'] = name
$P0 = new 'ResizablePMCArray'
$P0[0] = name
info['namespace'] = $P0
# Create grammar class..
grammar = new 'Class', info
=item !keyword_does(class, role_name)
Internal helper method to implement the functionality of the does keyword.
.sub '!keyword_does'
.param pmc class
.param string role_name
.local pmc role
role = get_hll_global role_name
addrole class, role
=item !keyword_has(class, attr_name)
Adds an attribute with the given name to the class.
.sub '!keyword_has'
.param pmc class
.param string attr_name
addattribute class, attr_name
.sub 'defined'
.param pmc x
$I0 = defined x
.return ($I0)
.sub 'lex_lookup'
.param string name
$P0 = find_name name
.sub 'lookup_class'
.param pmc item
$P0 = class item
if_null $P0, null_class
$P0 = new 'Undef'
.sub 'die'
.param pmc list :slurpy
.local pmc it
.local string message
message = ''
it = iter list
unless it goto iter_end
$P0 = shift it
$S0 = $P0
message .= $S0
goto iter_loop
if message > '' goto have_message
message = "Died\n"
$P0 = new 'Exception'
$P0 = message
set_global '$!', $P0
throw $P0
.return ()
# Local Variables:
# mode: pir
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir: