Rosetta Code/Run examples: Difference between revisions

→‎{{header|Perl 6}}: Update to latest version. Added rudimentary Go task run capability
(Added Go)
(→‎{{header|Perl 6}}: Update to latest version. Added rudimentary Go task run capability)
Line 588:
=={{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 by default, 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 Python and PythonGo 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.
 
(Note that there is no dependency download code nor resource hash for Python and Go, though they can run a remarkable number of tasks without.)
 
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 605 ⟶ 607:
use URI::Escape;
use JSON::Fast;
use Text::Levenshtein::Damerau;
use MONKEY-SEE-NO-EVAL;
 
#####################################
say "Version = 2020-02-16T01:00:33";
#####################################
 
sleep 1;
 
my %*SUB-MAIN-OPTS = :named-anywhere;
 
unit sub MAIN(
Str $run = '', #= Task or file name
Str :$lang = 'perl6', #= Language, default perl6 - should be same as in <lang *> markup
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 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
Bool :p(:$pause), #= pause after each task
Bool :b(:$broken), #= pause after each task which is broken or fails in some way
Int :$sleep = 0, #= sleep for $sleep after each task
Bool :t(:$timer), #= save timing data for each task
);
 
Line 633 ⟶ 644:
delim => "\e[0;93m", # yellow
cmd => "\e[1;96m", # cyan
warnbad => "\e[0;91m", # red
dep warn => "\e[4038;36m2;255;155;0m", # orange
dep => "\e[38;2;248;24;148m", # pink
clr => "\e[0m", # clear formatting
);
 
my $view = 'xdg-open'; # image viewer, this will open default under Linux
my %l = load-lang($lang); # load langugelanguage parameters
my %resource = load-resources($lang);
my $get-tasks = True;
Line 674 ⟶ 686:
@tasks = "%l<dir>.tasks".IO.slurp.lines; # load tasks from file
}
}
 
my $tfile;
if $timer {
$tfile = open :w, "{$lang}-time.txt";
$tfile.close;
}
 
Line 696 ⟶ 714:
my $page = $client.get("{ $url }/index.php?title={ uri-escape $title }&action=raw").content;
 
uh-oh("Whoops, can't find page: $url/$title :check spelling.\n\n{fuzzy-search($title)}", 'warn') and next if $page.elems == 0;
and next if $page.elems == 0;
say "Getting code from: http://rosettacode.org/wiki/{ $title.subst(' ', '_', :g) }#%l<language>";
 
$entry = $page.comb(rx:i/'=={{header|' $(%l<header>) '}}==' .+? [<?before \n'=='<-[={]>*'{{header'> || $] /).Str //
uh-oh("No code found\nMay be bad markup", 'warn');
 
if $entry ~~ /^^ 'See [[' (.+?) '/' $(%l<language>) / { # no code on main page, check sub page
Line 712 ⟶ 731:
say "Loading code from: $taskdir/$name.txt";
} else {
uh-oh("Task code $taskdir/$name.txt not found, check spelling or run remote.", 'warn');
next;
}
Line 720 ⟶ 739:
 
unless @blocks {
uh-oh("No code found\nMay be bad markup", 'warn') unless %resource{"$name"}<skip> ~~ /'ok to skip'/;
say "Skipping $name: ", %resource{"$name"}<skip>, "\n" if %resource{"$name"}<skip>
}
Line 730 ⟶ 749:
dump-code ("$taskdir/$name$n%l<ext>");
if %resource{"$name$n"}<skip> ~~ /'broken'/ {
uh-oh(%resource{"$name$n"}<skip>, 'bad');
pause if $broken;
} else {
say "{%c<warn>}Skipping $name$n: ", %resource{"$name$n"}<skip>, "{%c<clr>}\n";
}
next;
Line 742 ⟶ 761:
say %c<delim>, '=' x 79, %c<clr>;
redo if $redo;
sleep $sleep if $sleep;
pause if $pause;
 
}
 
Line 765 ⟶ 784:
chdir $dir;
if %resource{$code}<file> -> $fn {
copy "$current/rc/resources/{$fn_}", "./{$fn_}" for $fn[]
}
dump-code ("$code%l<ext>") unless $quiet;
check-dependencies("$code%l<ext>", $lang) if $deps;
my @cmd = %resource{$code}<cmd> ?? |%resource{$code}<cmd> !! "%l<exe> $code%l<ext>\n";
if $timer {
$tfile = open :a, "{$current}/{$lang}-time.txt";
}
my $time = 'NA: not run or killed before completion';
for @cmd -> $cmd {
say "\nCommand line: {%c<cmd>}$cmd",%c<clr>;
if $timer { $tfile.say: "Command line: $cmd".chomp }
my $start = now;
try shell $cmd;
$time = (now - $start).round(.001);
CATCH {
when /'exit code: 137'/ { }
default {
.resume unless $broken;
uh-oh($_, 'bad');
if pause.lc eq 'r'%resource{$code}<fail-by-design> {
unlink "$codesay %c<warn>, 'Fails by design, (or at least, it\'s not unexpected).txt"', %c<clr>;
} else $redo = True;{
} if pause.lc eq 'r' {
} unlink "$code.txt";
$redo = True;
}
}
}
}
if $timer { $tfile.say("#$tasknum - Wallclock seconds: $time\n") }
}
chdir $current;
say "\nDone task #$tasknum: $code - wallclock seconds: $time\e[?25h";
$tfile.close if $timer;
}
 
Line 805 ⟶ 837:
sub clear { "\r" ~ ' ' x 100 ~ "\r" }
 
sub uh-oh ($err, $class='warn') { put %c<warn>{$class}, "{'#' x 79}\n\n $err \n\n{'#' x 79}", %c<clr> }
 
sub fuzzy-search ($title) {
my @tasknames;
if "%l<dir>.tasks".IO.e {
@tasknames = "%l<dir>.tasks".IO.slurp.lines;
}
return '' unless @tasknames.elems;
" Did you perhaps mean:\n\n\t" ~
@tasknames.grep( {.lc.contains($title.lc) or dld($_, $title) < (5 min $title.chars)} ).join("\n\t");
}
 
 
multi check-dependencies ($fn, 'perl6') {
my @use = $fn.IO.slurp.comb(/<?after ^^ \h* 'use '> \N+? <?before \h* ';'>/);
if +@use {
say %c<dep>, 'Checking dependencies...', %c<clr>;
for @use -> $module {
next if $module eq any('v6', 'v6.c', 'v6.d', 'nqp', 'NativeCall', 'Test') or $module.contains('MONKEY')
or $module.contains('experimental') or $module.starts-with('lib'); or $module.contains('from<Perl5>') {
print %c<dep>;
say 'ok, no installation necessary: ', $module;
print %c<clr>;
next;
}
my $installed = $*REPO.resolve(CompUnit::DependencySpecification.new(:short-name($module)));
my @mods = $module;
if './../../../perl6-modules.txt'.IO.e {
my $fh = open( './../../../perl6-modules.txt', :r ) or die $fh;
@mods.append: $fh.lines;
$fh.close;
}
my $fh = open( './../../../perl6-modules.txt', :w ) or die $fh;
$fh.spurt: @mods.Bag.keys.sort.join: "\n";
$fh.close;
print %c<dep>;
if $installed {
say 'ok, installed: ', $module
} else {
say 'not installed: ', $module;
Line 827 ⟶ 885:
 
multi check-dependencies ($fn, 'perl') {
my @use = $fn.IO.slurp.comb(/<?after $$^^ \h* 'use '> \wN+['::'\w+]*? <?before \N+?h* ';'>/);
if +@use {
for @use -> $module {
next if $module eq $module.lc;
next if $module.starts-with(any('constant','bignum'));
my $installed = shell( "%l<exe> -e 'eval \"use {$module}\"; exit 1 if \$@'" );
print %c<dep>;
Line 850 ⟶ 909:
multi load-lang ('perl6') { ( # Language specific variables. Adjust to suit.
language => 'Perl_6', # language category name
exe => 'perl6', # executable namecommand to run perl6 in a shell
ext => '.p6', # file extension for perl6 code
dir => 'perl6', # directory to save tasks to
Line 875 ⟶ 934:
header => 'Python',
tag => rx/:i <?after '<lang ' 'python' '>' > .*? <?before '</' 'lang>'>/,
) }
 
multi load-lang ('go') { (
language => 'Go',
exe => 'go run',
ext => '.go',
dir => 'go',
header => 'Go',
tag => rx/:i <?after '<lang ' 'go' '>' > .*? <?before '</' 'lang>'>/,
) }
 
Line 944 ⟶ 1,012:
Done Lucky_and_even_lucky_numbers
===============================================================================</pre>
Try running a Go task - Command line: '''perl6 RC-run.p6 -q --lang=go "Determine if a string is numeric"'''
 
Finds two task entries, downloads both and runs each:
<pre>1) Determine if a string is numeric
Getting code from: http://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Go
 
Testing Determine_if_a_string_is_numeric0
 
Command line: go run Determine_if_a_string_is_numeric0.go
 
package main:
Determine_if_a_string_is_numeric0.go:1:1: expected 'package', found 'import'
 
Done task #1: Determine_if_a_string_is_numeric0 - wallclock seconds: 0.02
 
Testing Determine_if_a_string_is_numeric1
 
Command line: go run Determine_if_a_string_is_numeric1.go
 
"1" looks like a number.
false
 
Done task #1: Determine_if_a_string_is_numeric1 - wallclock seconds: 0.15</pre>
 
=={{header|Run BASIC}}==
10,333

edits