diff --git a/src/RTEX/Objects/Program/Instructions/Arithmetic/Absolute.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Absolute.php new file mode 100644 index 0000000..45db231 --- /dev/null +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Absolute.php @@ -0,0 +1,109 @@ + $this->Value, + ]); + } + + /** + * Constructs a new instance of this class from an array representation + * + * @param array $data + * @return InstructionInterface + * @throws InstructionException + */ + public static function fromArray(array $data): InstructionInterface + { + $instruction = new self(); + $instruction->setValue($data['value'] ?? null); + return $instruction; + } + + /** + * @param Engine $engine + * @return int|float + * @throws EvaluationException + * @throws TypeException + */ + public function eval(Engine $engine): int|float + { + $value = $engine->eval($this->Value); + + if(!(is_int($value) || is_float($value) || is_double($value))) + throw new TypeException(sprintf('Cannot calculate the absolute value of a non-numeric value, got %s', Utilities::getType($value, true))); + + return abs($value); + } + + /** + * Returns the string representation of the instruction + * + * @return string + */ + public function __toString(): string + { + return sprintf( + self::getType() . ' (%s+%s)', + Utilities::entityToString($this->Value), + ); + } + + /** + * Gets the value of A + * + * @return mixed + */ + public function getValue(): mixed + { + return $this->Value; + } + + /** + * Sets the value of A + * + * @param mixed $Value + * @throws InstructionException + */ + public function setValue(mixed $Value): void + { + $this->Value = InstructionBuilder::fromRaw($Value); + } + + } \ No newline at end of file diff --git a/src/RTEX/Objects/Program/Instructions/Divide.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Divide.php similarity index 89% rename from src/RTEX/Objects/Program/Instructions/Divide.php rename to src/RTEX/Objects/Program/Instructions/Arithmetic/Divide.php index cc430ce..a247f90 100644 --- a/src/RTEX/Objects/Program/Instructions/Divide.php +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Divide.php @@ -2,7 +2,7 @@ /** @noinspection PhpMissingFieldTypeInspection */ - namespace RTEX\Objects\Program\Instructions; + namespace RTEX\Objects\Program\Instructions\Arithmetic; use RTEX\Abstracts\InstructionType; use RTEX\Classes\InstructionBuilder; @@ -66,20 +66,20 @@ /** * @param Engine $engine - * @return int + * @return int|float * @throws EvaluationException * @throws TypeException * @throws ZeroDivisionException */ - public function eval(Engine $engine): int + public function eval(Engine $engine): int|float { $a = $engine->eval($this->A); $b = $engine->eval($this->B); if(!(is_int($a) || is_float($a) || is_double($a))) - throw new TypeException('Cannot divide a non-numeric value'); + throw new TypeException(sprintf('Cannot divide a non-numeric value \'A\' of type %s', Utilities::getType($a, true))); if(!(is_int($b) || is_float($b) || is_double($b))) - throw new TypeException('Cannot divide by a non-numeric value'); + throw new TypeException(sprintf('Cannot divide a non-numeric value \'B\' of type %s', Utilities::getType($b, true))); if ($b === 0) throw new ZeroDivisionException(sprintf('Division by zero in %s', $this)); diff --git a/src/RTEX/Objects/Program/Instructions/Arithmetic/Floor.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Floor.php new file mode 100644 index 0000000..6f4f16a --- /dev/null +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Floor.php @@ -0,0 +1,109 @@ + $this->Value, + ]); + } + + /** + * Constructs a new instance of this class from an array representation + * + * @param array $data + * @return InstructionInterface + * @throws InstructionException + */ + public static function fromArray(array $data): InstructionInterface + { + $instruction = new self(); + $instruction->setValue($data['value'] ?? null); + return $instruction; + } + + /** + * @param Engine $engine + * @return int|float + * @throws EvaluationException + * @throws TypeException + */ + public function eval(Engine $engine): int|float + { + $value = $engine->eval($this->Value); + + if(!(is_int($value) || is_float($value) || is_double($value))) + throw new TypeException(sprintf('Cannot calculate the floor value of a non-numeric value, got %s', Utilities::getType($value, true))); + + return floor($value); + } + + /** + * Returns the string representation of the instruction + * + * @return string + */ + public function __toString(): string + { + return sprintf( + self::getType() . ' (%s+%s)', + Utilities::entityToString($this->Value), + ); + } + + /** + * Gets the value of A + * + * @return mixed + */ + public function getValue(): mixed + { + return $this->Value; + } + + /** + * Sets the value of A + * + * @param mixed $Value + * @throws InstructionException + */ + public function setValue(mixed $Value): void + { + $this->Value = InstructionBuilder::fromRaw($Value); + } + + } \ No newline at end of file diff --git a/src/RTEX/Objects/Program/Instructions/Modulo.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Modulo.php similarity index 72% rename from src/RTEX/Objects/Program/Instructions/Modulo.php rename to src/RTEX/Objects/Program/Instructions/Arithmetic/Modulo.php index fbdab59..ff3cdaf 100644 --- a/src/RTEX/Objects/Program/Instructions/Modulo.php +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Modulo.php @@ -2,14 +2,15 @@ /** @noinspection PhpMissingFieldTypeInspection */ - namespace RTEX\Objects\Program\Instructions; + namespace RTEX\Objects\Program\Instructions\Arithmetic; use RTEX\Abstracts\InstructionType; use RTEX\Classes\InstructionBuilder; use RTEX\Classes\Utilities; use RTEX\Engine; - use RTEX\Exceptions\Core\MalformedInstructionException; - use RTEX\Exceptions\Core\UnsupportedVariableType; + use RTEX\Exceptions\EvaluationException; + use RTEX\Exceptions\InstructionException; + use RTEX\Exceptions\Runtime\TypeException; use RTEX\Interfaces\InstructionInterface; class Modulo implements InstructionInterface @@ -38,7 +39,6 @@ * Returns an array representation of the instruction * * @return array - * @throws UnsupportedVariableType */ public function toArray(): array { @@ -53,8 +53,7 @@ * * @param array $data * @return InstructionInterface - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public static function fromArray(array $data): InstructionInterface { @@ -66,19 +65,27 @@ /** * @param Engine $engine - * @return int - * @throws UnsupportedVariableType + * @return int|float + * @throws EvaluationException + * @throws TypeException */ - public function eval(Engine $engine): int + public function eval(Engine $engine): int|float { - return (intval($engine->eval($this->A)) % intval($engine->eval($this->B))); + $a = $engine->eval($this->A); + $b = $engine->eval($this->B); + + if(!(is_int($a) || is_float($a) || is_double($a))) + throw new TypeException(sprintf('Cannot perform modulo operation on non-numeric value \'A\' of type %s', Utilities::getType($a, true))); + if(!(is_int($b) || is_float($b) || is_double($b))) + throw new TypeException(sprintf('Cannot perform modulo operation on non-numeric value \'B\' of type %s', Utilities::getType($b. true))); + + return ($a % $b); } /** * Returns the string representation of the instruction * * @return string - * @throws UnsupportedVariableType */ public function __toString(): string { @@ -103,8 +110,7 @@ * Sets the value of A * * @param mixed $A - * @throws UnsupportedVariableType - * @throws MalformedInstructionException + * @throws InstructionException */ public function setA(mixed $A): void { @@ -125,8 +131,7 @@ * Sets the value of B * * @param mixed $B - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public function setB(mixed $B): void { diff --git a/src/RTEX/Objects/Program/Instructions/Multiply.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Multiply.php similarity index 72% rename from src/RTEX/Objects/Program/Instructions/Multiply.php rename to src/RTEX/Objects/Program/Instructions/Arithmetic/Multiply.php index 83c2a68..0ee5c70 100644 --- a/src/RTEX/Objects/Program/Instructions/Multiply.php +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Multiply.php @@ -2,14 +2,15 @@ /** @noinspection PhpMissingFieldTypeInspection */ - namespace RTEX\Objects\Program\Instructions; + namespace RTEX\Objects\Program\Instructions\Arithmetic; use RTEX\Abstracts\InstructionType; use RTEX\Classes\InstructionBuilder; use RTEX\Classes\Utilities; use RTEX\Engine; - use RTEX\Exceptions\Core\MalformedInstructionException; - use RTEX\Exceptions\Core\UnsupportedVariableType; + use RTEX\Exceptions\EvaluationException; + use RTEX\Exceptions\InstructionException; + use RTEX\Exceptions\Runtime\TypeException; use RTEX\Interfaces\InstructionInterface; class Multiply implements InstructionInterface @@ -38,7 +39,6 @@ * Returns an array representation of the instruction * * @return array - * @throws UnsupportedVariableType */ public function toArray(): array { @@ -53,8 +53,7 @@ * * @param array $data * @return InstructionInterface - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public static function fromArray(array $data): InstructionInterface { @@ -66,19 +65,27 @@ /** * @param Engine $engine - * @return int - * @throws UnsupportedVariableType + * @return int|float + * @throws EvaluationException + * @throws TypeException */ - public function eval(Engine $engine): int + public function eval(Engine $engine): int|float { - return (intval($engine->eval($this->A)) * intval($engine->eval($this->B))); + $a = $engine->eval($this->A); + $b = $engine->eval($this->B); + + if(!(is_int($a) || is_float($a) || is_double($a))) + throw new TypeException(sprintf('Cannot multiply a non-numeric value \'A\' of type \'%s\'', Utilities::getType($a, true))); + if(!(is_int($b) || is_float($b) || is_double($b))) + throw new TypeException(sprintf('Cannot multiply a non-numeric value \'B\' of type \'%s\'', Utilities::getType($b, true))); + + return ($a * $b); } /** * Returns the string representation of the instruction * * @return string - * @throws UnsupportedVariableType */ public function __toString(): string { @@ -103,8 +110,7 @@ * Sets the value of A * * @param mixed $A - * @throws UnsupportedVariableType - * @throws MalformedInstructionException + * @throws InstructionException */ public function setA(mixed $A): void { @@ -125,8 +131,7 @@ * Sets the value of B * * @param mixed $B - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public function setB(mixed $B): void { diff --git a/src/RTEX/Objects/Program/Instructions/Power.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Power.php similarity index 71% rename from src/RTEX/Objects/Program/Instructions/Power.php rename to src/RTEX/Objects/Program/Instructions/Arithmetic/Power.php index 9855be0..6f6ec0b 100644 --- a/src/RTEX/Objects/Program/Instructions/Power.php +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Power.php @@ -2,14 +2,15 @@ /** @noinspection PhpMissingFieldTypeInspection */ - namespace RTEX\Objects\Program\Instructions; + namespace RTEX\Objects\Program\Instructions\Arithmetic; use RTEX\Abstracts\InstructionType; use RTEX\Classes\InstructionBuilder; use RTEX\Classes\Utilities; use RTEX\Engine; - use RTEX\Exceptions\Core\MalformedInstructionException; - use RTEX\Exceptions\Core\UnsupportedVariableType; + use RTEX\Exceptions\EvaluationException; + use RTEX\Exceptions\InstructionException; + use RTEX\Exceptions\Runtime\TypeException; use RTEX\Interfaces\InstructionInterface; class Power implements InstructionInterface @@ -38,7 +39,6 @@ * Returns an array representation of the instruction * * @return array - * @throws UnsupportedVariableType */ public function toArray(): array { @@ -53,8 +53,7 @@ * * @param array $data * @return InstructionInterface - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public static function fromArray(array $data): InstructionInterface { @@ -66,19 +65,27 @@ /** * @param Engine $engine - * @return int - * @throws UnsupportedVariableType + * @return int|float + * @throws TypeException + * @throws EvaluationException */ - public function eval(Engine $engine): int + public function eval(Engine $engine): int|float { - return (intval($engine->eval($this->A)) ** intval($engine->eval($this->B))); + $a = $engine->eval($this->A); + $b = $engine->eval($this->B); + + if(!(is_int($a) || is_float($a) || is_double($a))) + throw new TypeException(sprintf('Cannot raise \'A\' to the power of \'B\' because \'A\' is not a number (\'%s\')', Utilities::getType($a, true))); + if(!(is_int($b) || is_float($b) || is_double($b))) + throw new TypeException(sprintf('Cannot raise \'A\' to the power of \'B\' because \'B\' is not a number (\'%s\')', Utilities::getType($b, true))); + + return ($a ** $b); } /** * Returns the string representation of the instruction * * @return string - * @throws UnsupportedVariableType */ public function __toString(): string { @@ -103,8 +110,7 @@ * Sets the value of A * * @param mixed $A - * @throws UnsupportedVariableType - * @throws MalformedInstructionException + * @throws InstructionException */ public function setA(mixed $A): void { @@ -125,8 +131,7 @@ * Sets the value of B * * @param mixed $B - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public function setB(mixed $B): void { diff --git a/src/RTEX/Objects/Program/Instructions/Arithmetic/Round.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Round.php new file mode 100644 index 0000000..9f6a3e3 --- /dev/null +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Round.php @@ -0,0 +1,142 @@ + $this->Value, + ]); + } + + /** + * Constructs a new instance of this class from an array representation + * + * @param array $data + * @return InstructionInterface + * @throws InstructionException + */ + public static function fromArray(array $data): InstructionInterface + { + $instruction = new self(); + $instruction->setValue($data['value'] ?? null); + return $instruction; + } + + /** + * @param Engine $engine + * @return float|int + * @throws EvaluationException + * @throws TypeException + */ + public function eval(Engine $engine): int|float + { + $value = $engine->eval($this->Value); + $precision = $engine->eval($this->Precision); + + if(!(is_int($value) || is_float($value) || is_double($value))) + throw new TypeException(sprintf('Cannot calculate the round value of a non-numeric value, got %s', Utilities::getType($value, true))); + + if(is_null($precision)) + return round($value); + + if(!(is_int($precision) || is_float($precision) || is_double($precision))) + throw new TypeException(sprintf('Cannot calculate the round value of a non-numeric precision, got %s', Utilities::getType($precision, true))); + + return round($value, $precision); + } + + /** + * Returns the string representation of the instruction + * + * @return string + */ + public function __toString(): string + { + return sprintf( + self::getType() . ' (%s+%s)', + Utilities::entityToString($this->Value), + ); + } + + + /** + * Gets the value of A + * + * @return mixed + */ + public function getValue(): mixed + { + return $this->Value; + } + + /** + * Sets the value of A + * + * @param mixed $Value + * @throws InstructionException + */ + public function setValue(mixed $Value): void + { + $this->Value = InstructionBuilder::fromRaw($Value); + } + + /** + * @return mixed + * @noinspection PhpUnused + */ + public function getPrecision(): mixed + { + return $this->Precision; + } + + /** + * @param mixed $Precision + * @noinspection PhpUnused + */ + public function setPrecision(mixed $Precision): void + { + $this->Precision = $Precision; + } + + } \ No newline at end of file diff --git a/src/RTEX/Objects/Program/Instructions/Arithmetic/SquareRoot.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/SquareRoot.php new file mode 100644 index 0000000..3eb985f --- /dev/null +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/SquareRoot.php @@ -0,0 +1,109 @@ + $this->Value, + ]); + } + + /** + * Constructs a new instance of this class from an array representation + * + * @param array $data + * @return InstructionInterface + * @throws InstructionException + */ + public static function fromArray(array $data): InstructionInterface + { + $instruction = new self(); + $instruction->setValue($data['value'] ?? null); + return $instruction; + } + + /** + * @param Engine $engine + * @return int|float + * @throws EvaluationException + * @throws TypeException + */ + public function eval(Engine $engine): int|float + { + $value = $engine->eval($this->Value); + + if(!(is_int($value) || is_float($value) || is_double($value))) + throw new TypeException(sprintf('Cannot calculate the square root of a non-numeric \'Value\', got type %s', Utilities::getType($value, true))); + + return sqrt($value); + } + + /** + * Returns the string representation of the instruction + * + * @return string + */ + public function __toString(): string + { + return sprintf( + self::getType() . ' (%s+%s)', + Utilities::entityToString($this->Value), + ); + } + + /** + * Gets the value of A + * + * @return mixed + */ + public function getValue(): mixed + { + return $this->Value; + } + + /** + * Sets the value of A + * + * @param mixed $Value + * @throws InstructionException + */ + public function setValue(mixed $Value): void + { + $this->Value = InstructionBuilder::fromRaw($Value); + } + + } \ No newline at end of file diff --git a/src/RTEX/Objects/Program/Instructions/Subtract.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Subtract.php similarity index 72% rename from src/RTEX/Objects/Program/Instructions/Subtract.php rename to src/RTEX/Objects/Program/Instructions/Arithmetic/Subtract.php index 5030c3f..2bef202 100644 --- a/src/RTEX/Objects/Program/Instructions/Subtract.php +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Subtract.php @@ -2,14 +2,15 @@ /** @noinspection PhpMissingFieldTypeInspection */ - namespace RTEX\Objects\Program\Instructions; + namespace RTEX\Objects\Program\Instructions\Arithmetic; use RTEX\Abstracts\InstructionType; use RTEX\Classes\InstructionBuilder; use RTEX\Classes\Utilities; use RTEX\Engine; - use RTEX\Exceptions\Core\MalformedInstructionException; - use RTEX\Exceptions\Core\UnsupportedVariableType; + use RTEX\Exceptions\EvaluationException; + use RTEX\Exceptions\InstructionException; + use RTEX\Exceptions\Runtime\TypeException; use RTEX\Interfaces\InstructionInterface; class Subtract implements InstructionInterface @@ -38,7 +39,6 @@ * Returns an array representation of the instruction * * @return array - * @throws UnsupportedVariableType */ public function toArray(): array { @@ -53,8 +53,7 @@ * * @param array $data * @return InstructionInterface - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public static function fromArray(array $data): InstructionInterface { @@ -66,19 +65,27 @@ /** * @param Engine $engine - * @return int - * @throws UnsupportedVariableType + * @return int|float + * @throws EvaluationException + * @throws TypeException */ - public function eval(Engine $engine): int + public function eval(Engine $engine): int|float { - return (intval($engine->eval($this->A)) - intval($engine->eval($this->B))); + $a = $engine->eval($this->A); + $b = $engine->eval($this->B); + + if(!(is_int($a) || is_float($a) || is_double($a))) + throw new TypeException(sprintf('Cannot subtract a non-numeric value of \'A\' of type \'%s\'', Utilities::getType($a, true))); + if(!(is_int($b) || is_float($b) || is_double($b))) + throw new TypeException(sprintf('Cannot subtract a non-numeric value of \'B\' of type \'%s\'', Utilities::getType($b, true))); + + return ($a - $b); } /** * Returns the string representation of the instruction * * @return string - * @throws UnsupportedVariableType */ public function __toString(): string { @@ -103,8 +110,7 @@ * Sets the value of A * * @param mixed $A - * @throws UnsupportedVariableType - * @throws MalformedInstructionException + * @throws InstructionException */ public function setA(mixed $A): void { @@ -125,8 +131,7 @@ * Sets the value of B * * @param mixed $B - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public function setB(mixed $B): void { diff --git a/src/RTEX/Objects/Program/Instructions/Sum.php b/src/RTEX/Objects/Program/Instructions/Arithmetic/Sum.php similarity index 73% rename from src/RTEX/Objects/Program/Instructions/Sum.php rename to src/RTEX/Objects/Program/Instructions/Arithmetic/Sum.php index 8f2df93..b5560ec 100644 --- a/src/RTEX/Objects/Program/Instructions/Sum.php +++ b/src/RTEX/Objects/Program/Instructions/Arithmetic/Sum.php @@ -2,14 +2,15 @@ /** @noinspection PhpMissingFieldTypeInspection */ - namespace RTEX\Objects\Program\Instructions; + namespace RTEX\Objects\Program\Instructions\Arithmetic; use RTEX\Abstracts\InstructionType; use RTEX\Classes\InstructionBuilder; use RTEX\Classes\Utilities; use RTEX\Engine; - use RTEX\Exceptions\Core\MalformedInstructionException; - use RTEX\Exceptions\Core\UnsupportedVariableType; + use RTEX\Exceptions\EvaluationException; + use RTEX\Exceptions\InstructionException; + use RTEX\Exceptions\Runtime\TypeException; use RTEX\Interfaces\InstructionInterface; class Sum implements InstructionInterface @@ -38,7 +39,6 @@ * Returns an array representation of the instruction * * @return array - * @throws UnsupportedVariableType */ public function toArray(): array { @@ -53,8 +53,7 @@ * * @param array $data * @return InstructionInterface - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public static function fromArray(array $data): InstructionInterface { @@ -66,19 +65,27 @@ /** * @param Engine $engine - * @return int - * @throws UnsupportedVariableType + * @return int|float + * @throws EvaluationException + * @throws TypeException */ - public function eval(Engine $engine): int + public function eval(Engine $engine): int|float { - return (intval($engine->eval($this->A)) + intval($engine->eval($this->B))); + $a = $engine->eval($this->A); + $b = $engine->eval($this->B); + + if(!(is_int($a) || is_float($a) || is_double($a))) + throw new TypeException(sprintf('Cannot sum a non-numeric value of \'A\' of type %s', Utilities::getType($a, true))); + if(!(is_int($b) || is_float($b) || is_double($b))) + throw new TypeException(sprintf('Cannot sum a non-numeric value of \'B\' of type %s', Utilities::getType($b, true))); + + return ($a + $b); } /** * Returns the string representation of the instruction * * @return string - * @throws UnsupportedVariableType */ public function __toString(): string { @@ -103,8 +110,7 @@ * Sets the value of A * * @param mixed $A - * @throws UnsupportedVariableType - * @throws MalformedInstructionException + * @throws InstructionException */ public function setA(mixed $A): void { @@ -125,8 +131,7 @@ * Sets the value of B * * @param mixed $B - * @throws MalformedInstructionException - * @throws UnsupportedVariableType + * @throws InstructionException */ public function setB(mixed $B): void {