Created
August 2, 2017 10:16
-
-
Save antonijn/f817b028cfffb76498e14797593d5760 to your computer and use it in GitHub Desktop.
Perl 6 version of `spt` program (CTokens.pm6 should be in lib dir relative to the main spt file)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use v6; | |
unit module CTokens; | |
grammar CTokens::Token is export { | |
token TOP { | |
[ | |
<preproc> | | |
<comment> | | |
<line-comment> | | |
<number> | | |
<operator> | | |
<word> | | |
<string-literal> | | |
<char-literal> | | |
\s+ | |
]* | |
} | |
token preproc { ^^ [ <comment> | \h ]* <directive> [ <-[\\\n]>+ | \\<-[\n]> | \\\n ]* $$ } | |
token directive { '#' [ <comment> | \h ]* <word> } | |
token comment { '/*' .*? '*/' } | |
token line-comment { '//' [ <-[\\\n]>+ | \\<-[\n]> | \\\n ]* $$ } | |
token number { '.'? \d+ [ <[eEpP]><[+-]> | <[.\w]> ]* } | |
token operator { | |
[ | |
'++' | '--' | '&&' | '||' | '->' | | |
'+=' | '-=' | '*=' | '/=' | '%=' | '^=' | '&=' | '|=' | '~=' | '<<=' | '>>=' | | |
'==' | '!=' | '>=' | '<=' | | |
'<<' | '>>' | | |
'+' | '-' | '*' | '/' | '%' | '^' | '&' | '|' | '!' | '<' | '>' | | |
'.' | ';' | ':' | '(' | ')' | '{' | '}' | '[' | ']' | ',' | '~' | '=' | |
] | |
} | |
token word { <[a..zA..Z_]>+ \w* } | |
token string-literal { \" [ <-[\\"]>+ | \\<-["]> | \\\"]* \" } | |
token char-literal { \' [ <-[\\']>+ | \\<-[']> | \\\']* \' } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl6 | |
use strict; | |
use lib 'lib'; | |
use CTokens; | |
class ArgFormatter { | |
# makes a list of argument strings | |
method TOP($/) { | |
# keeps track of parenthesis level | |
my $levels = 0; | |
# the index after last comma | |
my $origIdx = 0; | |
# list of argument strings | |
my @result = (); | |
for $/<operator> -> $tok { | |
if $levels == 0 and $tok eq ',' { | |
my $len = $tok.from - $origIdx; | |
my $argStr = $tok.orig.substr($origIdx, $len); | |
@result.push($argStr); | |
$origIdx = $tok.to; | |
} elsif $tok eq '(' { | |
$levels++; | |
} elsif $tok eq ')' { | |
$levels--; | |
} | |
} | |
@result.push($/.orig.substr($origIdx)); | |
make @result; | |
} | |
} | |
my $fmtr = ArgFormatter.new(); | |
for lines() -> $line { | |
if not $line ~~ /(\t*) (.*?) '(' (.*) ')' (.*)/ { | |
put $line; | |
next; | |
} | |
my ($indent, $name, $args, $post) = ($0, $1, $2, $3); | |
print $indent, $name; | |
# the whitespace that comes before the arguments to align them | |
my $preArgWS = $indent ~ $name.subst(/./, ' ', :g); | |
# an attempt to split the arguments into tokens | |
my $argMatch = CTokens::Token.parse($args, actions => $fmtr); | |
# revert to simple string split if tokenization fails | |
my @argv = $argMatch ?? $argMatch.made !! $args.split(','); | |
print '(', @argv[0].trim; | |
for @argv[1..*] -> $arg { | |
print ",\n", $preArgWS, ' ', $arg.trim; | |
} | |
put ')', $post; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment