Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge remote branch 'origin/master' into serialize

  • Loading branch information...
commit 94e9968941f9956fc37a72fb4981dcbc4a7240d3 2 parents 8a35c4f + 5be99bf
@sorear authored
View
2  FETCH_URL
@@ -1 +1 @@
-https://github.com/downloads/sorear/niecza/niecza-9.zip
+https://github.com/downloads/sorear/niecza/niecza-10.zip
View
10 Makefile
@@ -7,7 +7,8 @@ RM=rm -f
CP=cp
cskernel=Kernel.cs Builtins.cs Cursor.cs JSYNC.cs NieczaCLR.cs Utils.cs \
- ObjModel.cs BigInteger.cs Printf.cs CodeGen.cs
+ ObjModel.cs BigInteger.cs Printf.cs CodeGen.cs \
+ GeneratedTrigFunctions.cs
# Tell make to regard the following targets as not being filenames
.PHONY: all aot test spectest clean realclean
@@ -51,6 +52,13 @@ obj/Kernel.dll: $(patsubst %,lib/%,$(cskernel))
$(CSC) /target:library /out:obj/Kernel.dll /lib:obj /unsafe+ \
$(patsubst %,lib/%,$(cskernel))
+perl5: obj/Perl5Interpreter.dll obj/p5embed.so
+obj/Perl5Interpreter.dll: obj/Kernel.dll lib/Perl5Interpreter.cs
+ gmcs /target:library /lib:obj /out:obj/Perl5Interpreter.dll /r:Kernel.dll lib/Perl5Interpreter.cs
+
+obj/p5embed.so: lib/p5embed.c
+ cc -shared -Wl,-soname,p5embed.so -o obj/p5embed.so lib/p5embed.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
+
aot: all
mono --aot run/*.dll run/Niecza.exe
View
83 docs/announce.v10
@@ -0,0 +1,83 @@
+ Announce: Niecza Perl 6 v10
+
+This is the tenth release of Niecza Perl 6, as usual scheduled on
+the last Monday of the month.
+
+You can obtain a build of Niecza from [1]. This build contains a
+working compiler as a set of .exe and .dll files suitable for use with
+Mono or Microsoft .NET. If you wish to follow latest developments,
+you can obtain the source from [2]; however, you will still need a
+binary for bootstrapping, so you gain nothing from a "source is
+better" perspective.
+
+Niecza is a Perl 6 compiler project studying questions about the
+efficient implementability of Perl 6 features. It currently targets
+the Common Language Runtime; both Mono and Microsoft .NET are known to
+work. On Windows, Cygwin is required for source builds only; see the
+README for details.
+
+
+ List of changes
+
+
+
+[Major features]
+
+CLR interoperation is now fairly well supported! You can create
+objects, call methods, get and set fields and properties, create
+delegates, etc from Perl 6 code. See examples/ for usage ideas.
+(Examples by Martin Berends)
+
+The Mono.Posix dependency has been relaxed from load time to run
+time, meaning .NET support is back if you don't use file tests.
+
+
+
+[Minor new features]
+
+\qq[] syntax is now implemented.
+
+qp|| now returns a path object.
+
+New Test.pm6 methods succeeds_ok and fails_ok (and eval_ variants) to
+catch warnings. (Design by flussence)
+
+@foo? and %foo? in signatures are now correctly supported.
+
+Many more trig functions now implemented. (Solomon Foster)
+
+Standard grammar has been updated, in particular bringing the new
+concept of regex separators; x ** y is now spelled x+ % y. Do
+not expect other forms of % and %% to work just yet.
+
+
+
+[Selected bug fixes]
+
+sqrt now returns the correct value for arguments with a negative
+imaginary part. Also sqrt(0) returns Num not Complex now.
+
+
+
+[Other]
+
+docs/compiler.pod is more current. (Martin Berends)
+
+Prototyping has begun on Perl 5 interoperation. (Paweł Murias)
+
+
+ Getting involved
+
+Contact sorear in irc.freenode.net #perl6 or via the sender address of
+this mailing. Also check out the TODO file; whether you want to work
+on stuff on it, or have cool ideas to add to it, both are good.
+
+ Future directions
+
+I have an active branch (started this month) to unify compile-time and
+run-time metamodel representations, using serialization to bridge the
+gap. It doesn't work yet, but when it does it will enable many
+improvements, most importantly real support for BEGIN and roles.
+
+[1] https://github.com/downloads/sorear/niecza/niecza-10.zip
+[2] https://github.com/sorear/niecza
View
86 examples/gtk-clock.pl
@@ -0,0 +1,86 @@
+# Main documentation: http://docs.go-mono.com, particularly
+# Gnome (for Gdk and Gtk) and Mono (for Cairo) libraries.
+# See also: The X-Windows Disaster at http://www.art.net/~hopkins/Don/unix-haters/handbook.html
+
+constant $GTK = "gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f";
+constant $GDK = "gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f";
+constant $GLIB = "glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f";
+# use 'gacutil -l' to look up similar module details
+
+constant Application = CLR::("Gtk.Application,$GTK");
+constant Window = CLR::("Gtk.Window,$GTK");
+constant GdkCairoHelper = CLR::("Gdk.CairoHelper,$GDK");
+constant GtkDrawingArea = CLR::("Gtk.DrawingArea,$GTK");
+constant GLibTimeout = CLR::("GLib.Timeout,$GLIB");
+
+Application.Init;
+my $window = Window.new("clock");
+my $windowSizeX = 200; my $windowSizeY = 200;
+$window.Resize($windowSizeX, $windowSizeY);
+my $drawingarea = GtkDrawingArea.new;
+$drawingarea.add_ExposeEvent: sub ($obj, $args) {
+ $args; # suppress 'declared but not used' warnings
+ my $cc = GdkCairoHelper.Create($obj.GdkWindow); # Cairo Context
+ # TODO: the following two lines pass parameters by value, need to pass by references to integers
+ my $windowX=0; my $windowY=0; my $windowWidth=0; my $windowHeight=0; my $windowDepth=0;
+ $obj.GdkWindow.GetGeometry($windowX, $windowY, $windowWidth, $windowHeight, $windowDepth);
+ $cc.SetSourceRGB(0.95.Num, 0.90.Num, 0.85.Num); $cc.Paint; # background color
+ ClockFace($cc, $windowWidth, $windowHeight);
+ # Calculate the parameters needed to draw the clock
+ my $hour = ((now.to-posix[0] % (12*3600))/3600); # there must be a more elegant way...
+ my $minute = ((now.to-posix[0] / 60) % 60);
+ my $maxRadius = ($windowWidth min $windowHeight)/2;
+ my $linewidth = ($maxRadius * 0.03).Int max 1;
+ my $radiusHour = $maxRadius * 0.5;
+ my $radiusMinute = $maxRadius * 0.7;
+ # Draw the hands of the clock
+ my $radiansHour = $hour / 12 * pi * 2;
+ my $radiansMinute = $minute / 60 * pi * 2;
+ my $xCenter = $windowWidth / 2; my $yCenter = $windowHeight / 2;
+ my $xHour = $xCenter + $radiusHour * sin($radiansHour);
+ my $yHour = $yCenter + $radiusHour * sin($radiansHour - pi / 2);
+ my $xMinute = $xCenter + $radiusMinute * sin($radiansMinute);
+ my $yMinute = $yCenter + $radiusMinute * sin($radiansMinute - pi / 2);
+ $cc.LineWidth = $linewidth;
+ $cc.MoveTo($xMinute.Int,$yMinute.Int);
+ $cc.LineTo($xCenter.Int,$yCenter.Int);
+ $cc.LineTo($xHour.Int,$yHour.Int);
+ $cc.Arc($xCenter.Int,$yCenter.Int,$linewidth.Int,0,7); # from 0 radians to more than 2*pi
+ $cc.Stroke;
+ $cc.Target.Dispose;
+ $cc.dispose-hack; # Should be $cc.Dispose but CLR interop cannot call that
+ # Tracked as https://github.com/sorear/niecza/issues/56
+};
+GLibTimeout.Add: 60000, sub () { # Update once per minute
+ $drawingarea.QueueDrawArea(0,0,$windowSizeX,$windowSizeY);
+ return True; # meaning please continue calling this timeout handler
+};
+$window.add_DeleteEvent: sub ($obj, $args) {
+ $obj; $args; # suppress "declared but not used" Potential difficulties
+ Application.Quit;
+};
+$window.Add($drawingarea);
+$window.ShowAll;
+Application.Run;
+
+sub ClockFace($cc, $width, $height)
+{
+ # Calculate dimensions relative to window size
+ my $maxRadius = ($width min $height) / 2;
+ my $centerX = $width / 2;
+ my $centerY = $height / 2;
+ my $lineWidth = ($maxRadius * 0.025).Int max 1;
+ # Draw the outer circle
+ $cc.SetSourceRGB(0.7.Num, 0, 0); # dark red
+ $cc.LineWidth = $lineWidth;
+ $cc.Arc($centerX.Int, $centerY.Int, ($maxRadius - $lineWidth).Int, 0, 7);
+ $cc.Stroke();
+ # Write the clock name on its face
+ my $clockName = "it's Niecza time!";
+ $cc.SetSourceRGB(0.7.Num, 0, 0); # dark red
+ $cc.SetFontSize(($maxRadius * 0.15).Int);
+ my $textWidth = $cc.TextExtents($clockName).Width;
+ $cc.MoveTo(($width/2 - $textWidth/2).Int, ($height * 0.85).Int);
+ $cc.ShowText($clockName);
+ $cc.Stroke();
+}
View
80 examples/gtk-sierpinski.pl
@@ -0,0 +1,80 @@
+# Main documentation: http://docs.go-mono.com, particularly
+# Gnome (for Gdk and Gtk) and Mono (for Cairo) libraries.
+# See also: The X-Windows Disaster at http://www.art.net/~hopkins/Don/unix-haters/handbook.html
+
+constant $GTK = "gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f";
+constant $GDK = "gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f";
+# use 'gacutil -l' to look up similar module details
+
+constant Application = CLR::("Gtk.Application,$GTK");
+constant Window = CLR::("Gtk.Window,$GTK");
+constant GdkCairoHelper = CLR::("Gdk.CairoHelper,$GDK");
+constant GtkDrawingArea = CLR::("Gtk.DrawingArea,$GTK");
+
+Application.Init;
+my $window = Window.new("sierpinski");
+my $windowSizeX = 640; my $windowSizeY = 560;
+$window.Resize($windowSizeX, $windowSizeY); # TODO: resize at runtime NYI
+my $drawingarea = GtkDrawingArea.new;
+$drawingarea.add_ExposeEvent(&ExposeEvent);
+$window.add_DeleteEvent(&DeleteEvent);
+$window.Add($drawingarea);
+$window.ShowAll;
+Application.Run; # end of main program, it's all over when this returns
+
+sub DeleteEvent($obj, $args) {
+ $obj; $args; # suppress "declared but not used" "Potential difficulties"
+ Application.Quit;
+};
+
+sub ExposeEvent($obj, $args)
+{
+ $args; # suppress "declared but not used" "Potential difficulties"
+ my $cc = GdkCairoHelper.Create($obj.GdkWindow); # Cairo Context
+ # TODO: the following two lines pass parameters by value, need to pass by references to integers
+ # my $windowX; my $windowY; my $windowWidth; my $windowHeight; my $windowDepth;
+ # $obj.GdkWindow.GetGeometry($windowX, $windowY, $windowWidth, $windowHeight, $windowDepth);
+ # Tracked as https://github.com/sorear/niecza/issues/57
+ # TODO: remove the following one line cheat that works around the above problem
+ my $windowWidth = $windowSizeX; my $windowHeight = $windowSizeY;
+ $cc.SetSourceRGB(0.6, 1, 0.6); $cc.Paint; # pale green background
+ # Start the recursive drawing process
+ my $x0=0; my $y0=0; my $x1=$windowWidth-1; my $y1=$windowHeight/2;
+ my $x2=0; my $y2=$windowHeight-1;
+ my $depth = Sierpinski($cc, $x0, $y0, $x1, $y1, $x2, $y2, True, 1);
+ my $text = sprintf("%d x %d, %d levels", $windowWidth, $windowHeight, $depth);
+ $cc.SetSourceRGB(0.6, 0.6, 1); # pale blue
+ $cc.SetFontSize($windowWidth * 0.07);
+ my $textWidth = $cc.TextExtents($text).Width;
+ my $textHeight = $cc.TextExtents($text).Height;
+ $cc.MoveTo($windowWidth*0.98 - $textWidth, $windowHeight*0.01 + $textHeight);
+ $cc.ShowText($text);
+ $cc.Target.Dispose;
+ $cc.dispose-hack; # Should be $cc.Dispose but CLR interop cannot call that
+ # Tracked as https://github.com/sorear/niecza/issues/56
+};
+
+sub Sierpinski($cc, $x0, $y0, $x1, $y1, $x2, $y2, $colorflag, $depth is copy)
+{
+ if $colorflag { $cc.SetSourceRGB(0.6, 0, 0.8); } # indigo
+ else { $cc.SetSourceRGB( 1, 1, 0.8); } # pale yellow
+ # First draw the entire main triangle in the one color
+ $cc.MoveTo($x0, $y0); $cc.LineTo($x1, $y1);
+ $cc.LineTo($x2, $y2); $cc.LineTo($x0, $y0);
+ $cc.Fill;
+ $cc.Stroke;
+ if (($x1-$x0)>2) && (($y2-$y0)>2) { # Prepare to recurse
+ ++$depth;
+ # Calculate the midpoints of the 3 edges of the triangle
+ # note - these .Int conversions make a very big speed difference
+ my $x01=(($x0+$x1)/2).Int; my $y01=(($y0+$y1)/2).Int;
+ my $x12=(($x1+$x2)/2).Int; my $y12=(($y1+$y2)/2).Int;
+ my $x20=(($x2+$x0)/2).Int; my $y20=(($y2+$y0)/2).Int;
+ # Recursively draw three smaller triangles in the other color
+ Sierpinski($cc, $x0, $y0, $x01,$y01, $x20,$y20, !$colorflag, $depth);
+ Sierpinski($cc, $x01,$y01, $x1, $y1, $x12,$y12, !$colorflag, $depth);
+ $depth =
+ Sierpinski($cc, $x20,$y20, $x12,$y12, $x2, $y2, !$colorflag, $depth);
+ }
+ $depth;
+}
View
21 examples/perl5.pl
@@ -0,0 +1,21 @@
+eval(q:to/PERL5/,:lang<perl5>);
+ print "Hel"."lo ";
+ PERL5
+eval(q:to/PERL5/,:lang<perl5>);
+ print "World\n";
+ PERL5
+
+eval(q:to/PERL5/,:lang<perl5>);
+use strict;
+use warnings;
+package Foo;
+sub baz {
+ my ($self,$arg) = @_;
+ print "Just another $arg\n";
+}
+sub new {
+ bless {},"Foo";
+}
+PERL5
+my $foo = eval(:lang<perl5>,'Foo->new');
+$foo.baz(eval(:lang<perl5>,'"Perl hacker"'));
View
42 lib/Builtins.cs
@@ -7,6 +7,9 @@
using System.Runtime.CompilerServices;
namespace Niecza {
+ public interface IForeignInterpreter {
+ Variable Eval(string code);
+ }
class PosixWrapper {
static Assembly Mono_Posix;
static Type Syscall, AccessModes, Stat;
@@ -490,6 +493,10 @@ class SubstrLValue: Variable {
return Kernel.BoxAnyMO(str, Kernel.StrMO);
}
+ public static Variable MakeComplex(Complex z) {
+ return Kernel.BoxAnyMO<Complex>(z, Kernel.ComplexMO);
+ }
+
public static Variable MakeParcel(params Variable[] bits) {
return Kernel.NewRWListVar(Kernel.BoxRaw(bits, Kernel.ParcelMO));
}
@@ -878,22 +885,19 @@ class SubstrLValue: Variable {
}
}
- static Func<Variable,Variable> sin_d = sin;
- public static Variable sin(Variable a1) {
+ static Func<Variable,Variable,Variable> atan2_d = atan2;
+ public static Variable atan2(Variable a1, Variable a2) {
P6any o1 = a1.Fetch();
int r1;
- if (!o1.mo.is_any)
- return HandleSpecial1(a1,o1, sin_d);
P6any n1 = GetNumber(a1, o1, out r1);
+ P6any o2 = a2.Fetch();
+ int r2;
+ P6any n2 = GetNumber(a2, o2, out r2);
- if (r1 == NR_COMPLEX) {
- Complex v1 = PromoteToComplex(r1, n1);
- return MakeComplex(Math.Sin(v1.re) * Math.Cosh(v1.im),
- Math.Cos(v1.re) * Math.Sinh(v1.im));
- }
{
double v1 = PromoteToFloat(r1, n1);
- return MakeFloat(Math.Sin(v1));
+ double v2 = PromoteToFloat(r2, n2);
+ return MakeFloat(Math.Atan2(v1, v2));
}
}
@@ -940,6 +944,24 @@ class SubstrLValue: Variable {
return Kernel.NewROScalar(n1);
}
+ static Func<Variable,Variable> eval_perl5_d = eval_perl5;
+ static IForeignInterpreter p5_interpreter;
+ public static Variable eval_perl5(Variable v) {
+
+ // Cargo culted to get the string from the argument
+ P6any o1 = v.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(v,o1, eval_perl5_d);
+ string r = o1.mo.mro_raw_Str.Get(v);
+
+ if (p5_interpreter == null) {
+ System.Reflection.Assembly a = System.Reflection.Assembly.Load("Perl5Interpreter");
+ p5_interpreter = (IForeignInterpreter) a.CreateInstance("Perl5Interpreter");
+ }
+ return p5_interpreter.Eval(r);
+ }
+
// we don't need to do nominal checking stuff here because this
// is in a method, never inlined, and as such the binder had to
// already have been called.
View
57 lib/CORE.setting
@@ -160,6 +160,30 @@ my class Cool {
multi method log() { self.ln }
multi method log($base) { self.ln / $base.ln }
method sin() { Q:CgOp { (sin {self}) } }
+ method asin() { Q:CgOp { (asin {self}) } }
+ method cos() { Q:CgOp { (cos {self}) } }
+ method acos() { Q:CgOp { (acos {self}) } }
+ method tan() { Q:CgOp { (tan {self}) } }
+ method atan() { Q:CgOp { (atan {self}) } }
+ method sec() { Q:CgOp { (sec {self}) } }
+ method asec() { Q:CgOp { (asec {self}) } }
+ method cosec() { Q:CgOp { (cosec {self}) } }
+ method acosec() { Q:CgOp { (acosec {self}) } }
+ method cotan() { Q:CgOp { (cotan {self}) } }
+ method acotan() { Q:CgOp { (acotan {self}) } }
+ method sinh() { Q:CgOp { (sinh {self}) } }
+ method asinh() { Q:CgOp { (asinh {self}) } }
+ method cosh() { Q:CgOp { (cosh {self}) } }
+ method acosh() { Q:CgOp { (acosh {self}) } }
+ method tanh() { Q:CgOp { (tanh {self}) } }
+ method atanh() { Q:CgOp { (atanh {self}) } }
+ method sech() { Q:CgOp { (sech {self}) } }
+ method asech() { Q:CgOp { (asech {self}) } }
+ method cosech() { Q:CgOp { (cosech {self}) } }
+ method acosech() { Q:CgOp { (acosech {self}) } }
+ method cotanh() { Q:CgOp { (cotanh {self}) } }
+ method acotanh() { Q:CgOp { (acotanh {self}) } }
+ method atan2($x = 1) { Q:CgOp { (atan2 {self} {$x}) } }
method split($matcher, $limit?, :$all?) {
my $matchrx = (($matcher ~~ Regex) ?? $matcher !! /$matcher/);
@@ -1873,6 +1897,7 @@ sub round($x, $scale=1) { floor($x / $scale + 0.5) * $scale }
sub truncate($x) { $x.Int }
sub sign($x) { $x < 0 ?? -1 !! $x > 0 ?? 1 !! 0 }
sub sqrt($x) { Q:CgOp { (sqrt {$x}) } }
+sub exp($x) { $x.exp }
# XXX 'Order' type
sub infix:« <=> » is equiv<leg> ($a, $b) { $a < $b ?? -1 !! $a > $b ?? 1 !! 0 }
# XXX polymorphic equality
@@ -1908,7 +1933,13 @@ sub infix:« ==>> »(\|$args) { die "Feed ops NYI" } #OK
sub infix:« <== »(\|$args) { die "Feed ops NYI" } #OK
sub infix:« <<== »(\|$args) { die "Feed ops NYI" } #OK
-sub eval($str) is return-pass { Q:CgOp { (simple_eval {$str}) } }
+sub eval($str,:$lang="perl6") is return-pass {
+ if $lang eq "perl6" {
+ Q:CgOp { (simple_eval {$str}) }
+ } else {
+ Q:CgOp { (eval_perl5 {$str}) }
+ }
+}
sub rungather($ ) { die "Run NYI" }
# }}}
@@ -2039,6 +2070,30 @@ sub prompt($msg) { print $msg; $*IN.get }
sub getc($handle) { $handle.getc }
sub sin($x) { $x.sin }
+sub asin($x) { $x.asin }
+sub cos($x) { $x.cos }
+sub acos($x) { $x.acos }
+sub tan($x) { $x.tan }
+sub atan($x) { $x.atan }
+sub sec($x) { $x.sec }
+sub asec($x) { $x.asec }
+sub cosec($x) { $x.cosec }
+sub acosec($x) { $x.acosec }
+sub cotan($x) { $x.cotan }
+sub acotan($x) { $x.acotan }
+sub sinh($x) { $x.sinh }
+sub asinh($x) { $x.asinh }
+sub cosh($x) { $x.cosh }
+sub acosh($x) { $x.acosh }
+sub tanh($x) { $x.tanh }
+sub atanh($x) { $x.atanh }
+sub sech($x) { $x.sech }
+sub asech($x) { $x.asech }
+sub cosech($x) { $x.cosech }
+sub acosech($x) { $x.acosech }
+sub cotanh($x) { $x.cotanh }
+sub acotanh($x) { $x.acotanh }
+sub atan2($y, $x = 1) { $y.atan2($x) }
INIT {
$PROCESS::IN ::= Q:CgOp { (box TextReader (treader_stdin)) };
View
498 lib/GeneratedTrigFunctions.cs
@@ -0,0 +1,498 @@
+// DO NOT EDIT! Autogenerated file, created by tools/make_trig_code.pl.
+using Niecza;
+using System;
+
+public partial class Builtins {
+
+ static Func<Variable,Variable> sin_d = sin;
+ public static Variable sin(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, sin_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Sin());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Sin(v1));
+ }
+ }
+
+ static Func<Variable,Variable> asin_d = asin;
+ public static Variable asin(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, asin_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Asin());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Asin(v1));
+ }
+ }
+
+ static Func<Variable,Variable> cos_d = cos;
+ public static Variable cos(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, cos_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Cos());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Cos(v1));
+ }
+ }
+
+ static Func<Variable,Variable> acos_d = acos;
+ public static Variable acos(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, acos_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Acos());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Acos(v1));
+ }
+ }
+
+ static Func<Variable,Variable> tan_d = tan;
+ public static Variable tan(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, tan_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Tan());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Tan(v1));
+ }
+ }
+
+ static Func<Variable,Variable> atan_d = atan;
+ public static Variable atan(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, atan_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Atan());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Atan(v1));
+ }
+ }
+
+ static Func<Variable,Variable> sinh_d = sinh;
+ public static Variable sinh(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, sinh_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Sinh());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Sinh();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> asinh_d = asinh;
+ public static Variable asinh(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, asinh_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Asinh());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Asinh();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> cosh_d = cosh;
+ public static Variable cosh(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, cosh_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Cosh());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Cosh();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> acosh_d = acosh;
+ public static Variable acosh(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, acosh_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Acosh());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Acosh();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> tanh_d = tanh;
+ public static Variable tanh(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, tanh_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Tanh());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Tanh();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> atanh_d = atanh;
+ public static Variable atanh(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, atanh_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Atanh());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Atanh();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> acotanh_d = acotanh;
+ public static Variable acotanh(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, acotanh_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Acotanh());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Acotanh();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> asec_d = asec;
+ public static Variable asec(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, asec_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Asec());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Acos(1 / v1));
+ }
+ }
+
+ static Func<Variable,Variable> cosech_d = cosech;
+ public static Variable cosech(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, cosech_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Cosech());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Cosech();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> acosech_d = acosech;
+ public static Variable acosech(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, acosech_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Acosech());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Acosech();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> sec_d = sec;
+ public static Variable sec(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, sec_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Sec());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(1 / Math.Cos(v1));
+ }
+ }
+
+ static Func<Variable,Variable> acosec_d = acosec;
+ public static Variable acosec(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, acosec_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Acosec());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Asin(1 / v1));
+ }
+ }
+
+ static Func<Variable,Variable> cotanh_d = cotanh;
+ public static Variable cotanh(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, cotanh_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Cotanh());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Cotanh();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> sech_d = sech;
+ public static Variable sech(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, sech_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Sech());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Sech();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+
+ static Func<Variable,Variable> cotan_d = cotan;
+ public static Variable cotan(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, cotan_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Cotan());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(1 / Math.Tan(v1));
+ }
+ }
+
+ static Func<Variable,Variable> acotan_d = acotan;
+ public static Variable acotan(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, acotan_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Acotan());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.Atan(1 / v1));
+ }
+ }
+
+ static Func<Variable,Variable> cosec_d = cosec;
+ public static Variable cosec(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, cosec_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Cosec());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(1 / Math.Sin(v1));
+ }
+ }
+
+ static Func<Variable,Variable> asech_d = asech;
+ public static Variable asech(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, asech_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.Asech());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.Asech();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+}
View
2  lib/Kernel.cs
@@ -3402,7 +3402,7 @@ public struct StashCursor {
have_sc:
if (!final) return;
if (bind_to != null)
- throw new NieczaException("cannot bind a psuedo package");
+ throw new NieczaException("cannot bind a pseudo package");
{
P6any who = Kernel.BoxRaw(this, Kernel.PseudoStashMO);
who.SetSlot("name", Kernel.BoxAnyMO(key, Kernel.StrMO));
View
108 lib/NieczaCLR.cs
@@ -246,27 +246,35 @@ sealed class FieldProxy : Variable {
class OverloadCandidate : MultiCandidate {
MemberInfo what_call;
Type[] args;
+ bool[] refs;
Type param_array;
private OverloadCandidate(MemberInfo what_call, Type[] args,
- Type param_array) {
+ bool[] refs, Type param_array) {
this.what_call = what_call;
this.args = args;
+ this.refs = refs;
this.param_array = param_array;
}
public static void MakeCandidates(MemberInfo what, ParameterInfo[] pi,
List<MultiCandidate> into) {
Type[] args1 = new Type[pi.Length];
- for (int i = 0; i < pi.Length; i++)
+ bool[] refs = new bool[pi.Length];
+ for (int i = 0; i < pi.Length; i++) {
args1[i] = pi[i].ParameterType;
- into.Add(new OverloadCandidate(what, args1, null));
+ if (args1[i].IsByRef) {
+ args1[i] = args1[i].GetElementType();
+ refs[i] = true;
+ }
+ }
+ into.Add(new OverloadCandidate(what, args1, refs, null));
if (pi.Length != 0 && pi[pi.Length-1].GetCustomAttributes(
typeof(ParamArrayAttribute), false).Length != 0) {
Type[] args2 = new Type[args1.Length - 1];
Array.Copy(args1, 0, args2, 0, args2.Length);
- into.Add(new OverloadCandidate(what, args2,
+ into.Add(new OverloadCandidate(what, args2, refs,
args1[args1.Length - 1].GetElementType()));
}
}
@@ -280,6 +288,13 @@ class OverloadCandidate : MultiCandidate {
}
}
+ void WritebackRefs(Variable[] pos, object[] argv) {
+ for (int i = 0; i < args.Length; i++)
+ if (refs[i])
+ pos[i].Store(CLRWrapperProvider.BoxResult(args[i],
+ argv[i]).Fetch());
+ }
+
public Variable Invoke(object obj, Variable[] pos, VarHash named) {
object[] argv = new object[args.Length +
(param_array != null ? 1 : 0)];
@@ -298,10 +313,12 @@ class OverloadCandidate : MultiCandidate {
if (what_call is MethodInfo) {
MethodInfo mi = (MethodInfo) what_call;
object ret = mi.Invoke((mi.IsStatic ? null : obj), argv);
+ WritebackRefs(pos, argv);
return CLRWrapperProvider.BoxResult(mi.ReturnType, ret);
} else if (what_call is ConstructorInfo) {
ConstructorInfo ci = (ConstructorInfo) what_call;
object ret = ci.Invoke(null, argv);
+ WritebackRefs(pos, argv);
return CLRWrapperProvider.BoxResult(ci.DeclaringType, ret);
} else if (what_call is FieldInfo) {
return new FieldProxy((FieldInfo) what_call, obj);
@@ -320,7 +337,8 @@ class OverloadCandidate : MultiCandidate {
object dummy;
for (int i = 0; i < args.Length; i++)
- if (!CLRWrapperProvider.CoerceArgument(out dummy, args[i], pos[i]))
+ if (!CLRWrapperProvider.CoerceArgument(out dummy, args[i], pos[i])
+ || (refs[i] && !pos[i].rw))
return false;
// XXX: maybe param arrays should be treated as slurpies?
for (int i = args.Length; i < pos.Length; i++)
@@ -549,6 +567,13 @@ public class CLRWrapperProvider {
return th.caller;
}
+ static Frame dispose_handler(Frame th) {
+ object o = Kernel.UnboxAny<object>(((Variable)th.lex0).Fetch());
+ ((IDisposable)o).Dispose();
+ th.caller.resultSlot = Kernel.NilP.mo.typeVar;
+ return th.caller;
+ }
+
static Frame Str_handler(Frame th) {
P6any ro = ((Variable)th.lex0).Fetch();
object o = Kernel.UnboxAny<object>(ro);
@@ -611,6 +636,17 @@ public class CLRWrapperProvider {
MultiAdd(allMembers, fi.Name, fi, new ParameterInfo[0]);
}
+ if (typeof(IDisposable).IsAssignableFrom(t)) {
+ SubInfo si;
+
+ si = new SubInfo("KERNEL dispose-hack", dispose_handler);
+ si.sig_i = new int[] {
+ SubInfo.SIG_F_RWTRANS | SubInfo.SIG_F_POSITIONAL, 0, 0,
+ };
+ si.sig_r = new object[] { "self" };
+ m.AddMethod(0, "dispose-hack", Kernel.MakeSub(si, null));
+ }
+
if (t == typeof(object)) {
SubInfo si;
@@ -766,6 +802,68 @@ public class CLRWrapperProvider {
clr = obj;
}
}
+ else if (obj.Does(Kernel.RealMO)) {
+ // fractional value
+
+ if (ty == typeof(decimal)) {
+ // decimal is for people who care about exactness
+ int rk;
+ P6any n = Builtins.GetNumber(var, obj, out rk);
+ BigInteger num, den;
+ if (rk == Builtins.NR_FATRAT) {
+ FatRat r = Kernel.UnboxAny<FatRat>(n);
+ num = r.num; den = r.den;
+ }
+ else if (rk == Builtins.NR_FIXRAT) {
+ Rat r = Kernel.UnboxAny<Rat>(n);
+ num = r.num; den = r.den;
+ }
+ else if (rk == Builtins.NR_BIGINT) {
+ num = Kernel.UnboxAny<BigInteger>(n); den = BigInteger.One;
+ }
+ else if (rk == Builtins.NR_FIXINT) {
+ num = Kernel.UnboxAny<int>(n); den = BigInteger.One;
+ }
+ else {
+ return false;
+ }
+ BigInteger div, rem;
+ int scale = 0;
+ while (true) {
+ div = BigInteger.DivRem(den, 10, out rem);
+ if (rem.Sign != 0) break;
+ den = div;
+ scale++;
+ }
+ while (true) {
+ div = BigInteger.DivRem(den, 5, out rem);
+ if (rem.Sign != 0) break;
+ den = div;
+ num *= 2;
+ scale++;
+ }
+ while (true) {
+ div = BigInteger.DivRem(den, 2, out rem);
+ if (rem.Sign != 0) break;
+ den = div;
+ num *= 5;
+ scale++;
+ }
+ if (den != BigInteger.One)
+ return false;
+ if (scale > 28)
+ return false;
+ int[] bits = decimal.GetBits((decimal)num);
+ bits[3] = scale << 16;
+ clr = new decimal(bits);
+ } else {
+ double val = obj.mo.mro_raw_Numeric.Get(var);
+ if (ty == typeof(float))
+ clr = (object)(float)val;
+ else if (ty == typeof(double) || ty == typeof(object))
+ clr = (object)val;
+ }
+ }
else if (obj.Does(Kernel.StrMO)) {
string s = Kernel.UnboxAny<string>(obj);
if (ty == typeof(char) && s.Length == 1)
View
76 lib/Perl5Interpreter.cs
@@ -0,0 +1,76 @@
+using Niecza;
+using System.Runtime.InteropServices;
+using System;
+
+public class Perl5Interpreter : IForeignInterpreter {
+ [DllImport("obj/p5embed.so", EntryPoint="p5embed_initialize")]
+ public static extern void Initialize();
+
+ [DllImport("obj/p5embed.so", EntryPoint="p5embed_dispose")]
+ public static extern void Dispose();
+
+ [DllImport("obj/p5embed.so", EntryPoint="p5embed_eval")]
+ public static extern IntPtr EvalPerl5(string code);
+
+
+
+ public Perl5Interpreter() {
+ Initialize();
+ }
+ ~Perl5Interpreter() {
+ Dispose();
+ }
+ public Variable Eval(string code) {
+ return new SVVariable(EvalPerl5(code));
+ }
+}
+
+public class SVVariable : Variable {
+ public IntPtr sv;
+ public SVVariable(IntPtr _sv) {
+ sv = _sv;
+ }
+ public override P6any Fetch() {
+ return new SVany(sv);
+ }
+ public override void Store(P6any v) {
+ }
+ public override Variable GetVar() {
+ return Kernel.BoxAnyMO<Variable>(this, Kernel.ScalarMO);
+
+ }
+}
+public class SVany : P6any {
+ [DllImport("obj/p5embed.so", EntryPoint="p5method_call")]
+ public static extern IntPtr MethodCall(
+ string name,
+ IntPtr[] foo,
+ int n
+ );
+
+ public static IntPtr VariableToSV(Variable var) {
+ P6any obj = var.Fetch();
+ if (obj is SVany) {
+ return ((SVany)obj).sv;
+ } else {
+ throw new NieczaException("can't convert argument to p5 type");
+ }
+ }
+
+ public IntPtr sv;
+ public override Frame InvokeMethod(Frame caller, string name,
+ Variable[] pos, VarHash named) {
+ IntPtr[] args = new IntPtr[pos.Length];
+ for (int i=0;i<pos.Length;i++) {
+ args[i] = VariableToSV(pos[i]);
+ }
+ MethodCall(name,args,args.Length);
+ return caller;
+ }
+
+ public SVany(IntPtr _sv) {
+ mo = Kernel.AnyMO;
+ sv = _sv;
+ }
+}
+
View
8 lib/Printf.cs
@@ -64,8 +64,8 @@ private struct PrintfFormat {
for (int pos=0; pos < fmtstring.Length; ++pos) {
char c = fmtstring[pos];
PrintfFormat format = new PrintfFormat();
- // not necessary to initialize all these fields,
- // but handy to have them all listed together in one place.
+ // We do not have to initialize all these fields, but it's
+ // handy to have them all listed together in one place.
format.index = 0;
format.nonNegativeSpacePrefix = false;
format.nonNegativePlusPrefix = false;
@@ -238,7 +238,11 @@ private struct PrintfFormat {
i = format.index>0 ? format.index : ++argi;
if (i < args.Length) {
s = args[i].Fetch().mo.mro_raw_Str.Get(args[i]);
+ if (format.minimumWidth > s.Length && !format.leftJustify)
+ result += new string(' ', format.minimumWidth-s.Length);
result += s;
+ if (format.minimumWidth > s.Length && format.leftJustify)
+ result += new string(' ', format.minimumWidth-s.Length);
}
else {
throw new NieczaException("index out of range");
View
25 lib/Test.pm6
@@ -3,8 +3,10 @@ my module Test;
constant $?TRANSPARENT = 1;
class Builder {
- has $.current-test;
+ has $!current-test;
has $!set-plan;
+ has $!todo-up-to;
+ has $!todo-reason;
method new() {
$*TEST-BUILDER;
@@ -23,7 +25,7 @@ class Builder {
}
method reset() {
- $.current-test = 1;
+ $!current-test = 1;
}
method note($m) {
@@ -35,20 +37,24 @@ class Builder {
my $not = $bool ?? "" !! "not ";
my $desc;
if $tag {
- $desc = " - " ~ $tag.split("\n").join("\n#");
+ $desc = " - " ~ $tag.subst('#', '\#').split("\n").join("\n#");
} else {
$desc = '';
}
- self!output($not ~ "ok " ~ $.current-test++ ~ $desc);
+ if $!todo-up-to >= $!current-test {
+ $desc ~= " # TODO $!todo-reason";
+ }
+ self!output($not ~ "ok " ~ $!current-test++ ~ $desc);
if !$bool { self.note(self.blame); }
}
- # TODO: Generalize this.
- method todo($tag, $reason) {
- self!output("not ok {$.current-test++} - $tag # TODO $reason");
+ method todo($reason, $count) {
+ $!todo-reason = $reason;
+ $!todo-up-to = $!current-test + $count - 1; # todo(1) should stop after cur
}
+
method skip($reason) {
- self!output("ok {$.current-test++} # skip $reason");
+ self!output("ok {$!current-test++} # SKIP $reason");
}
method expected-tests($num) {
@@ -66,7 +72,7 @@ class Builder {
method done {
if !($!set-plan) {
- self!output("1.." ~ ($.current-test - 1));
+ self!output("1.." ~ ($!current-test - 1));
}
}
}
@@ -145,6 +151,7 @@ sub is_approx(Mu $got, Mu $expected, $desc = '') is export {
}
?$test;
}
+sub todo($reason="", $count = 1) is export { $*TEST-BUILDER.todo($reason, $count) }
sub plan($num) is export { $*TEST-BUILDER.plan($num) }
sub done() is export { $*TEST-BUILDER.done }
sub skip($reason,$number) is export {
View
162 lib/Utils.cs
@@ -517,6 +517,168 @@ public sealed class Complex {
public Complex(double re, double im) {
this.re = re; this.im = im;
}
+
+ public static readonly Complex i = new Complex(0, 1);
+
+ public static Complex operator- (Complex left) {
+ return new Complex(-left.re, -left.im);
+ }
+
+ public static Complex operator+ (Double left, Complex right) {
+ return new Complex(left + right.re, right.im);
+ }
+
+ public static Complex operator+ (Complex left, Complex right) {
+ return new Complex(left.re + right.re, left.im + right.im);
+ }
+
+ public static Complex operator- (Double left, Complex right) {
+ return new Complex(left - right.re, -right.im);
+ }
+
+ public static Complex operator- (Complex left, Complex right) {
+ return new Complex(left.re - right.re, left.im - right.im);
+ }
+
+ public static Complex operator* (Complex left, Complex right) {
+ return new Complex(left.re*right.re - left.im*right.im,
+ left.im*right.re + left.re*right.im);
+ }
+
+ public static Complex operator* (Double left, Complex right) {
+ return new Complex(left*right.re,
+ left*right.im);
+ }
+
+ public static Complex operator/ (Complex left, Complex right) {
+ double sn2 = right.re*right.re + right.im*right.im;
+ return new Complex((left.re*right.re + left.im*right.im)/sn2,
+ (right.re*left.im - right.im*left.re)/sn2);
+ }
+
+ public static Complex operator/ (Double left, Complex right) {
+ double sn2 = right.re * right.re + right.im * right.im;
+ return new Complex(left * right.re / sn2,
+ -right.im * left / sn2);
+ }
+
+ public static Complex operator/ (Complex left, Double right) {
+ return new Complex(left.re / right,
+ left.im / right);
+ }
+
+ public Complex log() {
+ return new Complex(Math.Log(Math.Sqrt(re * re + im * im)),
+ Math.Atan2(im, re));
+ }
+
+ public Complex exp() {
+ return new Complex(Math.Exp(re) * Math.Cos(im),
+ Math.Exp(re) * Math.Sin(im));
+ }
+
+ public Complex sqrt() {
+ return (this.log() / 2).exp();
+ }
+
+ public Complex Sin() {
+ return new Complex(Math.Sin(re) * Math.Cosh(im),
+ Math.Cos(re) * Math.Sinh(im));
+ }
+
+ public Complex Asin() {
+ return -i * (this * i + (1 - this * this).sqrt()).log();
+ }
+
+ public Complex Cos() {
+ return new Complex(Math.Cos(re) * Math.Cosh(im),
+ -Math.Sin(re) * Math.Sinh(im));
+ }
+
+ public Complex Acos() {
+ return Math.PI / 2 - this.Asin();
+ }
+
+ public Complex Tan() {
+ return this.Sin() / this.Cos();
+ }
+
+ public Complex Atan() {
+ return ((1 + this * i).log() - (1 - this * i).log()) / (2 * i);
+ }
+
+ public Complex Sec() {
+ return 1 / this.Cos();
+ }
+
+ public Complex Asec() {
+ return (1 / this).Acos();
+ }
+
+ public Complex Cosec() {
+ return 1 / this.Sin();
+ }
+
+ public Complex Acosec() {
+ return (1 / this).Asin();
+ }
+
+ public Complex Cotan() {
+ return this.Cos() / this.Sin();
+ }
+
+ public Complex Acotan() {
+ return (1 / this).Atan();
+ }
+
+ public Complex Sinh() {
+ return -((i * this).Sin()) * i;
+ }
+
+ public Complex Asinh() {
+ return (this + (1 + this * this).sqrt()).log();
+ }
+
+ public Complex Cosh() {
+ return (i * this).Cos();
+ }
+
+ public Complex Acosh() {
+ return 2 * (((1 + this) / 2).sqrt() + ((-1 + this) / 2).sqrt()).log();
+/* return (this + (-1 + this * this).sqrt()).log();*/
+ }
+
+ public Complex Tanh() {
+ return -(i * this).Tan() * i;
+ }
+
+ public Complex Atanh() {
+ return ((1 + this).log() - (1 - this).log()) / 2;
+ }
+
+ public Complex Sech() {
+ return 1 / this.Cosh();
+ }
+
+ public Complex Asech() {
+ return (1 / this).Acosh();
+ }
+
+ public Complex Cosech() {
+ return 1 / this.Sinh();
+ }
+
+ public Complex Acosech() {
+ return (1 / this).Asinh();
+ }
+
+ public Complex Cotanh() {
+ return 1 / this.Tanh();
+ }
+
+ public Complex Acotanh() {
+ return (1 / this).Atanh();
+ }
}
public sealed class Rat {
View
61 lib/p5embed.c
@@ -0,0 +1,61 @@
+#include <EXTERN.h>
+#include <perl.h>
+
+/* So that we can load XS using modules from our perl */
+EXTERN_C void xs_init (pTHX);
+
+EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
+
+EXTERN_C void
+xs_init(pTHX)
+{
+ char *file = __FILE__;
+ dXSUB_SYS;
+
+ /* DynaLoader is a special case */
+ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
+}
+
+static PerlInterpreter *my_perl;
+void p5embed_initialize()
+{
+ PERL_SYS_INIT3(0,NULL,NULL);
+ PerlInterpreter* my_perl = perl_alloc();
+ PERL_SET_CONTEXT(my_perl);
+ perl_construct(my_perl);
+ char *embedding[] = { "", "-e", "0" };
+ perl_parse(my_perl, xs_init, 3, embedding, NULL);
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
+ eval_pv("use lib 'perl5';use Niecza::Interoperability",TRUE);
+}
+
+SV* p5embed_eval(char* code) {
+ return eval_pv(code,TRUE);
+}
+
+void p5embed_dispose()
+{
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ PERL_SYS_TERM();
+}
+
+void p5method_call(char* name,int* args,int n) {
+ dSP;
+
+
+ /*ENTER;
+ SAVETMPS;*/
+
+ PUSHMARK(SP);
+ int i;
+ for (i=0;i<n;i++) {
+ XPUSHs(args[i]);
+ }
+ PUTBACK;
+
+ call_method(name,G_DISCARD);
+
+ /*FREETMPS;
+ LEAVE;*/
+}
View
3  perl5/Niecza/Interoperability.pm
@@ -0,0 +1,3 @@
+package Niecza::Interoperability;
+#BEGIN {print "ok 1 # loaded Niecza::Interoperability\n"}
+1;
View
2  src/Metamodel.pm6
@@ -569,7 +569,7 @@ class StaticSub is RefTarget {
# helper for compile_get_pkg; handles stuff like SETTING::OUTER::Foo,
# recursively.
method _lexy_ref(*@names, :$auto) {
- @names || die "Cannot use a lexical psuedopackage as a compile time package reference";
+ @names || die "Cannot use a lexical pseudopackage as a compile time package reference";
self // die "Passed top of lexical tree";
given shift @names {
when 'OUTER' { return self.outer._lexy_ref(@names, :$auto) }
View
23 src/NieczaActions.pm6
@@ -470,10 +470,16 @@ method quantified_atom($/) { # :: RxOp
if defined $q<min> {
my @z = $atom;
+ if $<separator> {
+ if $q<sep>:exists {
+ $/.CURSOR.sorry("Cannot use two separators in one quantified_atom");
+ }
+ for %( $<separator>.ast ) { $q{.key} = .value }
+ }
push @z, $q<sep> if defined $q<sep>;
# parsing quirk, x #`(1) ** #`(2) y, the 1* position is counted
# as $<normspace> but the 2* is parsed by the quantifier
- if $q<general> && %*RX<s> && ($q<space> || $<normspace>) {
+ if ($q<general> || @z[1]) && %*RX<s> && ($q<space> || $<normspace>) {
if @z[1] {
@z[1] = ::RxOp::Sequence.new(zyg => [
::RxOp::Sigspace.new, @z[1], ::RxOp::Sigspace.new]);
@@ -483,7 +489,8 @@ method quantified_atom($/) { # :: RxOp
}
$atom = ::RxOp::Quantifier.new(min => $q<min>, max => $q<max>,
nonlisty => $q<nonlisty>, closure => $q<closure>,
- zyg => [@z], minimal => ($q<mod> && $q<mod> eq '?'));
+ opsep => $q<opsep>, zyg => [@z],
+ minimal => ($q<mod> && $q<mod> eq '?'));
}
if defined($q<mod>) && $q<mod> eq '' {
@@ -529,15 +536,17 @@ method quantifier:sym<**> ($/) {
make $h;
}
+method separator($/) {
+ make { sep => $<quantified_atom>.ast,
+ space => ?($<normspace>),
+ opsep => (substr($/.orig, $/.from+1, 1) // '') eq '%' };
+}
+
method quantmod($/) {
my $t = ~$/;
if $t eq '' { make Any; return Nil }
if substr($t,0,1) eq ':' { $t = substr($t,1,chars($t)-1) }
- if $t eq '+' {
- $/.CURSOR.sorry('STD parses + as a quantmod but there is nothing at all in S05 to explain what it should _do_'); #XXX
- make Any;
- return Nil;
- }
+ if $t eq '+' { $t = '' }
make $t;
}
View
1  src/RxOp.pm6
@@ -124,6 +124,7 @@ class Quantifier is RxOp {
has $.max; # Int
has $.closure;
has $.nonlisty;
+ has $.opsep;
method opzyg() { $!closure // () }
View
11 src/STD.pm6
@@ -2423,6 +2423,7 @@ grammar P6 is STD {
# parametric type?
<.unsp>? [ <?before '['> <param=.postcircumfix> ]?
<.unsp>? [ <?before '{'> <whence=.postcircumfix> ]?
+ <.unsp>? [ <?before '('> <accept=.postcircumfix> ]?
[<.ws> 'of' <.ws> <typename> ]?
}
@@ -3320,7 +3321,7 @@ grammar P6 is STD {
[ <!{$*QSIGIL}> || <!before '"' <-["]>*? \s > ] # dwim on "$foo."
<quote>
[ <?before '(' | '.(' | '\\'> || <.obs('. to concatenate strings or to call a quoted method', '~ to concatenate, or if you meant to call a quoted method, please supply the required parentheses')> ]
- { my $t = $<quote><nibble>.Str; $t ~~ /\W/ or $t ~~ /^(WHO|WHAT|WHERE|WHEN|WHY|HOW)$/ or $¢.worry("Useless use of quotes") }
+ { my $t = $<quote><nibble>.Str; $t ~~ /\W/ or $t eq '' or $t ~~ /^(WHO|WHAT|WHERE|WHEN|WHY|HOW)$/ or $¢.worry("Useless use of quotes") }
] <.unsp>?
:dba('method arguments')
@@ -4714,11 +4715,15 @@ grammar Regex is STD {
<!stopper>
<!regex_infix>
<atom>
- [ <normspace>? <quantifier> ]?
+ [ <normspace>? <quantifier> <normspace>? <separator>? ]?
# <?{ $<atom>.max_width }>
# || <.panic: "Cannot quantify zero-width atom">
}
+ token separator {
+ '%''%'? <normspace>? <quantified_atom>
+ }
+
token atom {
:dba('regex atom')
[
@@ -5002,7 +5007,7 @@ grammar Regex is STD {
| \d+ \s+ '..' <.panic: "Spaces not allowed in bare range">
| (\d+) [ '..' [ (\d+) { $¢.panic("Empty range") if $0.Str > $1[0].Str } | '*' | <.panic: "Malformed range"> ] ]?
| <embeddedblock>
- | <quantified_atom>
+ | <quantified_atom> <.worryobs("atom ** " ~ $<quantified_atom>.Str ~ " as separator", "atom+ % " ~ $<quantified_atom>.Str, "nowadays")>
]
}
View
12 t/run_spectests
@@ -1,2 +1,12 @@
#!/bin/sh
-sed 's|^|t/spec/|' t/spectest.data | xargs prove -e 't/fudgeandrun' "$@"
+
+jobs=1
+if [ -z "$TEST_JOBS" ] ; then
+ jobs=1
+else
+ jobs=$TEST_JOBS
+fi
+
+grep -v "^#" t/spectest.data |
+sed 's|^|t/spec/|' |
+xargs prove -e 't/fudgeandrun' -j $jobs "$@"
View
151 t/spectest.data
@@ -4,70 +4,135 @@ integration/method-calls-and-instantiation.t
integration/no-indirect-new.t
integration/passing-pair-class-to-sub.t
integration/substr-after-match-in-gather-in-for.t
-S02-builtin_data_types/array.t
-S02-builtin_data_types/autovivification.t
-S02-builtin_data_types/bool.t
-S02-builtin_data_types/catch_type_cast_mismatch.t
-S02-builtin_data_types/flattening.t
-S02-builtin_data_types/nested_pairs.t
-S02-builtin_data_types/nil.t
-S02-builtin_data_types/parsing-bool.t
-S02-builtin_data_types/subscripts_and_context.t
+S02-lexical-conventions/begin_end_pod.t
+S02-lexical-conventions/comments.t
+S02-lexical-conventions/minimal-whitespace.t
+S02-lexical-conventions/pod-in-multi-line-exprs.t
+S02-lexical-conventions/sub-block-parsing.t
+S02-lexical-conventions/unicode-whitespace.t
S02-lexical-conventions/unicode.t
+S02-literals/array-interpolation.t
+S02-literals/autoref.t
S02-literals/hash-interpolation.t
+S02-literals/numeric.t
S02-literals/pair-boolean.t
+S02-literals/quoting.t
S02-literals/string-interpolation.t
S02-literals/types.t
S02-literals/underscores.t
S02-magicals/block.t
+S02-magicals/dollar-underscore.t
S02-magicals/file_line.t
+S02-magicals/progname.t
S02-magicals/sub.t
-S02-names_and_variables/contextual.t
+S02-names-vars/contextual.t
+S02-names-vars/varnames.t
S02-names/caller.t
S02-names/identifier.t
S02-names/our.t
S02-names/pseudo.t
S02-names/symbolic-deref.t
-S02-whitespace_and_comments/begin_end_pod.t
-S02-whitespace_and_comments/pod-in-multi-line-exprs.t
-S02-whitespace_and_comments/sub-block-parsing.t
+S02-one-pass-parsing/less-than.t
+S02-types/array.t
+S02-types/array_extending.t
+S02-types/assigning-refs.t
+S02-types/autovivification.t
+S02-types/bool.t
+S02-types/catch_type_cast_mismatch.t
+S02-types/fatrat.t
+S02-types/flattening.t
+S02-types/hash.t
+S02-types/hash_ref.t
+S02-types/infinity.t
+S02-types/lists.t
+S02-types/mixed_multi_dimensional.t
+S02-types/nan.t
+S02-types/nested_arrays.t
+S02-types/nested_pairs.t
+S02-types/nil.t
+S02-types/num.t
+S02-types/parcel.t
+S02-types/parsing-bool.t
+S02-types/range.t
+S02-types/subscripts_and_context.t
+S02-types/whatever.t
S03-junctions/associative.t
S03-junctions/autothreading.t
S03-junctions/boolean-context.t
S03-junctions/misc.t
+S03-metaops/cross.t
S03-metaops/hyper.t
S03-metaops/not.t
S03-metaops/reduce.t
+S03-metaops/reverse.t
+S03-operators/also.t
S03-operators/assign-is-not-binding.t
+S03-operators/autovivification.t
S03-operators/binding-arrays.t
-S03-operators/binding-closure.t
+# S03-operators/binding-closure.t err: 'System.NullReferenceException: Object reference not set to an instance of an object'
S03-operators/binding-hashes.t
S03-operators/binding-nested.t
+S03-operators/binding-ro.t
S03-operators/binding-scalars.t
S03-operators/bit.t
+S03-operators/boolean-bitwise.t
S03-operators/chained-declarators.t
+S03-operators/cmp.t
+S03-operators/comparison-simple.t
+S03-operators/equality.t
+S03-operators/eqv.t
S03-operators/flip-flop.t
+S03-operators/inplace.t
+S03-operators/is-divisible-by.t
+S03-operators/list-quote-junction.t
+S03-operators/minmax.t
+S03-operators/misc.t
+S03-operators/names.t
S03-operators/not.t
S03-operators/overflow.t
+S03-operators/precedence.t
S03-operators/range-basic.t
+S03-operators/range.t
S03-operators/relational.t
S03-operators/repeat.t
S03-operators/scalar-assign.t
+S03-operators/so.t
S03-operators/spaceship-and-containers.t
S03-operators/spaceship.t
+S03-operators/subscript-adverbs.t
S03-operators/subscript-vs-lt.t
+S03-operators/ternary.t
+S03-operators/value_equivalence.t
S03-smartmatch/any-any.t
+S03-smartmatch/any-array-slice.t
+S03-smartmatch/any-array.t
S03-smartmatch/any-bool.t
+S03-smartmatch/any-callable.t
+S03-smartmatch/any-complex.t
+S03-smartmatch/any-hash-pair.t
+S03-smartmatch/any-hash-slice.t
+S03-smartmatch/any-method.t
+S03-smartmatch/any-num.t
+S03-smartmatch/any-pair.t
S03-smartmatch/any-str.t
+S03-smartmatch/any-sub.t
+S03-smartmatch/array-array.t
+S03-smartmatch/array-hash.t
+S03-smartmatch/regex-hash.t
+S03-smartmatch/scalar-hash.t
S04-blocks-and-statements/let.t
+S04-blocks-and-statements/pointy-rw.t
S04-blocks-and-statements/temp.t
+S04-declarations/implicit-parameter.t
S04-declarations/multiple.t
S04-declarations/my.t
S04-declarations/state.t
S04-exceptions/control_across_runloop.t
+S04-phasers/end.t
S04-phasers/enter-leave.t
S04-phasers/keep-undo.t
S04-phasers/pre-post.t
+S04-phasers/start.t
S04-statement-modifiers/for.t
S04-statement-modifiers/given.t
S04-statement-modifiers/if.t
@@ -77,9 +142,8 @@ S04-statement-modifiers/values_in_bool_context.t
S04-statement-modifiers/while.t
S04-statement-parsing/hash.t
S04-statements/do.t
-S04-statements/gather.t
-S04-statements/for.t
S04-statements/for-scope.t
+S04-statements/for.t
S04-statements/for_with_only_one_item.t
S04-statements/gather.t
S04-statements/given.t
@@ -92,31 +156,67 @@ S04-statements/no-implicit-block.t
S04-statements/redo.t
S04-statements/repeat.t
S04-statements/return.t
+S04-statements/terminator.t
+S04-statements/try.t
S04-statements/unless.t
S04-statements/until.t
S04-statements/while.t
+S05-capture/match-object.t
S05-capture/subrule.t
+S05-grammar/action-stubs.t
S05-grammar/methods.t
S05-grammar/protoregex.t
S05-grammar/signatures.t
S05-interpolation/lexicals.t
S05-mass/recursive.t
+S05-mass/stdrules.t
+S05-match/blocks.t
+S05-match/non-capturing.t
+S05-match/positions.t
+S05-metachars/closure.t
S05-metachars/line-anchors.t
+S05-metachars/newline.t
+S05-metachars/tilde.t
S05-metasyntax/changed.t
+S05-metasyntax/charset.t
+S05-metasyntax/litvar.t
S05-metasyntax/null.t
S05-metasyntax/repeat.t
+S05-metasyntax/sequential-alternation.t
S05-metasyntax/single-quotes.t
-S05-modifier/pos.t
+S05-metasyntax/unknown.t
S05-modifier/continue.t
+S05-modifier/counted-match.t
S05-modifier/counted.t
+S05-modifier/ignorecase.t
+# S05-modifier/pos.t err: 'Unsupported use of $/ variable as input record separator'
+S05-substitution/match.t
+S06-advanced/caller.t
+S06-advanced/recurse.t
+S06-currying/assuming-and-mmd.t
+S06-currying/named.t
+S06-multi/by-trait.t
S06-multi/lexical-multis.t
-S06-advanced_subroutine_features/caller.t
+S06-other/anon-hashes-vs-blocks.t
+S06-other/misc.t
+S06-routine-modifiers/scoped-named-subs.t
S06-signature/arity.t
+S06-signature/caller-param.t
+S06-signature/closure-over-parameters.t
+S06-signature/code.t
+S06-signature/defaults.t
+S06-signature/errors.t
+S06-signature/mixed-placeholders.t
+S06-signature/named-placeholders.t
S06-signature/optional.t
S06-signature/passing-arrays.t
+S06-signature/passing-hashes.t
S06-signature/positional-placeholders.t
S06-signature/positional.t
+S06-signature/scalar-type.t
S06-signature/slurpy-and-interpolation.t
+S06-signature/slurpy-placeholders.t
+S06-traits/is-copy.t
S06-traits/is-rw.t
S06-traits/precedence.t
S06-traits/slurpy-is-rw.t
@@ -161,4 +261,19 @@ S32-str/substr.t
S32-str/uc.t
S32-str/ucfirst.t
S32-str/words.t
+# S32-trig/atan2.t # TODO: fudging
+S32-trig/cos.t
+S32-trig/cosec.t
+S32-trig/cosech.t
+S32-trig/cosh.t
+S32-trig/cotan.t
+S32-trig/cotanh.t
S32-trig/e.t
+S32-trig/pi.t
+S32-trig/sec.t
+S32-trig/sech.t
+S32-trig/simple.t
+S32-trig/sin.t
+S32-trig/sinh.t
+S32-trig/tan.t
+S32-trig/tanh.t
View
2  test.pl
@@ -2259,7 +2259,7 @@
is (1, 2).all.perl, 'all(1, 2)', 'Any.all means all()';
is (1, 2).none.perl, 'none(1, 2)', 'Any.none means none()';
-is { a => True }.any.perl, 'any("a")', 'Hash.any means any(keys)';
+is { a => True }.any.perl, any("a").perl, 'Hash.any means any(keys)';
ok ?(all( True, True)), 'all(True, True)';
nok ?(all( True, False)), '!all(True, False)';
View
143 tools/make_trig_code.pl
@@ -0,0 +1,143 @@
+my $real = "";
+my $complex = "";
+my $function = "";
+
+print <<"Prelude";
+// DO NOT EDIT! Autogenerated file, created by tools/make_trig_code.pl.
+using Niecza;
+using System;
+
+public partial class Builtins {
+Prelude
+
+my @normal_functions = <sin asin cos acos tan atan sinh asinh cosh acosh tanh atanh>;
+my %inverted_functions = (
+ sec => "cos", asec => "acos",
+ cosec => "sin", acosec => "asin",
+ cotan => "tan", acotan => "atan",
+ sech => "cosh", asech => "acosh",
+ cosech => "sinh", acosech => "asinh",
+ cotanh => "tanh", acotanh => "atanh"
+ );
+ # sinh asinh cosh acosh tanh atanh sech asech cosech acosech cotanh acotanh>;
+
+foreach my $function (@normal_functions) {
+ my $upper_function = ucfirst($function);
+
+ if ($function =~ /h/) {
+
+ print <<"Function";
+
+ static Func<Variable,Variable> ${function}_d = ${function};
+ public static Variable ${function}(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, ${function}_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.$upper_function());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.$upper_function();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+Function
+
+ } else {
+
+ print <<"Function";
+
+ static Func<Variable,Variable> ${function}_d = ${function};
+ public static Variable ${function}(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, ${function}_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.$upper_function());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat(Math.$upper_function(v1));
+ }
+ }
+Function
+ }
+}
+
+foreach my $function (keys %inverted_functions) {
+ my $upper_function = ucfirst($function);
+ my $base_function = ucfirst($inverted_functions{$function});
+ # print "xyzzy: $base_function\n";
+ my $double = "1 / Math.$base_function(v1)";
+ if ($function =~ /^a/) {
+ $double = "Math.$base_function(1 / v1)";
+ }
+
+ if ($function =~ /h/) {
+
+ print <<"Function";
+
+ static Func<Variable,Variable> ${function}_d = ${function};
+ public static Variable ${function}(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, ${function}_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.$upper_function());
+ }
+ {
+ Complex v1 = PromoteToComplex(r1, n1);
+ Complex v2 = v1.$upper_function();
+ if (v2.im < -1e-15 || v2.im > 1e-15) {
+ return MakeFloat(double.NaN);
+ } else {
+ return MakeFloat(v2.re);
+ }
+ }
+ }
+Function
+
+ } else {
+
+ print <<"Function";
+
+ static Func<Variable,Variable> ${function}_d = ${function};
+ public static Variable ${function}(Variable a1) {
+ P6any o1 = a1.Fetch();
+ int r1;
+ if (!o1.mo.is_any)
+ return HandleSpecial1(a1,o1, ${function}_d);
+ P6any n1 = GetNumber(a1, o1, out r1);
+
+ if (r1 == NR_COMPLEX) {
+ Complex v1 = PromoteToComplex(r1, n1);
+ return MakeComplex(v1.$upper_function());
+ }
+ {
+ double v1 = PromoteToFloat(r1, n1);
+ return MakeFloat($double);
+ }
+ }
+Function
+
+ }
+}
+
+print "}\n";
Please sign in to comment.
Something went wrong with that request. Please try again.