Skip to content

Commit

Permalink
Bring example compiler in line with last commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
tcurtis committed Jul 19, 2010
1 parent e372aba commit 21bbd5c
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/Squaak/Actions.pm
Expand Up @@ -78,6 +78,73 @@ method statement:sym<assignment>($/) {
make PAST::Op.new($lhs, $rhs, :pasttype<bind>, :node($/));
}

method for_init($/) {
our $?BLOCK;
our @?BLOCK;

## create a new scope here, so that we can
## add the loop variable
## to this block here, which is convenient.
$?BLOCK := PAST::Block.new( :blocktype('immediate'),
:node($/) );
@?BLOCK.unshift($?BLOCK);

my $iter := $<identifier>.ast;
## set a flag that this identifier is being declared
$iter.isdecl(1);
$iter.scope('lexical');
## the identifier is initialized with this expression
$iter.viviself( $<expression>.ast );

## enter the loop variable into the symbol table.
$?BLOCK.symbol($iter.name(), :scope('lexical'));

make $iter;
}

method step($/) {
make $<expression>.ast;
}

method statement:sym<for>($/) {
our $?BLOCK;
our @?BLOCK;

my $init := $<for_init>.ast;
## cache the name of the loop variable
my $itername := $init.name();
my $iter := PAST::Var.new( :name($itername),
:scope('lexical'),
:node($/) );
## the body of the loop consists of the statements written by the user and
## the increment instruction of the loop iterator.

my $body := @?BLOCK.shift();
$?BLOCK := @?BLOCK[0];
for $<statement> {
$body.push($_.ast);
}

my $step;
if $<step> {
my $stepsize := $<step>[0].ast;
$step := PAST::Op.new( $iter, $stepsize,
:pirop('add__0P+'), :node($/) );
}
else { ## default is increment by 1
$step := PAST::Op.new( $iter, :pirop('inc'), :node($/) );
}
$body.push($step);

## while loop iterator <= end-expression
my $cond := PAST::Op.new( :pirop<isle__IPP>,
$iter,
$<expression>.ast );
my $loop := PAST::Op.new( $cond, $body, :pasttype('while'), :node($/) );

make PAST::Stmts.new( $init, $loop, :node($/) );
}

method statement:sym<if>($/) {
my $cond := $<expression>.ast;
my $past := PAST::Op.new( $cond, $<then>.ast,
Expand Down
13 changes: 13 additions & 0 deletions src/Squaak/Grammar.pm
Expand Up @@ -55,6 +55,19 @@ rule statement:sym<do> {
<sym> <block> 'end'
}

rule statement:sym<for> {
<sym> <for_init> ',' <expression> <step>?
'do' <statement>* 'end'
}

rule step {
',' <expression>
}

rule for_init {
'var' <identifier> '=' <expression>
}

rule statement:sym<if> {
<sym> <expression> 'then' $<then>=<block>
['else' $<else>=<block> ]?
Expand Down

0 comments on commit 21bbd5c

Please sign in to comment.