Skip to content

Commit

Permalink
Add a concrete syntax for CgOp
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan O'Rear committed Jul 15, 2010
1 parent 6dac3ce commit e32cb27
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
28 changes: 28 additions & 0 deletions Niecza/Actions.pm
Expand Up @@ -149,6 +149,8 @@ sub quote__S_Q { my ($cl, $M) = @_;
sub nibbler { my ($cl, $M) = @_;
if ($M->isa('STD::Regex')) {
$M->{_ast} = $M->{EXPR}{_ast};
} elsif ($M->isa('Niecza::Grammar::CgOp')) {
$M->{_ast} = Op::CgOp->new(op => $M->{cgexp}{_ast});
} elsif ($M->isa('Niecza::Grammar::NIL')) {
$M->{_ast} = Op::NIL->new(ops => [map { @{$_->{_ast}} } @{$M->{insn}}]);
} else {
Expand Down Expand Up @@ -528,6 +530,32 @@ sub multisig { my ($cl, $M) = @_;
$M->{_ast} = $M->{signature}[0]{_ast};
}

sub cgopname { my ($cl, $M) = @_;
$M->{_ast} = $M->Str;
}

sub cgexp { }
sub cgexp__S_name { my ($cl, $M) = @_;
$M->{_ast} = $M->{cgopname}{_ast};
}

sub cgexp__S_decint { my ($cl, $M) = @_;
$M->{_ast} = $M->{decint}{_ast};
}

sub cgexp__S_quote { my ($cl, $M) = @_;
if (!$M->{quote}{_ast}->isa('Op::StringLiteral')) {
$M->sorry("Strings used in CgOp code must be compile time constants");
}
$M->{_ast} = $M->{quote}{_ast}->text;
}

sub cgexp__S_op { my ($cl, $M) = @_;
no strict 'refs';
$M->{_ast} = &{'CgOp::' . $M->{cgopname}{_ast}}(
map { $_->{_ast} } @{ $M->{cgexp} });
}

sub voidmark { my ($cl, $M) = @_;
$M->{_ast} = 1;
}
Expand Down
17 changes: 17 additions & 0 deletions Niecza/Grammar.pm6
Expand Up @@ -22,6 +22,23 @@ grammar Q is STD::Q {
#}

multi method tweak(:$NIL!) { self.cursor_fresh( ::Niecza::Grammar::NIL ) }
multi method tweak(:$CgOp!) { self.cursor_fresh( ::Niecza::Grammar::CgOp)}
}

# an OPP is planned, but I need a better way to write action methods first,
# since the OPP would necessarily use the same rule names as STD::P6
grammar CgOp is STD {
rule nibbler { <cgexp> }

token category:cgexp { <sym> }
proto token cgexp { <...> }

token cgopname { \w+ }

token cgexp:op { '(':s {} <cgopname> [ <cgexp> ]* ')' }
token cgexp:name { <cgopname> }
token cgexp:quote { <?before <[ ' " ]>> {} [ :lang(%*LANG<MAIN>) <quote> ] }
token cgexp:decint { <decint> }
}

# mnemonic characters: (@, !, =) fetch, store, lvalue.
Expand Down
13 changes: 13 additions & 0 deletions Op.pm
Expand Up @@ -30,6 +30,19 @@ use CgOp;
no Moose;
}

{
package Op::CgOp;
use Moose;
extends 'Op';

has op => (is => 'ro', required => 1);

sub code { $_[0]->op }

__PACKAGE__->meta->make_immutable;
no Moose;
}

{
package Op::StatementList;
use Moose;
Expand Down

0 comments on commit e32cb27

Please sign in to comment.