Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
Add initial version of NQP grammar and actions.
Browse files Browse the repository at this point in the history
  • Loading branch information
pmichaud committed Oct 18, 2009
1 parent 6d0e83e commit 7b40261
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 5 deletions.
23 changes: 18 additions & 5 deletions build/Makefile.in
Expand Up @@ -29,7 +29,7 @@ CHMOD = $(PERL) -MExtUtils::Command -e chmod

# locations of parrot resources
PARROT = $(PARROT_BIN_DIR)/parrot$(EXE)
NQP = $(PARROT_BIN_DIR)/parrot_nqp$(EXE)
PARROT_NQP = $(PARROT_BIN_DIR)/parrot_nqp$(EXE)
PBC_TO_EXE = $(PARROT_BIN_DIR)/pbc_to_exe$(EXE)
PARROT_TOOLS_DIR = $(PARROT_LIB_DIR)/tools
PARROT_PERL_LIB = $(PARROT_TOOLS_DIR)/lib
Expand All @@ -54,6 +54,11 @@ P6GRAMMAR_SOURCES = \
src/Regex/P6Grammar/Grammar.pm \
src/Regex/P6Grammar/Actions.pm \

NQP_SOURCES = \
src/NQP/Grammar.pm \
src/NQP/Actions.pm \
src/NQP/Compiler.pir \

STAGE0 = src/stage0
STAGE1 = src/stage1

Expand Down Expand Up @@ -87,12 +92,12 @@ exe: P6Regex$(EXE) P6Grammar$(EXE)
stage0: $(P6REGEX_PBC_0) $(P6GRAMMAR_PBC_0)
stage1: $(P6REGEX_PBC_1) $(P6GRAMMAR_PBC_1)

$(P6REGEX_A): $(NQP) src/Regex/P6Regex/Actions.pm
$(NQP) --target=pir --output=$(P6REGEX_A) \
$(P6REGEX_A): $(PARROT_NQP) src/Regex/P6Regex/Actions.pm
$(PARROT_NQP) --target=pir --output=$(P6REGEX_A) \
src/Regex/P6Regex/Actions.pm

$(P6GRAMMAR_A): $(NQP) src/Regex/P6Grammar/Actions.pm
$(NQP) --target=pir --output=$(P6GRAMMAR_A) \
$(P6GRAMMAR_A): $(PARROT_NQP) src/Regex/P6Grammar/Actions.pm
$(PARROT_NQP) --target=pir --output=$(P6GRAMMAR_A) \
src/Regex/P6Grammar/Actions.pm

$(P6REGEX_PBC_0): src/stage0/P6Regex-s0.pir
Expand Down Expand Up @@ -135,6 +140,14 @@ P6Regex$(EXE): $(P6REGEX_PBC) $(PBC_TO_EXE)
P6Grammar$(EXE): $(P6GRAMMAR_PBC) $(PBC_TO_EXE)
$(PBC_TO_EXE) $(P6GRAMMAR_PBC)

nqp$(EXE): $(P6GRAMMAR_PBC) $(PARROT_NQP) $(PBC_TO_EXE) $(NQP_SOURCES)
$(PARROT) $(P6GRAMMAR_PBC) --target=pir \
src/NQP/Grammar.pm >src/gen/nqp-grammar.pir
$(PARROT_NQP) --target=pir \
src/NQP/Actions.pm >src/gen/nqp-actions.pir
$(PARROT) -o nqp.pbc src/NQP/Compiler.pir
$(PBC_TO_EXE) nqp.pbc


bootstrap: p6grammar
./p6grammar --target=pir src/Regex/P6Regex/Grammar.pm >p6regex-grammar.pir
Expand Down
71 changes: 71 additions & 0 deletions src/NQP/Actions.pm
@@ -0,0 +1,71 @@
class NQP::Actions;

method TOP($/, $key?) {
make PAST::Val.new( :value($<integer>.ast) );
}

method integer($/) {
make
$<hexint>
?? $<hexint>.ast
!! $<octint>
?? $<octint>.ast
!! string_to_int( $<digits>, $<base> eq 'b' ?? 2 !! 10 );
}

method hexint($/) {
make string_to_int( $/, 16 );
}

method octint($/) {
make string_to_int( $/, 8 );
}

method quote_delimited($/) {
my $str := '';
for $<quote_atom> {
$str := $str ~ $_.ast;
}
make PAST::Val.new(:value($str), :node($/));
}

method quote_atom($/) {
make $<escape> ?? $<escape>.ast !! ~$/;
}

method escape:sym<nl>($/) { make "\n"; }
method escape:sym<bs>($/) { make "\b"; }
method escape:sym<tab>($/) { make "\t"; }

sub string_to_int($src, $base) {
Q:PIR {
.local string src
$P0 = find_lex '$src'
src = $P0
.local int base, pos, eos, result
$P0 = find_lex '$base'
base = $P0
pos = 0
eos = length src
result = 0
str_loop:
unless pos < eos goto str_done
.local string char
char = substr src, pos, 1
if char == '_' goto str_next
.local int digitval
digitval = index "00112233445566778899AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", char
if digitval < 0 goto err_base
digitval >>= 1
if digitval > base goto err_base
result *= base
result += digitval
str_next:
inc pos
goto str_loop
err_base:
die "Invalid radix conversion"
str_done:
%r = box result
};
}
47 changes: 47 additions & 0 deletions src/NQP/Compiler.pir
@@ -0,0 +1,47 @@
# Copyright (C) 2009, Patrick R. Michaud

=head1 NAME

NQP::Compiler - NQP compiler

=head1 DESCRIPTION

=cut

.sub '' :anon :load :init
load_bytecode 'PCT.pbc'
load_bytecode 'P6Regex.pbc'
.end

.include 'src/gen/nqp-grammar.pir'
.include 'src/gen/nqp-actions.pir'

.namespace ['NQP';'Compiler']

.sub '' :anon :load :init
.local pmc p6meta, nqpproto
p6meta = get_hll_global 'P6metaclass'
nqpproto = p6meta.'new_class'('Regex::P6Grammar::Compiler', 'parent'=>'HLL::Compiler')
nqpproto.'language'('NQP-rx')
$P0 = get_hll_global ['NQP'], 'Grammar'
nqpproto.'parsegrammar'($P0)
$P0 = get_hll_global ['NQP'], 'Actions'
nqpproto.'parseactions'($P0)
.end

.sub 'main' :main
.param pmc args_str

$P0 = compreg 'NQP-rx'
$P1 = $P0.'command_line'(args_str, 'encoding'=>'utf8', 'transcode'=>'ascii iso-8859-1')
exit 0
.end


=cut

# Local Variables:
# mode: pir
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:
61 changes: 61 additions & 0 deletions src/NQP/Grammar.pm
@@ -0,0 +1,61 @@
grammar NQP::Grammar;

token starter { \" }
token stopper { \" }

token TOP { ^ \s* <integer> \s* $ }

token quote_delimited {
<starter> <quote_atom>* <stopper>
}

token quote_atom {
<!stopper>
[
| <escape>
| [ <-escape-stopper> ]+
]
}

token hexint { [<[ 0..9 a..f A..F ]>+] ** '_' }
token hexints { [<.ws><hexint><.ws>] ** ',' }

token octint { [<[ 0..7 ]>+] ** '_' }
token octints { [<.ws><octint><.ws>] ** ',' }

token integer {
[
| 0 [ b $<digits>=[[<[01]>+] ** '_']
| o <octint>
| x <hexint>
| d $<digits>=[[\d+] ** '_']
]
| $<digits>=[\d+ [_\d+]*]
]
}

proto token escape { <...> }
token escape:sym<backslash> { \\ \\ }
token escape:sym<bs> { \\ b }
token escape:sym<oct> { \\ o [ <octint> | '[' <octints> ']' ] }
token escape:sym<hex> { \\ x [ <hexint> | '[' <hexints> ']' ] }
token escape:sym<chr> { \\ c <charspec> }
token escape:sym<nl> { \\ n }
token escape:sym<cr> { \\ r }
token escape:sym<tab> { \\ t }

token charname {
|| <integer>
|| <[a..z A..Z]> <-[ \] , # ]>*? <[a..z A..Z ) ]>
<?before \s* <[ \] , # ]> >
}
token charnames { [<.ws><charname><.ws>] ** ',' }

token charspec {
[
| '[' <charnames> ']'
| \d+ [ _ \d+]*
| <[ ?..Z ]>
| <.panic: 'Unrecognized \\c character'>
]
}

0 comments on commit 7b40261

Please sign in to comment.