mirror of
https://github.com/perlbot/perlbuut
synced 2025-06-08 16:05:44 -04:00
230 lines
6.6 KiB
Perl
230 lines
6.6 KiB
Perl
package Math::Farnsworth::Value::Lambda;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Math::Farnsworth::Dimension;
|
|
use Math::Farnsworth::Value;
|
|
use Carp;
|
|
|
|
use Data::Dumper;
|
|
|
|
use utf8;
|
|
|
|
our $VERSION = 0.6;
|
|
|
|
use overload
|
|
'+' => \&add,
|
|
'-' => \&subtract,
|
|
'*' => \&mult,
|
|
'/' => \&div,
|
|
'%' => \&mod,
|
|
'**' => \&pow,
|
|
'<=>' => \&compare,
|
|
'bool' => \&bool;
|
|
|
|
use base qw(Math::Farnsworth::Value);
|
|
|
|
#this is the REQUIRED fields for Math::Farnsworth::Value subclasses
|
|
#
|
|
#dimen => a Math::Farnsworth::Dimension object
|
|
#
|
|
#this is so i can make a -> conforms in Math::Farnsworth::Value, to replace the existing code, i'm also planning on adding some definitions such as, TYPE_PARI, TYPE_STRING, TYPE_LAMBDA, TYPE_DATE, etc. to make certain things easier
|
|
|
|
sub new
|
|
{
|
|
my $class = shift;
|
|
my $scope = shift;
|
|
my $args = shift;
|
|
my $code = shift;
|
|
my $branches = shift;
|
|
my $outmagic = shift; #i'm still not sure on this one
|
|
|
|
my $self = {};
|
|
|
|
bless $self, $class;
|
|
|
|
$self->{outmagic} = $outmagic;
|
|
|
|
$self->{scope} = $scope;
|
|
$self->{code} = $code;
|
|
$self->{args} = $args;
|
|
$self->{branches} = $branches;
|
|
|
|
return $self;
|
|
}
|
|
|
|
sub getcode
|
|
{
|
|
return $_[0]->{code};
|
|
}
|
|
|
|
sub getargs
|
|
{
|
|
return $_[0]->{args};
|
|
}
|
|
|
|
sub getscope
|
|
{
|
|
return $_[0]->{scope};
|
|
}
|
|
|
|
sub getbranches
|
|
{
|
|
return $_[0]->{branches};
|
|
}
|
|
|
|
#######
|
|
#The rest of this code can be GREATLY cleaned up by assuming that $one is of type, Math::Farnsworth::Value::Pari, this means that i can slowly redo a lot of this code
|
|
|
|
sub add
|
|
{
|
|
my ($one, $two, $rev) = @_;
|
|
|
|
confess "Non reference given to addition" unless ref($two);
|
|
|
|
#if we're not being added to a Math::Farnsworth::Value::Pari, the higher class object needs to handle it.
|
|
confess "Scalar value given to addition to Lambda" if ($two->isa("Math::Farnsworth::Value::Pari"));
|
|
return $two->add($one, !$rev) unless ($two->ismediumtype());
|
|
if (!$two->istype("Lambda"))
|
|
{
|
|
confess "Given non boolean to boolean operation";
|
|
}
|
|
|
|
|
|
#NOTE TO SELF this needs to be more helpful, i'll probably do this by creating an "error" class that'll be captured in ->evalbranch's recursion and use that to add information from the parse tree about WHERE the error occured
|
|
die "Adding lambda is not a good idea\n";
|
|
}
|
|
|
|
sub subtract
|
|
{
|
|
my ($one, $two, $rev) = @_;
|
|
|
|
confess "Non reference given to subtraction" unless ref($two);
|
|
|
|
#if there's a higher type, use it, subtraction otherwise doesn't make sense on arrays
|
|
die "Scalar value given to subtraction to Lambda" if ($two->isa("Math::Farnsworth::Value::Pari"));
|
|
return $two->subtract($one, !$rev) unless ($two->ismediumtype());
|
|
if (!$two->istype("Lambda"))
|
|
{
|
|
confess "Given non boolean to lambda operation";
|
|
}
|
|
|
|
die "Subtracting lambdas? what did you think this would do, create a black hole?";
|
|
}
|
|
|
|
sub modulus
|
|
{
|
|
my ($one, $two, $rev) = @_;
|
|
|
|
confess "Non reference given to modulus" unless ref($two);
|
|
|
|
#if there's a higher type, use it, subtraction otherwise doesn't make sense on arrays
|
|
confess "Scalar value given to modulus to lambda" if ($two->isa("Math::Farnsworth::Value::Pari"));
|
|
return $two->mod($one, !$rev) unless ($two->ismediumtype());
|
|
if (!$two->istype("Lambda"))
|
|
{
|
|
confess "Given non lambda to lambda operation";
|
|
}
|
|
|
|
die "Modulusing lambda? what did you think this would do, create a black hole?";
|
|
}
|
|
|
|
sub mult
|
|
{
|
|
my ($one, $two, $rev) = @_;
|
|
|
|
confess "Non reference given to multiplication" unless ref($two);
|
|
|
|
#if there's a higher type, use it, subtraction otherwise doesn't make sense on arrays
|
|
#confess "Scalar value given to multiplcation to lambda. ED: This will make white holes later" if ($two->isa("Math::Farnsworth::Value::Pari"));
|
|
return $two->mult($one, !$rev) unless ($two->ismediumtype() || $two->istype("Pari") || $two->istype("Lambda"));
|
|
|
|
# if (!$two->istype("Lambda"))
|
|
# {
|
|
# confess "Given non lambda to lambda operation";
|
|
# }
|
|
|
|
my $args = $two->istype("Array") ? $two : new Math::Farnsworth::Value::Array([$two]);
|
|
|
|
#this code is debug code, but i'm afraid to take it out, when i put it here it started working properly
|
|
#print "LAMBDAMULT\n";
|
|
#eval{print Dumper($one->{scope}->{vars}->getvar('x'), $one->{scope}->{vars}->getvar('y'))}; #this bug was fixed
|
|
|
|
return $one->{scope}->{funcs}->calllambda($one, $args); #needs to be updated
|
|
|
|
# die "Multiplying lambdas? what did you think this would do, create a black hole? ED: this will make black holes later";
|
|
}
|
|
|
|
sub div
|
|
{
|
|
my ($one, $two, $rev) = @_;
|
|
|
|
print "INSIDE LAMBDA DIVISION\n";
|
|
|
|
confess "Non reference given to division" unless ref($two);
|
|
|
|
#if there's a higher type, use it, subtraction otherwise doesn't make sense on arrays
|
|
|
|
return $two->div($one, !$rev) unless ($two->ismediumtype()|| $two->istype("Pari") || $two->istype("Lambda"));
|
|
|
|
if ($two->isa("Math::Farnsworth::Value::Pari"))
|
|
{
|
|
#ok i've got a simple thing here i think!
|
|
#its not simple, will not be simple and will not end up working right, this is a hack to make 10 kg per cubic meter, and the like to work, until i add objects
|
|
my $onevalue = Math::Farnsworth::Value::Pari->new(1); #don't use 1.0 it'll coerce things into floats unneccesarily
|
|
my $newv = $onevalue * $one; #this'll remultiply things!
|
|
my $ret = $two / $newv; #this COULD be dangerous since i can see how to make an inf loop in a division this way
|
|
return $ret;
|
|
}
|
|
|
|
if (!$two->istype("Lambda"))
|
|
{
|
|
confess "Given non boolean to lambda operation";
|
|
}
|
|
|
|
die "Dividing lambdas? what did you think this would do, create a black hole?";
|
|
}
|
|
|
|
sub bool
|
|
{
|
|
#my $self = shift;
|
|
|
|
#seems good enough of an idea to me
|
|
#i have a bug HERE
|
|
#print "BOOLCONV\n";
|
|
#print Dumper($self);
|
|
#print "ENDBOOLCONV\n";
|
|
return 1; #for now lambdas are ALWAYS true!
|
|
}
|
|
|
|
sub pow
|
|
{
|
|
my ($one, $two, $rev) = @_;
|
|
|
|
confess "Non reference given to exponentiation" unless ref($two);
|
|
|
|
#if there's a higher type, use it, subtraction otherwise doesn't make sense on arrays
|
|
confess "Exponentiating arrays? what did you think this would do, create a black hole?" if ($two->isa("Math::Farnsworth::Value::Pari"));
|
|
return $two->pow($one, !$rev) unless ($two->ismediumtype());
|
|
if (!$two->istype("Lambda"))
|
|
{
|
|
confess "Given non boolean to lambdas operation";
|
|
}
|
|
|
|
die "Exponentiating lambdas? what did you think this would do, create a black hole?";
|
|
}
|
|
|
|
sub compare
|
|
{
|
|
my ($one, $two, $rev) = @_;
|
|
|
|
confess "Non reference given to compare" unless ref($two);
|
|
|
|
#if we're not being added to a Math::Farnsworth::Value::Pari, the higher class object needs to handle it.
|
|
confess "Scalar value given to division to lambdas" if ($two->istype("Pari"));
|
|
return $two->compare($one, !$rev) unless ($two->istype("Lambda"));
|
|
|
|
return 0; #i don't have any metric for comparing lambdas, so... they'll always be equal
|
|
}
|
|
|