Red.git | lib/Red/AST/ | Infixes.rakumod
use Red::AST::Infix;
use Red::AST::Value;
class Red::AST::Sum { ... }
class Red::AST::Eq { ... }
class Red::AST::Ne { ... }
class Red::AST::Lt { ... }
class Red::AST::Gt { ... }
class Red::AST::Le { ... }
class Red::AST::Ge { ... }
class Red::AST::AND { ... }
class Red::AST::OR { ... }
class Red::AST::Mul { ... }
class Red::AST::Div { ... }
class Red::AST::IDiv { ... }
class Red::AST::Mod { ... }
class Red::AST::Concat { ... }
class Red::AST::Like { ... }
class Red::AST::In { ... }
#| Represents a sum operation
class Red::AST::Sum does Red::AST::Infix {
has $.op = "+";
has $.returns = (self.left | self.right).returns ~~ Num ?? Num !! Int;
method should-set(--> Hash()) {
self.find-column-name => self.find-value
}
method should-validate {}
method find-column-name {
gather for self.args {
.take for .?find-column-name
}
}
method find-value {
for self.args {
.return with .?find-value
}
}
}
#| Represents a subtraction operation
class Red::AST::Sub does Red::AST::Infix {
has $.op = "-";
has $.returns = (self.left | self.right).returns ~~ Num ?? Num !! Int;
method should-set(--> Hash()) {
self.find-column-name => self.find-value
}
method should-validate {}
method find-column-name {
gather for self.args {
.take for .?find-column-name
}
}
method find-value {
for self.args {
.return with .?find-value
}
}
}
#| Represents a equality operation
class Red::AST::Eq does Red::AST::Infix {
has $.op = "=";
has Bool $.returns;
method should-set(--> Hash()) {
self.find-column-name => self.find-value
}
method should-validate {}
method find-column-name {
gather for self.args {
.take if .defined for .?find-column-name
}
}
method find-value {
for self.args {
.return with .?find-value
}
}
method not {
Red::AST::Ne.new: $.left, $.right, :bind-left($.bind-left), :bind-right($.bind-right)
}
}
#| Represents a not equality operation
class Red::AST::Ne does Red::AST::Infix {
has $.op = "!=";
has Bool $.returns;
method should-set(--> Hash()) { }
method should-validate {}
method not {
Red::AST::Eq.new: $.left, $.right, :bind-left($.bind-left), :bind-right($.bind-right)
}
}
#| Represents a less than operation
class Red::AST::Lt does Red::AST::Infix {
has $.op = "<";
has Bool $.returns;
method should-set(--> Hash()) { }
method should-validate {}
method not {
Red::AST::Ge.new: $.left, $.right, :bind-left($.bind-left), :bind-right($.bind-right)
}
}
#| Represents a greater than operation
class Red::AST::Gt does Red::AST::Infix {
has $.op = ">";
has Bool $.returns;
method should-set(--> Hash()) { }
method should-validate {}
method not {
Red::AST::Le.new: $.left, $.right, :bind-left($.bind-left), :bind-right($.bind-right)
}
}
#| Represents a less than equal operation
class Red::AST::Le does Red::AST::Infix {
has $.op = "<=";
has Bool $.returns;
method should-set(--> Hash()) { }
method should-validate {}
method not {
Red::AST::Gt.new: $.left, $.right, :bind-left($.bind-left), :bind-right($.bind-right)
}
}
#| Represents a greater then equal operation
class Red::AST::Ge does Red::AST::Infix {
has $.op = ">=";
has Bool $.returns;
method should-set(--> Hash()) { }
method should-validate {}
method not {
Red::AST::Lt.new: $.left, $.right, :bind-left($.bind-left), :bind-right($.bind-right)
}
}
#| Represents a AND operation
class Red::AST::AND does Red::AST::Infix {
#also does Red::AST::Optimizer::And;
has $.op = "AND";
has Bool $.returns;
multi method new(Red::AST $left is copy, Red::AST $right is copy) {
my \ret = self.optimize: $left, $right;
return ret if ret.DEFINITE && ret !~~ Empty;
$left .= value if $left ~~ Red::AST::So;
$right .= value if $right ~~ Red::AST::So;
return $left if $left eqv $right;
return ast-value(False) if $left eqv $right.not;
self.WHAT.bless: :$left, :$right
}
method should-set(--> Hash()) {
[$.left, $.right].flatmap({ .should-set })
}
method should-validate {}
method not {
Red::AST::OR.new: $.left.not, $.right.not, :bind-left($.bind-left), :bind-right($.bind-right)
}
}
#| Represents a OR operation
class Red::AST::OR does Red::AST::Infix {
#also does Red::AST::Optimizer::OR;
has $.op = "OR";
has Bool $.returns;
multi method new(Red::AST $left is copy, Red::AST $right is copy) {
my \ret = self.optimize: $left, $right;
return ret if ret.DEFINITE && ret !~~ Empty;
$left .= value if $left ~~ Red::AST::So;
$right .= value if $right ~~ Red::AST::So;
return $left if $left eqv $right;
return ast-value(True) if $left eqv $right.not;
self.WHAT.bless: :$left, :$right
}
method should-set(--> Hash()) {}
method should-validate {}
method not {
Red::AST::AND.new: $.left.not, $.right.not, :bind-left($.bind-left), :bind-right($.bind-right)
}
}
#| Represents a multiplication operation
class Red::AST::Mul does Red::AST::Infix {
has $.op = "*";
has $.returns = (self.left | self.right).returns ~~ Num ?? Num !! Int;
method should-set(--> Hash()) {
self.find-column-name => self.find-value
}
method should-validate {}
method find-column-name {
gather for self.args {
.take for .?find-column-name
}
}
method find-value {
for self.args {
.return with .?find-value
}
}
}
#| Represents a division operation
class Red::AST::Div does Red::AST::Infix {
has $.op = "/";
has Num $.returns;
method should-set(--> Hash()) {
self.find-column-name => self.find-value
}
method should-validate {}
method find-column-name {
gather for self.args {
.take for .?find-column-name
}
}
method find-value {
for self.args {
.return with .?find-value
}
}
}
#| Represents a division operation
class Red::AST::IDiv does Red::AST::Infix {
has $.op = "/";
has Int $.returns;
method should-set(--> Hash()) {
self.find-column-name => self.find-value
}
method should-validate {}
method find-column-name {
gather for self.args {
.take for .?find-column-name
}
}
method find-value {
for self.args {
.return with .?find-value
}
}
}
#| Represents a module operation
class Red::AST::Mod does Red::AST::Infix {
has $.op = "%";
has Int $.returns;
method should-set(--> Hash()) {
self.find-column-name => self.find-value
}
method should-validate {}
method find-column-name {
gather for self.args {
.take for .?find-column-name
}
}
method find-value {
for self.args {
.return with .?find-value
}
}
}
#| Represents a concatenation operation
class Red::AST::Concat does Red::AST::Infix {
has $.op = "||";
has Str $.returns;
method should-set(--> Hash()) {}
method should-validate {}
multi method new(Red::AST $left, Red::AST::Value $ where .value eq "", *%) { $left }
multi method new(Red::AST::Value $ where .value eq "", Red::AST $right, *%) { $right }
}
#| Represents a like operation
class Red::AST::Like does Red::AST::Infix {
has $.op = "like";
has Str $.returns;
method should-set(--> Hash()) {}
method should-validate {}
multi method new(Red::AST $left, Red::AST::Value $ where .value eq "", *%) { $left }
}
#| Represents a not in operation
class Red::AST::NotIn does Red::AST::Infix {
has $.op = "NOT IN";
has Str $.returns;
method should-set(--> Hash()) {}
method should-validate {}
method not {
Red::AST::In.new: $!left, $!right;
}
}
#| Represents a in operation
class Red::AST::In does Red::AST::Infix {
has $.op = "IN";
has Str $.returns;
method should-set(--> Hash()) {}
method should-validate {}
method not {
Red::AST::NotIn.new: $!left, $!right;
}
}