Ok, so without knowing what the XS-replacement will look like and without knowing what we're doing with filehandle-functions (is tell() staying or does it get removed in favor of $fh.tell()) and a whole lot of other stuff it's impossible to translate all of the Perl 5 functions to Perl 6. However, what I've done is take a quick stab at creating at least function signatures for everything that was in perlfunc and implemented some of the functions that do not require any external junk (e.g. reverse).
Some questions came up while I was doing this. Questions that came up a lot, I put in comments at the front of the file. Other comments are in-line and are marked with "XXX" for easy searching. Anything that I think will be handled by internals or by the pre-coded functions that are currently in parrot/languages/perl6/P6C/Builtins.pm, I marked with "INTERNAL" for easy searching. Please don't expect this to compile. It probably has typos and certainly has masses of undefined class names (e.g. IO::Socket). It's really just here to help me understand what I don't understand and to get some questions on the table. I'll keep updating this as more information about XS, filehandles, etc become clear. There are also some functions (like split) that will require my going over A5 with a fine-toothed comb before I proceed.
# Builtin functions # XXX - This marker is used all over to indicate potential problems and # quesitons about how Perl 6 works. # # High-level questions: # # When declaring: # sub foo($a, $b) {...} # and # sub foo($a, *@rest) { ... } # What is the correct order, and/or is this even valid? I need to know, # given the way I did sort and reverse in order to handle exploded # argument lists and arrays efficiently. # # What is happening to the IO functions? Do they just go away to be # subsumed by the appropriate IO:: classes? # # Generally need to know how the interface ot libc will work, so # that all of this junk can be implemented. # # Do I need to "@array is rw"? I would think not.... # An EMACS helper macro # (defalias 'perl6-mockup (read-kbd-macro # "C-a sub SPC M-d C-y ( C-e ) SPC { SPC UNIMP(\" C-y \") SPC }")) sub UNIMP($func) { die "$0: Unimplemented: $func" } sub NEVER($func) { die "$0: $func makes no sense in Perl 6" } # Math sub abs($num is int){ return $num>=0 ?? $num :: -$num } sub accept($new is IO::Socket, $gen is IO::Socket){ UNIMP("accept") } sub alarm($seconds is int){ UNIMP("alarm") } sub atan2($y is number, $x is number) { UNIMP("atan2") } sub bind($socket is IO::Socket, $name) { UNIMP("bind") } sub binmode($fh is IO::Handle, $disc //= ':raw'){ UNIMP("binmode") } sub bless($ref, $name //= undef){ NEVER("bless") } sub caller($expr //= undef){ UNIMP("caller") } sub chdir($path //= $ENV{HOME}){ UNIMP("chdir") } sub chmod($mode is int, *@paths){ for @paths -> $_ { UNIMP("chmod $mode, $_") } # XXX - Return value? } sub chomp($string is rw){ my $irs = $ {"/"}; if defined $irs { if $irs.isa(Object) { return undef; } elsif $irs.length == 0 { $string =~ s/ \n+ $ //; return $0; } else { $string =~ s/<{"<[$irs]>"}>+$//; return $0; } } } sub chomp() { UNIMP("chomp(LIST)") } sub chomp(*@strings is rw) { UNIMP("chomp(LIST)") } sub chop($string is rw) { UNIMP("chop") } sub chop() { UNIMP("chop") } sub chop(*@strings) { UNIMP("chop") } sub chown($uid is int, $gid is int, *@files) { for @files -> $_ { UNIMP("chown $uid, $gid, $_"); } # XXX Return value? } sub chr($num is int //= $_){ return pack 'C', $num } # XXX Not UNICODE sub chroot($path //= $_){ UNIMP("chroot") } sub close($fh is IO::Handle //= "XXX_defaulthandle") { UNIMP("close") } sub closedir($dh is IO::DirHandle) { UNIMP("closedir") } sub connect($socket is IO:Socket, $name) { UNIMP("connect") } sub cos($num is number //= $_) { UNIMP("cos") } sub acos($num is number //= $_) { atan2( sqrt(1 - ($num ** 2)), $num ) } sub tan($num is number //= $_) { return sin($num) / cos($num) } sub cos($num is number //= $_) { UNIMP("cos") } sub crypt($plaintext, $salt) { UNIMP("crypt") } sub dbmclose(%hash) { NEVER("dbmclose") } sub dbmopen(%hash, $dbname, $mask) { NEVER("dbmopen") } # INTERNAL defined # INTERNAL delete # INTERNAL die # INTERNAL do sub dump($label //= $_) { NEVER("dump") } # INTERNAL each sub eof($fh is IO::Handle //= "XXX_defaulthandle") { UNIMP("eof") } sub eval(&code) { warn "Perl 6 uses try for blocks"; return try(&code); } # INTERNAL eval(string) sub exec($program, *@args) { UNIMP("exec") } # XXX exec $prog $argv0, $argv1... # INTERNAL exists # INTERNAL exit sub exp($num is number //= $_) { UNIMP("exp") } sub fcntl($fh is IO::Handle, $func, $scalar) { UNIMP("fcntl") } sub fileno($fh is IO::Handle //= "XXX_defaulthandle") { UNIMP(fileno) } sub flock($fh is IO::Handle, $operation) { UNIMP("flock") } sub fork() { UNIMP("fork") } sub format() { NEVER("format") } sub formline($picture, *@list) { NEVER("formline") } sub getc($fh is IO::Handle //= "XXX_defaulthandle") { UNIMP("getc") } sub getlogin() { UNIMP("getlogin") } sub getpeername($socket is IO::Socket) { UNIMP("getpeername") } sub getpgrp($pid is int) { UNIMP("getpgrp") } sub getppid() { UNIMP("getppid") } sub getpriority($which is int, $who is int) { UNIMP("getpriority") } sub getpwnam($name) { UNIMP("getpwnam") } sub getgrnam($name) { UNIMP("getgrnam") } sub gethostbyname($name) { UNIMP("gethostbyname") } sub getnetbyname($name) { UNIMP("getnetbyname") } sub getprotobyname($name) { UNIMP("getprotobyname") } sub getpwuid($uid is int) { UNIMP("getpwuid") } sub getgrgid($gid is int) { UNIMP("getgrgid") } sub getservbyname($name, $proto) { UNIMP("getservbyname") } sub gethostbyaddr($addr, $addrtype) { UNIMP("gethostbyaddr") } sub getnetbyaddr($addr, $addrtype) { UNIMP("getnetbyaddr") } sub getprotobynumber($number is int) { UNIMP("getprotobynumber") } sub getservbyport($port is int, $proto) { UNIMP("getservbyport") } sub getpwent() { UNIMP("getpwent") } sub getgrent() { UNIMP("getgrent") } sub gethostent() { UNIMP("gethostent") } sub getnetent() { UNIMP("getnetent") } sub getprotoent() { UNIMP("getprotoent") } sub getservent() { UNIMP("getservent") } sub setpwent() { UNIMP("setpwent") } sub setgrent() { UNIMP("setgrent") } sub sethostent($stayopen is bool) { UNIMP("sethostent") } sub setnetent($stayopen is bool) { UNIMP("setnetent") } sub setprotoent($stayopen is bool) { UNIMP("setprotoent") } sub setservent($stayopen is bool) { UNIMP("setservent") } sub endpwent() { UNIMP("endpwent") } sub endgrent() { UNIMP("endgrent") } sub endhostent() { UNIMP("endhostent") } sub endnetent() { UNIMP("endnetent") } sub endprotoent() { UNIMP("endprotoent") } sub endservent() { UNIMP("endservent") } sub getsockname($socket is IO::Socket) { UNIMP("getsockname") } sub getsockopt($socket is IO::Socket,$level,$optname) { UNIMP("getsockopt") } sub glob($string //= $_) { UNIMP("glob") } sub gmtime($unixtime is number) { UNIMP("gmtime") } # INTERNAL goto sub grep(&code, *@list) { my @newlist; for @list -> $_ { push @newlist, $_ if &code(); # XXX - How does code get $_? } return @newlist; } sub hex($string) { my($tmp) = ($string =~ /^[0x]?(<[a-fA-F0-9]>+)/); return 0 unless defined($hex) && $hex.length; my $bit = 0; my $result = 0; for(my $i = $tmp.length-1;$i>=0;$i--) { my $n = substr($tmp,$i,1); given $n { when 'a' .. 'f', 'A' .. 'F' { $n = ord(lc $n)-ord('a')+10; } when '0' .. '9' { $n = +$n; } } $result += $n * (16**$bit++); } return $tmp; } sub index($string, $substr, $pos is int //= 0) { # XXX - slow dumb way for(my $i = $pos; $i < $string.length; $i++) { return $i if substr($string,$i,$substr.length) eq $substr; } return -1; } sub int($num is int //= $_) { $num } sub ioctl($fh is IO::Handle,$function,$scalar) { UNIMP("ioctl") } sub join($sep, *@list) { return '' unless @list.length; my $result = @list[0]; for(my $i=1;$i <= @list.length;$i++) { $result _= $sep _ @list[$i]; } return $result; } # INTERNAL keys sub kill($signal, *@procs) { UNIMP("kill") } # INTERNAL last sub lc($string //= $_) { $string =~ tr/A-Z/a-z/; } # XXX NOT UNICODE sub lcfirst($string //= $_) { given $string.length { 0 { return '' } 1 { return lc $string } default { return lc($string[0]) _ substr($string,1) } } } sub length($string //= $_) { return $string.length } sub link($oldfile,$newfile) { UNIMP("link") } sub listen($socket is IO::Socket,$queuesize) { UNIMP("listen") } sub local($var) { NEVER("local") } sub localtime($thetime //= time()) { UNIMP("localtime") } # INTERNAL lock sub log($num is int) { UNIMP("log") } sub log10($num is int) { return log($num)/log(10) } sub lstat($fh is IO::Handle) { UNIMP("lstat") } sub lstat($path //= $_) { UNIMP("lstat") } # INTERNAL m sub map(&code, *@list) { my @result; for @list -> $_ { push @result, &code(); # XXX how does &code get $_ } return @result; } sub mkdir($file, $mask is int //= 0777) { UNIMP("mkdir") } sub msgctl($id,$cmd,$arg) { UNIMP("msgctl") } sub msgget($key,$flags) { UNIMP("msgget") } sub msgrcv($id,$var,$size,$type,$flags) { UNIMP("msgrcv") } sub msgsnd($id,$msg,$flags) { UNIMP("msgsnd") } # INTERNAL my # INTERNAL next # INTERNAL no sub oct($string //= $_) { given $string { # XXX - handle "0b" when /^0x/ { return hex($string); } default { my $return = 0; my $bit = 0; for(my $i = $tmp.length-1;$i>=0;$i--) { my $n = substr($tmp,$i,1); # Avoid overflow for leading 0 $return += $n * (8**$bit++) if $n; } return $return; } } } sub open(*@args) { NEVER("open") } # XXX Will handle objects be forced? sub opendir(*@args) { NEVER("opendir") } # XXX see open sub ord($char //= $_) { return unpack 'C', $char } # INTERNAL our sub pack($template,*@args) { UNIMP("pack") } # INTERNAL package sub pipe($readhandle,$writehandle) { UNIMP("pipe") } # XXX gone? sub pop(@list) { return undef if @list.length == 0; return delete @list[@list.length - 1]; } sub pos($scalar //= $_) { NEVER("pos") } # pos is now a method on $0 # INTERNAL print sub printf($format, *@list) { print(sprintf($format, *@list)) } sub prototype($function) { UNIMP("prototype") } sub push(@array,*@list) { for @list -> $_ { @array[@array.length] = $_; } } # INTERNAL q, qq, qw # XXX - how do I do quote-like operators? I know I saw someone say... # Need to do: qr (NEVER("qr")) and qx sub quotemeta($string //= $_) { $string =~ s:each/(\W)/\\$1/ } # XXX ? sub rand($num is int //= 1) { UNIMP("rand") } sub read($fh,$buf,$len,$off //= 0) { UNIMP("read") } sub readdir($dh is IO::DirHandle) { UNIMP("readdir") } sub readline($fh is IO::Handle) { UNIMP("readline") } sub readlink($path //= $_) { UNIMP("readlink") } sub readpipe($command) { UNIMP("readpipe") } sub recv($socket is IO::Socket,$buf,$len,$flags) { UNIMP("recv") } # INTERNAL redo sub ref($scalar //= $_) { UNIMP("ref") } # XXX Never? sub rename($oldname,$newname) { UNIMP("rename") } sub reset($tmp //= $_) { NEVER("reset") } # INTERNAL return sub reverse(@list) { my @r; my $last = @list.length - 1; for(my $i=$last;$i >= 0;$i++) { @r[$last-$i] = @list[$i]; } return *@r; } sub reverse(*@list) { return reverse @list } sub rewinddir($dh is IO::DirHandle) { UNIMP("rewinddir") } sub rindex($string, $substr, $pos //= 0) { # XXX - slow dumb way for(my $i = $string.length-1; $i >= $pos; $i--) { return $i if substr($string,$i,$substr.length) eq $substr; } return -1; } sub rmdir($path //= $_) { UNIMP("rmdir") } # INTERNAL s sub scalar($value) { return $value } sub seek($fh is IO::Handle,$pos, $whence) { UNIMP("seek") } sub seekdir($dh is IO::DirHandle,$pos is int) { UNIMP("seekdir") } sub select($fh) { UNIMP("select") } sub select() { UNIMP("select") } sub select($rbits,$wbits,$ebits,$timeout is number) { UNIMP("select") } sub semctl($id,$semnum,$cmd,$arg) { UNIMP("semctl") } sub semget($key,$nsems,$flags) { UNIMP("semget") } sub semop($key,$opstring) { UNIMP("semop") } sub send($socket is IO::Socket,$msg,$flags,$to //= undef) { UNIMP("send") } sub setpgrp($pid,$pgrp) { UNIMP("setpgrp") } sub setpriority($which,$who,$priority) { UNIMP("setpriority") } sub setsockopt($socket is IO::Socket,$level,$optname,$optval) { UNIMP("setsockopt") } sub shift(@list) { return undef if @list.length == 0; return delete @list[@list.length-1]; } sub shmctl($id,$cmd,$arg) { UNIMP("shmctl") } sub shmget($key,$size,$flags) { UNIMP("shmget") } sub shmread($id,$var,$pos,$size) { UNIMP("shmread") } sub shmwrite($id,$string,$pos,$size) { UNIMP("shmwrite") } sub shutdown($socket is IO::Socket,$how is int) { UNIMP("shutdown") } sub sin($num is number //= $_) { UNIMP("sin") } sub asin($num is number //= $_) { atan2($num, sqrt(1 - $num * $num)) } # INTERNAL sleep #sub sleep($seconds is int) { UNIMP("sleep") } sub sleep() { UNIMP("sleep") } # Never wake up sub socket($socket is IO::Socket is rw,$domain,$type,$protocol) { UNIMP("socket") } sub socketpair($socket1,$socket2,$domain,$type,$protocol) { NEVER("socketpair") } sub sort(&code, @list) { UNIMP("sort") } sub sort(&code, *@list) { return sort &code, @list } sub sort(*@list) { return sort sub($a,$b){$a cmp $b}, @list } sub splice(@array,$off is int //= 0,$len is int //= undef, *@list) { # XXX - A9 is supposed to tell us how slicing works! if !defined($len) || $len > (@array.length-$off) { $len = @array.length-$off; } # XXX - Too tired to type -ajs UNIMP("splice"); # return @old; } sub split(rx $pat,$string //= $_, $limit //= undef) { # XXX - split may just fall out of regex syntax.. more thought needed UNIMP("split"); } sub split($match //= undef, $string //= $_, $limit //= undef) { $match = (defined($match) ?? rx/$match/ :: rx/\s+/); return split $match, $string, $limit; } sub sprintf($format, *@list) { UNIMP("sprintf") } sub sqrt($num is number //= $_) { UNIMP("sqrt") } sub srand($seed is int //= undef) { UNIMP("srand") } sub stat($path //= $_) { UNIMP("stat") } sub study($scalar //= $_) { NEVER("study") } # INTERNAL sub # INTERNAL substr sub symlink($oldfile,$newfile) { UNIMP("symlink") } sub syscall(*@list) { UNIMP("syscall") } sub sysopen(*@list) { UNIMP("sysopen") } sub sysread(*@list) { UNIMP("sysread") } sub sysseek(*@list) { UNIMP("sysseek") } # XXX system($program @list) sub system(*@list) { UNIMP("system") } sub syswrite(*@list) { UNIMP("syswrite") } sub tell($fh is IO::Handle //= "XXX_defaulthandle") { UNIMP("tell") } sub telldir($dh is IO::DirHandle) { UNIMP("telldir") } # XXX tie, tied?? # INTERNAL time sub times() { UNIMP("times") } # XXX tr?? sub truncate($fh is IO::Handle,$len) { UNIMP("truncate") } sub truncate($path,$len) { UNIMP("truncate") } sub uc($string //= $_) { $string =~ tr/a-z/A-Z/; } # XXX NOT UNICODE sub ucfirst($string //= $_) { given $string.length { 0 { return '' } 1 { return uc $string } default { return uc($string[0]) _ substr($string,1) } } } sub umask($newmask is int) { UNIMP("umask") } sub umask() { UNIMP("umask") } # INTERNAL undef sub unlink($path //= $_) { UNIMP("unlink") } sub unpack($template,$value) { UNIMP("unpack") } sub untie($var) { UNIMP("untie") } sub unshift(@array is rw,*@list) { @array = (*@list, *@array) } # INTERNAL use sub utime(@paths) { UNIMP("utime") } sub utime(*@paths) { utime(@paths) } # INTERNAL values sub vec($bitvec,$off is int,$bits is int) { UNIMP("vec") } sub wait() { UNIMP("wait") } sub waitpid($pid is int,$flags is int) { UNIMP("waitpid") } # INTERNAL wantarray sub warn(*@list) { UNIMP("warn") } sub write() { NEVER("write") } # INTERNAL y