Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Rudimentary variable and assignment handling.
  • Loading branch information
arnsholt committed Nov 3, 2014
1 parent 5f9404b commit 430570e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 8 deletions.
29 changes: 23 additions & 6 deletions src/Snake/Actions.nqp
Expand Up @@ -44,9 +44,10 @@ method sports($/) {
}

# 6: Expressions
method term:sym<string>($/) { make $<string>.ast; }
method term:sym<integer>($/) { make QAST::IVal.new(:value($<integer>.ast)) }
method term:sym<float>($/) { make QAST::NVal.new(:value($<dec_number>.ast)) }
method term:sym<identifier>($/) { make QAST::Var.new(:name(~$<identifier>), :scope<lexical>); }
method term:sym<string>($/) { make $<string>.ast; }
method term:sym<integer>($/) { make QAST::IVal.new(:value($<integer>.ast)) }
method term:sym<float>($/) { make QAST::NVal.new(:value($<dec_number>.ast)) }

method circumfix:sym<[ ]>($/) {
my $ast := QAST::Op.new(:op<list>);
Expand Down Expand Up @@ -74,7 +75,23 @@ method expression_list($/) {
}

# 7: Simple statements
method simple-statement:sym<expr>($/) { make $<EXPR>.ast; }
#method simple-statement:sym<expr>($/) { make $<EXPR>.ast; }
method simple-statement($/) {
make $<assignment> ?? $<assignment>.ast !! $<EXPR>.ast;
}

method assignment($/) {
my $var := ~$<identifier>;
my %sym := $*BLOCK.symbol: $var;

if !%sym<declared> {
$*BLOCK[0].push: QAST::Var.new(:name($var), :scope<lexical>, :decl<var>);
}

make QAST::Op.new(:op<bind>,
QAST::Var.new(:name($var), :scope<lexical>),
$<EXPR>.ast);
}

# 8: Compound statements
method compound-statement:sym<if>($/) {
Expand Down Expand Up @@ -118,11 +135,11 @@ method file-input($/) {
for $<line> -> $line {
$stmts.push($line.ast) if $line.ast;
}
$*BLOCK.push: $stmts;

# XXX: This has been cargo-culted from Rakudo. Should probably figure out
# how this API should be used (and what it can do).
make QAST::CompUnit.new(QAST::Block.new(QAST::Var.new(:name<__args__>,
:scope<local>, :decl<param>, :slurpy(1)), $stmts), :hll<snake>);
make QAST::CompUnit.new($*BLOCK, :hll<snake>);
}

method line($/) { make $<statement>.ast if $<statement>; }
Expand Down
20 changes: 18 additions & 2 deletions src/Snake/Grammar.nqp
Expand Up @@ -4,6 +4,14 @@ grammar Snake::Grammar is HLL::Grammar;

method TOP() {
my @*INDENT := nqp::list_i(0);
# XXX: For the time being, we handle variables like NQP: Each scope is a
# block, which has two Stmts children. We stick variable decls in the
# first one, and put the actual code as the second one. Undeclared
# variables are compile-time errors. This has to change at some point I
# think, since variables can be created by other compilation units (again,
# I think).
my $*BLOCK := QAST::Block.new(QAST::Var.new(:name<__args__>,
:scope<local>, :decl<param>, :slurpy(1)), QAST::Stmts.new());

return self.file-input;
}
Expand Down Expand Up @@ -188,8 +196,16 @@ token term:sym<nqp::op> { 'nqp::' $<op>=[\w+] '(' ~ ')' [<EXPR>+ % [:s ',' ]] }
rule expression_list { <EXPR>+ % [ ',' ]$<trailing>=[ ',' ]? }

# 7: Simple statements
proto token simple-statement {*}
token simple-statement:sym<expr> { <EXPR> }
#proto token simple-statement {*}
#token simple-statement:sym<expr> { <EXPR> }
# XXX: Can't use protos here (or at least, I can't make it work) since
# expressions and assignments can't really be easily disambiguated via their
# declarative prefixes. Therefore, we first try to parse an assignment, and if
# that fails fall back to EXPR.
token simple-statement { <assignment> || <EXPR> }

# TODO: Handle all possible assignments.
rule assignment { <identifier> '=' <EXPR> }

# 8: Compound statements
proto token compound-statement {*}
Expand Down

0 comments on commit 430570e

Please sign in to comment.