Rosetta Code/Run examples: Difference between revisions

→‎{{header|Perl 6}}: More switches & updates, roughed in multi-language code, will now run Perl & Python as well as Perl6
(→‎{{header|Perl 6}}: Substantial upgrades to configurability and capability)
(→‎{{header|Perl 6}}: More switches & updates, roughed in multi-language code, will now run Perl & Python as well as Perl6)
Line 263:
=={{header|Perl 6}}==
{{works with|Rakudo|2018.03}}
This is a fairly comprehensive task code runner. It is set up to work for Perl 6 atby this pointdefault, but has basic configurations to run Perl and Python tasks as well. It can be easily tweaked to work with other languages by adding a load-lang('whatever'){} routine similar to the Perl6, Perl and Python ones. (And ensuring that the appropriate compiler is installed and accessible.) There is so much variation to the task requirements and calling conventions that it would be problematic to make a general purpose, language agnostic code runner so some configuration is necessary to make it work with other languages.
 
By default, this will download the Perl 6 section of any (every) task that has a Perl 6 example, extract the code blocks and attempt to run them. Many tasks require files or user interaction to proceed, others are not complete runnable code blocks (example code fragments), some tasks run forever. To try to deal with and compensate for this, this implementation can load a %resource hash that will: supply input files where necessary, skip unrunnable code fragments, limit long and/or infinite running blocks, supply user interaction code where possible, and skip blocks where user interaction is unavoidable.
Line 284:
my %*SUB-MAIN-OPTS = :named-anywhere;
 
unit sub MAIN(
unit sub MAIN( Str $run = '', Bool :f(:$force), Bool :l(:$local), Bool :r(:$remote) );
Str $run = '', # Task or file name
Str :$lang = 'perl6', # Language, default perl6 - should be same as in the <lang *> tags
Int :$skip = 0, # Skip # to continue partially into a list
Bool :f(:$force), # Override any task-skip parameter in %resource hash
Bool :l(:$local), # Only use task code from local cache
Bool :r(:$remote), # Only use code from remote server (refresh local cache)
Bool :q(:$quiet), # Less verbose, don't display source code
Bool :d(:$deps), # Load dependencies if necessary
Bool :p(:$pause), # pause after each task
);
 
die 'You can select local or remote, but not both...' if $local && $remote;
Line 290 ⟶ 300:
my $client = HTTP::UserAgent.new;
my $url = 'http://rosettacode.org/mw';
 
my %l = ( # Language specific variables Adjust to suit
language => 'Perl_6', # language category name
exe => 'perl6', # executable name to run perl6 in a shell
ext => '.p6', # file extension for perl6 code
dir => 'perl6', # directory to save tasks to
header => 'Perl 6', # header text
# tags marking blocks of code - spaced out to placate wiki formatter
# and to avoid getting tripped up when trying to run _this_ task
tag => rx/<?after '<lang ' 'perl6' '>' > .*? <?before '</' 'lang>'>/,
);
 
my %c = ( # text colors
Line 310 ⟶ 309:
);
 
my $view = 'xdg-open'; # image viewer, this will open default under Linux
my %resourcel = load-resourceslang($lang); # load languge paramters
my %resource = load-resources($lang);
my $get-tasks = True;
 
Line 320:
 
if $run {
if $run.IO.e and $run.IO.f {# is it a file?
@tasks = $run.IO.lines; # yep, treat each line as a task name
} else { # must be a single task name
} else {
@tasks = ($run); # treat it so
}
$get-tasks = False; # don't need to retreive task names from web
}
 
if $get-tasks { # load tasks from web if no cache is not found, older than one day or forced
if $get-tasks {
if (!"%l<language>.tasks".IO.e or ("%l<language>.tasks".IO.modified//0 - now) > 86400 ) or $remote {
@tasks = mediawiki-query( # get tasks from web
$url, 'pages',
:generator<categorymembers>,
Line 340:
"%l<exe>.tasks".IO.spurt: @tasks.sort.join("\n");
} else {
@tasks = "%l<language>.tasks".IO.slurp; # load tasks from file
}
}
 
note "Skipping first $skip tasks..." if $skip;
 
for @tasks -> $title {
# If you want to resume partially into automatic
# downloads, adjust $skip to skip that many tasks
my $skip = 0;
next if $++ < $skip;
next unless $title ~~ /\S/; # filter blank lines (from files)
note "Skipping first $skip tasks..." if $skip;
next unlesssay $titleskip ~~+ /\S/;++$, #") filter blank lines$title";
say $skip + ++$, " $title";
 
my $name = $title.subst(/<-[-0..9A..Za..z]>/, '_', :g);
Line 359 ⟶ 357:
 
my $entry;
if $remote or !"$taskdir/name.txt".IO.e or (($modified - now) > 86400 * 7) {
my $page = $client.get("{ $url }/index.php?title={ uri-escape $title }&action=raw").content;
 
say %c<warn>, uh-oh("Whoops, can't find page: $url/$title :check spelling.", %c<clr>) and next if $page.elems == 0;
say "Getting code from: http://rosettacode.org/wiki/{ $title.subst(' ', '_', :g) }#%l<language>";
 
my $header = %l<header>; # can't interpolate hash into regex
$entry = $page.comb(/'=={{header|' $header '}}==' .+? [<?before \n'=='<-[={]>*'{{header'> || $] /).Str // whoops;
uh-oh("No code found\nMay be bad markup");
 
my $lang = %l<language>; # can't interpolate hash into regex
Line 387 ⟶ 386:
 
unless @blocks {
whoopsuh-oh("No code found\nMay be bad markup") unless %resource{"$name"}<skip> ~~ /'ok to skip'/;
say "Skipping $name: ", %resource{"$name"}<skip>, "\n" if %resource{"$name"}<skip>
}
Line 406 ⟶ 405:
run-it($taskdir, "$name$n");
}
say %c<delim>, '=' x 79, %c<clr>;
pause if $pause;
}
 
Line 428:
copy "$current/rc/resources/{$fn}", "./{$fn}"
}
dump-code ("$code%l<ext>") unless $quiet;
check-modulesdependencies("$code%l<ext>", $lang) if %l<language> eq 'Perl_6'$deps;
my @cmd = %resource{$code}<cmd> ?? |%resource{$code}<cmd> !! "%l<exe> $code%l<ext>\n";
for @cmd -> $cmd {
Line 437:
chdir $current;
say "\nDone $code";
}
 
sub pause {
prompt "Press enter to procede: >";
# or
}# elsesleep {5;
}
 
Line 449 ⟶ 455:
sub clear { "\r" ~ ' ' x 100 ~ "\r" }
 
sub whoopsuh-oh ($err) { sayput %c<warn>, "{'#' x 79}\n\nNon code$err found\nMay be bad markup\n\n{'#' x 79}", %c<clr> }
 
multi check-dependencies ($fn, 'perl6') {
sub uh-oh ($err) { put %c<warn>, "{'#' x 79}\n\n$err;\n\n{'#' x 79}", %c<clr> }
 
sub check-modules ($fn) {
my @use = $fn.IO.slurp.comb(/<?after $$ 'use '> \N+? <?before \h* ';'>/);
if +@use {
Line 464 ⟶ 468:
}
 
multi check-dependencies ($fn, $unknown) {
sub load-resources { () } # load resources for finer control
note "Sorry, don't know how to handle dependancies for $unknown language."
</lang>
};
 
mymulti %lload-lang =('perl6') { ( # Language specific variables. Adjust to suit.
language => 'Perl_6', # language category name
exe => 'perl6', # executable name to run perl6 in a shell
ext => '.p6', # file extension for perl6 code
dir => 'perl6', # directory to save tasks to
header => 'Perl 6', # header text
# tags marking blocks of code - spaced out to placate wiki formatter
# and to avoid getting tripped up when trying to run _this_ task
tag => rx/<?after '<lang ' 'perl6' '>' > .*? <?before '</' 'lang>'>/,
) }
 
multi load-lang ('perl') { (
language => 'Perl',
exe => 'perl',
ext => '.pl',
dir => 'perl',
header => 'Perl',
tag => rx/<?after '<lang ' 'perl' '>' > .*? <?before '</' 'lang>'>/,
) }
 
multi load-lang ('python') { (
language => 'Python',
exe => 'python',
ext => '.py',
dir => 'python',
header => 'Python',
tag => rx/<?after '<lang ' 'python' '>' > .*? <?before '</' 'lang>'>/,
) }
 
multi load-lang ($unknown) { die "Sorry, don't know how to handle $unknown language." };
 
multi load-resources ($unknown) { () };</lang>
 
{{out}} with command line: '''perl6 RC-run.p6 -q "Determine if a string is numeric"'''
<pre>Retrieving tasks
1 Determine if a string is numeric
Line 501 ⟶ 539:
===============================================================================</pre>
Or, if the full %resource hash is loaded it will automatically feed input parameters to tasks that require them:<br>
'''perl6 RC-run.p6 Lucky_and_even_lucky_numbers''' -q
<pre>Retrieving tasks
1 Lucky_and_even_lucky_numbers
10,333

edits