Skip to content

Commit

Permalink
Sometimes you have to screw it up before getting it right(er). Refact…
Browse files Browse the repository at this point in the history
…or state variables a bit. Gets all tests in state.t that aren't broken due to other features missing/broken passing.
  • Loading branch information
jnthn committed Mar 17, 2009
1 parent 5af6f41 commit cc85a31
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 23 deletions.
29 changes: 20 additions & 9 deletions src/builtins/guts.pir
Expand Up @@ -1143,14 +1143,11 @@ Reblesses a sub into a new type.
=item !state_var_init
Takes a list of state variables to initialize. Returns wether we need to run
the initial setting of values for them.
Loads any existing values of state variables for a block.
=cut
.sub '!state_var_init'
.param pmc names :slurpy
.local pmc lexpad, state_store, names_it
$P0 = new 'ParrotInterpreter'
lexpad = $P0['lexpad'; 1]
Expand All @@ -1161,19 +1158,33 @@ the initial setting of values for them.
setprop $P0, '$!state_store', state_store
have_state_store:
names_it = iter names
names_it = iter state_store
names_loop:
unless names_it goto names_loop_end
$S0 = shift names_it
$P0 = state_store[$S0]
if null $P0 goto need_init
lexpad[$S0] = $P0
goto names_loop
names_loop_end:
.return (0)
.end
need_init:
.return (1)
=item !state_var_inited
Takes the name of a state variable and returns true if it's been
initialized already.

=cut

.sub '!state_var_inited'
.param string name
$P0 = new 'ParrotInterpreter'
$P0 = $P0['sub'; 1]
$P0 = getprop '$!state_store', $P0
$P0 = $P0[name]
$I0 = isnull $P0
$I0 = not $I0
.return ($I0)
.end

=back
Expand Down
23 changes: 11 additions & 12 deletions src/parser/actions.pm
Expand Up @@ -1877,6 +1877,13 @@ method scope_declarator($/) {
else { $past.name('infix:,'); $past.pasttype('call'); }
if $scope eq 'state' {
$past<scopedecl> := $scope;
unless $block<needs_state_loaded> {
$block[0].push(PAST::Op.new(
:pasttype('call'),
:name('!state_var_init')
));
$block<needs_state_loaded> := 1;
}
}
}
make $past;
Expand Down Expand Up @@ -2477,16 +2484,14 @@ method EXPR($/, $key) {
}
elsif $lhs<scopedecl> eq 'state' {
# State variables - only want to actually do an assignment if
# there is no value. This calls !state_var_init, which does the
# initialization of state vars to their previous values and then
# returns a false value. In the event that there are not any
# existing values, however, it does the assignment.
# there is no value.
$past := PAST::Op.new(
:pasttype('if'),
:pasttype('unless'),
:node($/),
PAST::Op.new(
:pasttype('call'),
:name('!state_var_init'),
:name('!state_var_inited'),
$lhs.isa(PAST::Var) ?? $lhs.name() !! $lhs[0].name()
),
PAST::Op.new(
:pasttype('call'),
Expand All @@ -2496,12 +2501,6 @@ method EXPR($/, $key) {
$rhs
)
);
if $lhs.isa(PAST::Op) {
for @($lhs) { $past[0].push($_.name()); }
}
else {
$past[0].push($lhs.name());
}
}
else {
# Just a normal assignment.
Expand Down
4 changes: 2 additions & 2 deletions src/pctextensions/state.pir
Expand Up @@ -44,11 +44,11 @@ XXX TODO: Doesn't yet handle binding beyond the initial one.
# Do a call to restore any previous values. We can skip the rest
# if it returns a false value.
$P0 = self.'uniquereg'('I')
ops.'push_pirop'('call', '"!state_var_init"', name, 'result'=>$P0)
ops.'push_pirop'('call', '"!state_var_inited"', name, 'result'=>$P0)
$P1 = get_hll_global ['POST'], 'Label'
$S0 = self.'unique'('state')
$P1 = $P1.'new'('result'=>$S0)
ops.'push_pirop'('unless', $P0, $P1)
ops.'push_pirop'('if', $P0, $P1)
# Vivify and store vivification.
.local pmc viviself, vivipost
Expand Down

0 comments on commit cc85a31

Please sign in to comment.