module Prelude-0.0.1;
use v6;
# There are a couple of things going on here.
#
# * These are perl6 implementations of "builtins"
# * They sometimes use Pugs internals to do the job
# * Some of this isn't specced yet (need S29 work).
class File;
# Simple file open. Unlike perl5 open, it isn't very dwimmy.
### XXX: NOTE ###
# this is intended to eventually replace Prim.hs's open (or be replaced by
# it, since that would probably be faster)
# also, the signature for this sub is nowhere near finalized; it should
# support asynch/exclusive/other stuff. For lots of discussion but no final
# spec, see the thread rooted at <20050502192508.GF24107@sike.forum2.org>
# on p6-l.
multi sub open (Str $filename, Str +$layer, Bool +$r, Bool +$w, Bool +$rw, Bool +$a) returns IO is primitive is unsafe is export {
die "fancy open modes not supported yet" if $a & any($r, $w, $rw);
my $mode;
$mode = "a" if $a;
$mode = "w" if $w;
$mode = "rw" if $rw || $r & $w;
$mode ||= "r";
# XXX failures
my $fh = Pugs::Internals::openFile($filename, $mode);
# XXX layers :)
Pugs::Internals::hSetBinaryMode($fh, bool::true) if
$layer ~~ rx:P5/:raw\b/;
$fh;
}
class Pipe;
# Easy to use, unidirectional pipe. Uses the shell.
multi sub open (Str $command, Bool +$r is copy, Bool +$w) returns IO is primitive is unsafe {
die "Pipe::open is unidirectional" if all($r, $w);
$r = bool::true if none($r, $w);
my ($in, $out, $err, undef) =
Pugs::Internals::runInteractiveCommand($command);
close $err;
close ($r ?? $in :: $out);
($r ?? $out :: $in);
}
# Bidirectional pipe. Potenially dangerous. Uses the shell.
multi sub open2 (Str $command) returns List is primitive is unsafe {
my ($in, $out, $err, $pid) =
Pugs::Internals::runInteractiveCommand($command);
close $err;
($in, $out, $pid);
}
# Tridirectional pipe. Potenially dangerous. Uses the shell.
# Please remember to update t/pugsrun/11-safemode.t if you change the fully
# qualified name of open3.
multi sub open3 (Str $command) returns List is primitive is unsafe {
my ($in, $out, $err, $pid) =
Pugs::Internals::runInteractiveCommand($command);
($in, $out, $err, $pid);
}
class Control::Basic;
# multi-lingual eval.
# S29:
# Execute C<$code> as if it were code written in C<$lang>. C<Perl6> is the
# only required language, but supporting C<Perl5> is I<strongly>
# recommended.
# XXX: don't call me yet, the Prim.hs side of this isn't done.
# migrating all of eval takes updating lots of code.
# XXX: mark everything except :lang<YAML> unsafe
# (maybe :lang<YAML> doesn't quite belong here?)
multi sub eval (Str ?$code = $CALLER::_, Str +$lang = 'Perl6')
is primitive is unsafe {
given $lang {
when 'Perl6' { Pugs::Internals::eval($code) };
when 'Perl5' { Pugs::Internals::eval_perl5($code) };
when 'Haskell' { Pugs::Internals::eval_haskell($code) };
when 'Parrot' { Pugs::Internals::eval_parrot($code) };
when 'YAML' { Pugs::Internals::eval_yaml($code) };
}
}
# S29:
# Behaves like, and replaces Perl 5 C<do EXPR>, with optional C<$lang>
# support.
multi sub evalfile (Str $filename : Str +$lang = 'Perl6')
is primitive is unsafe {
eval(slurp $filename, $lang);
}
class Control::Caller;
has Str $.package;
has Str $.file;
has Int $.line;
has Str $.subname;
has Str $.subtype;
has Code $.sub;
has Str $.params; # FIXME: needs attention; don't use yet.
multi sub caller (Class ?$kind = Any, Int +$skip = 0, Str +$label) returns Control::Caller is primitive is export is safe {
my @caller = Pugs::Internals::caller($kind, $skip, $label);
# FIXME: why doesn't this work?
# this is here just because of an icky pugsbug.
#my %idx = <package file line subname subtype params> Y 0 .. 5; # ugly.
#Control::Caller.new( map { ; $_ => @caller[ %idx{$_} ] }, keys %idx );
#( map { say( $_ => @caller[ %idx{$_} ] ) }, keys %idx );
@caller.elems ?? Control::Caller.new(
'package' => @caller[0],
'file' => @caller[1],
'line' => @caller[2],
'subname' => @caller[3],
'subtype' => @caller[4],
'sub' => @caller[5],
) :: undef;
}
class Carp;
# Please remember to update t/pugsrun/11-safemode.t if you change the fully
# qualified name of longmess.
multi sub longmess (: ?$e = '') returns Str is primitive is safe {
my($mess, $i);
$mess = "$e at $?CALLER::POSITION";
#while Control::Caller::caller(++$i) -> $caller {
# $mess ~= "\n\t{$caller.package}::{$caller.subname}() at {$caller.file} line {$caller.line}";
#}
loop {
my $caller = Control::Caller::caller(skip => $i++) err last;
$mess ~= "\n\t{$caller.package}::{$caller.subname}() at {$caller.file} line {$caller.line}";
}
$mess;
}