Refactored Base instructions and added documentation

This commit is contained in:
Netkas 2022-12-30 02:47:43 -05:00
parent deccb1f6fa
commit dc0811a271
10 changed files with 372 additions and 72 deletions

View file

@ -0,0 +1,41 @@
# array_set
Set an item in an array using "dot" notation.
## Parameters
* array (`array`, `instruction`) - The array to get the value from.
* key (`string`, `instruction`) - The key to get the value for.
* value (`any`, `instruction`) - The value to set.
## Return
(`array`) - The array with the new value set.
## Exceptions
* `EvaluationException` - If there was an error while evaluating one or more parameters.
* `KeyException` - If the key is not found.
* `TypeException` - If one or more parameters are not of the expected type.
## Instruction Example
```json
{
"type": "array_set",
"_": {
"array": {
"foo": {
"bar": "baz"
}
},
"key": "foo.bar",
"value": "qux"
}
}
```
### Last Updated
Monday, December 26th, 2022.
Written by [Netkas](https://git.n64.cc/netkas)

View file

@ -0,0 +1,42 @@
# invoke
Invokes a method under a namespace.
## Parameters
* namespace (`string`, `instruction`) - The namespace to invoke the method under.
* method (`string`, `instruction`) - The method to invoke.
* parameters (`array`, `instruction`) - The parameters to pass to the method.
* fail_on_error (`boolean`, `instruction`) - Whether to fail if the method throws an exception.
## Return
(`any`) - The return value of the method. See the method's documentation for more information.
## Exceptions
* `EvaluationException` - If there was an error while evaluating one or more parameters.
* `TypeException` - If one or more parameters are not of the expected type.
* `UndefinedMethodException` - If the method is not defined.
* `Exception` - If the method throws an exception and `fail_on_error` is `true`.
## Instruction Example
```json
{
"type": "invoke",
"_": {
"namespace": "system",
"method": "print",
"parameters": {
"value": "Hello, world!"
},
"fail_on_error": true
}
}
```
### Last Updated
Monday, December 29th, 2022.
Written by [Netkas](https://git.n64.cc/netkas)

View file

@ -0,0 +1,35 @@
# set
Sets aor overwrites a variable in the environment.
## Parameters
* name (`string`, `instruction`) - The name of the variable to get.
* value (`any`, `instruction`) - The value to set.
## Return
(`null`) - Nothing.
## Exceptions
* `EvaluationException` - If there was an error while evaluating one or more parameters.
* `TypeException` - If one or more parameters are not of the expected type.
## Instruction Example
```json
{
"type": "set",
"_": {
"name": "foo",
"value": "bar"
}
}
```
### Last Updated
Monday, December 29th, 2022.
Written by [Netkas](https://git.n64.cc/netkas)

View file

@ -2,7 +2,7 @@
/** @noinspection PhpMissingFieldTypeInspection */
namespace RTEX\Objects\Program\Instructions;
namespace RTEX\Objects\Program\Instructions\Base;
use RTEX\Abstracts\InstructionType;
use RTEX\Abstracts\RegexPatterns;
@ -30,7 +30,7 @@
*
* @var mixed
*/
private $Value;
private $Key;
/**
* The name of the variable to set
@ -63,10 +63,11 @@
/**
* @return mixed
* @noinspection PhpUnused
*/
public function getValue(): mixed
public function getKey(): mixed
{
return $this->Value;
return $this->Key;
}
/**
@ -74,9 +75,9 @@
* @throws InstructionException
* @noinspection PhpMissingParamTypeInspection
*/
public function setValue($value): void
public function setKey($value): void
{
$this->Value = InstructionBuilder::fromRaw($value);
$this->Key = InstructionBuilder::fromRaw($value);
}
/**
@ -88,7 +89,7 @@
{
return InstructionBuilder::toRaw(self::getType(), [
'array' => $this->Array,
'value' => $this->Value
'key' => $this->Key
]);
}
@ -101,7 +102,7 @@
{
$instruction = new self();
$instruction->setArray($data['array'] ?? null);
$instruction->setValue($data['value'] ?? null);
$instruction->setKey($data['key'] ?? null);
return $instruction;
}
@ -115,17 +116,18 @@
*/
public function eval(Engine $engine): mixed
{
$value = $engine->eval($this->Value);
$key = $engine->eval($this->Key);
$array = $engine->eval($this->Array);
/** @noinspection DuplicatedCode */
if (!is_array($array))
throw new KeyException(sprintf('Cannot read from non-array value of type %s', Utilities::getType($array, true)));
if(!is_string($value) && !is_int($value))
throw new TypeException(sprintf('Cannot read from array with non-string value %s', Utilities::getType($value, true)));
if(!Validate::validateRegex($value, RegexPatterns::ArrayQuery))
throw new KeyException(sprintf('Cannot read from array with invalid query %s', $value));
if(!is_string($key) && !is_int($key))
throw new TypeException(sprintf('Cannot read from array with non-string value %s', Utilities::getType($key, true)));
if(!Validate::validateRegex($key, RegexPatterns::ArrayQuery))
throw new KeyException(sprintf('Cannot read from array with invalid query %s', $key));
$keys = explode('.', $value);
$keys = explode('.', $key);
$result = $array;
foreach ($keys as $key)
{
@ -135,7 +137,7 @@
}
else
{
throw new KeyException(sprintf('Key "%s" does not exist in array (%s)', $key, $value));
throw new KeyException(sprintf('Key "%s" does not exist in array (%s)', $key, $key));
}
}
@ -148,9 +150,9 @@
public function __toString(): string
{
return sprintf(
self::getType() . ' (array: %s, value: %s)',
self::getType() . ' %s[%s]',
Utilities::entityToString($this->Array),
Utilities::entityToString($this->Value)
Utilities::entityToString($this->Key)
);
}
}

View file

@ -0,0 +1,183 @@
<?php
/** @noinspection PhpMissingFieldTypeInspection */
namespace RTEX\Objects\Program\Instructions\Base;
use RTEX\Abstracts\InstructionType;
use RTEX\Abstracts\RegexPatterns;
use RTEX\Classes\InstructionBuilder;
use RTEX\Classes\Utilities;
use RTEX\Classes\Validate;
use RTEX\Engine;
use RTEX\Exceptions\EvaluationException;
use RTEX\Exceptions\InstructionException;
use RTEX\Exceptions\Runtime\KeyException;
use RTEX\Exceptions\Runtime\TypeException;
use RTEX\Interfaces\InstructionInterface;
class ArraySet implements InstructionInterface
{
/**
* The array to read from
*
* @var mixed
*/
private $Array;
/**
* The query to use to read from the array
*
* @var mixed
*/
private $Key;
/**
* The value to set the key's value to
*
* @var mixed
*/
private $Value;
/**
* The name of the variable to set
*
* @return string
*/
public function getType(): string
{
return InstructionType::ArraySet;
}
/**
* @return mixed
* @noinspection PhpUnused
*/
public function getArray(): mixed
{
return $this->Array;
}
/**
* @param mixed $variable
* @throws InstructionException
* @noinspection PhpMissingParamTypeInspection
*/
public function setArray($variable): void
{
$this->Array = InstructionBuilder::fromRaw($variable);
}
/**
* @return mixed
* @noinspection PhpUnused
*/
public function getKey(): mixed
{
return $this->Key;
}
/**
* @param mixed $value
* @throws InstructionException
* @noinspection PhpMissingParamTypeInspection
*/
public function setKey($value): void
{
$this->Key = InstructionBuilder::fromRaw($value);
}
/**
* @return mixed
*/
public function getValue(): mixed
{
return $this->Value;
}
/**
* @param mixed $Value
*/
public function setValue(mixed $Value): void
{
$this->Value = $Value;
}
/**
* Returns an array representation of the object
*
* @return array
*/
public function toArray(): array
{
return InstructionBuilder::toRaw(self::getType(), [
'array' => $this->Array,
'key' => $this->Key,
'value' => $this->Value
]);
}
/**
* @param array $data
* @return InstructionInterface
* @throws InstructionException
*/
public static function fromArray(array $data): InstructionInterface
{
$instruction = new self();
$instruction->setArray($data['array'] ?? null);
$instruction->setKey($data['key'] ?? null);
$instruction->setValue($data['value'] ?? null);
return $instruction;
}
/**
* @param Engine $engine
* @return array
* @throws EvaluationException
* @throws KeyException
* @throws TypeException
* @noinspection DuplicatedCode
*/
public function eval(Engine $engine): array
{
$key = $engine->eval($this->Key);
$array = $engine->eval($this->Array);
$value = $engine->eval($this->Value);
if (!is_array($array))
throw new KeyException(sprintf('Cannot read from non-array value of type %s', Utilities::getType($array, true)));
if(!is_string($key) && !is_int($key))
throw new TypeException(sprintf('Cannot read from array with non-string value %s', Utilities::getType($key, true)));
if(!Validate::validateRegex($key, RegexPatterns::ArrayQuery))
throw new KeyException(sprintf('Cannot read from array with invalid query %s', $key));
$keys = explode('.', $key);
$result = &$array; // use a reference so we can modify the original array
foreach ($keys as $key)
{
if (!(is_array($result) && array_key_exists($key, $result)))
throw new KeyException(sprintf('Key "%s" does not exist in array (%s)', $key, $value));
$result = &$result[$key];
}
$result = $value;
return $array;
}
/**
* @inheritDoc
*/
public function __toString(): string
{
return sprintf(
self::getType() . ' %s[%s]=%s',
Utilities::entityToString($this->Array),
Utilities::entityToString($this->Key),
Utilities::entityToString($this->Value)
);
}
}

View file

@ -2,7 +2,7 @@
/** @noinspection PhpMissingFieldTypeInspection */
namespace RTEX\Objects\Program\Instructions;
namespace RTEX\Objects\Program\Instructions\Base;
use RTEX\Abstracts\InstructionType;
use RTEX\Classes\InstructionBuilder;
@ -67,14 +67,9 @@
$variable = $engine->eval($this->VariableName);
if(!is_string($variable))
throw new TypeException(sprintf('Expected string, got %s', Utilities::getType($variable)));
if (!$engine->getEnvironment()->variableExists($variable))
throw new NameException("Variable '$variable' is not defined");
throw new TypeException(sprintf('Expected string, got %s', Utilities::getType($variable, true)));
return $engine->getEnvironment()->getRuntimeVariable(
$engine->eval($this->VariableName)
);
return $engine->getEnvironment()->getRuntimeVariable($variable);
}
/**
@ -110,7 +105,7 @@
public function __toString(): string
{
return sprintf(
self::getType() . ' (name: %s)',
self::getType() . ' %s',
Utilities::entityToString($this->VariableName)
);
}

View file

@ -2,14 +2,16 @@
/** @noinspection PhpMissingFieldTypeInspection */
namespace RTEX\Objects\Program\Instructions;
namespace RTEX\Objects\Program\Instructions\Base;
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\ImportException;
use RTEX\Exceptions\Runtime\TypeException;
use RTEX\Interfaces\InstructionInterface;
class Invoke implements InstructionInterface
@ -60,7 +62,6 @@
/**
* @return array
* @throws UnsupportedVariableType
*/
public function toArray(): array
{
@ -68,7 +69,7 @@
'namespace' => $this->Namespace,
'method' => $this->Method,
'parameters' => $this->Parameters,
'fail_on_error' => $this->FailOnError,
'fail_on_error' => $this->FailOnError, // TODO: Implement this
]);
}
@ -77,8 +78,7 @@
*
* @param array $data
* @return InstructionInterface
* @throws MalformedInstructionException
* @throws UnsupportedVariableType
* @throws InstructionException
*/
public static function fromArray(array $data): InstructionInterface
{
@ -96,19 +96,24 @@
*
* @param Engine $engine
* @return mixed
* @throws UnsupportedVariableType
* @noinspection PhpMissingReturnTypeInspection
* @throws EvaluationException
* @throws ImportException
* @throws TypeException
*/
public function eval(Engine $engine)
public function eval(Engine $engine): mixed
{
$namespace = $engine->eval($this->Namespace);
$method = $engine->eval($this->Method);
$parameters = [];
foreach($this->Parameters as $key => $value)
$parameters[$key] = $engine->eval($value);
return $engine->callMethod(
$engine->eval($this->Namespace), $engine->eval($this->Method),
$parameters
);
if(!is_string($namespace))
throw new TypeException(sprintf('The namespace must be a string, %s given', Utilities::getType($namespace, true)));
if(!is_string($method))
throw new TypeException(sprintf('The method must be a string, %s given', Utilities::getType($method, true)));
return $engine->callMethod($namespace, $method, $parameters);
}
/**
@ -156,8 +161,7 @@
/**
* @param array $Parameters
* @throws MalformedInstructionException
* @throws UnsupportedVariableType
* @throws InstructionException
*/
public function setParameters(array $Parameters): void
{
@ -183,7 +187,6 @@
/**
* @inheritDoc
* @throws UnsupportedVariableType
*/
public function __toString(): string
{

View file

@ -2,14 +2,15 @@
/** @noinspection PhpMissingFieldTypeInspection */
namespace RTEX\Objects\Program\Instructions;
namespace RTEX\Objects\Program\Instructions\Base;
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 SetVariable implements InstructionInterface
@ -19,7 +20,7 @@
*
* @var mixed
*/
private $Variable;
private $Name;
/**
* The value to set the variable to
@ -38,41 +39,38 @@
return InstructionType::SetVariable;
}
/**
* @return mixed
* @noinspection PhpMissingReturnTypeInspection
* @noinspection PhpUnused
*/
public function getVariable()
public function getName(): mixed
{
return $this->Variable;
return $this->Name;
}
/**
* @param mixed $variable
* @throws UnsupportedVariableType
* @throws MalformedInstructionException
* @throws InstructionException
* @noinspection PhpMissingParamTypeInspection
*/
public function setVariable($variable): void
public function setName($variable): void
{
$this->Variable = InstructionBuilder::fromRaw($variable);
$this->Name = InstructionBuilder::fromRaw($variable);
}
/**
* @return mixed
* @noinspection PhpMissingReturnTypeInspection
*/
public function getValue()
public function getValue(): mixed
{
return $this->Value;
}
/**
* @param mixed $value
* @throws MalformedInstructionException
* @throws UnsupportedVariableType
* @throws InstructionException
* @noinspection PhpMissingParamTypeInspection
*/
public function setValue($value): void
@ -84,12 +82,11 @@
* Returns an array representation of the object
*
* @return array
* @throws UnsupportedVariableType
*/
public function toArray(): array
{
return InstructionBuilder::toRaw(self::getType(), [
'variable' => $this->Variable,
'name' => $this->Name,
'value' => $this->Value
]);
}
@ -97,13 +94,12 @@
/**
* @param array $data
* @return InstructionInterface
* @throws MalformedInstructionException
* @throws UnsupportedVariableType
* @throws InstructionException
*/
public static function fromArray(array $data): InstructionInterface
{
$instruction = new self();
$instruction->setVariable($data['variable'] ?? null);
$instruction->setName($data['name'] ?? null);
$instruction->setValue($data['value'] ?? null);
return $instruction;
@ -112,25 +108,28 @@
/**
* @param Engine $engine
* @return void
* @throws UnsupportedVariableType
* @throws EvaluationException
* @throws TypeException
*/
public function eval(Engine $engine): void
{
$engine->getEnvironment()->setRuntimeVariable(
$engine->eval($this->Variable),
$engine->eval($this->Value)
);
$name = $engine->eval($this->Name);
$value = $engine->eval($this->Value);
if(!is_string($name))
throw new TypeException(sprintf('Variable name must be a string, %s given', Utilities::getType($name, true)));
$engine->getEnvironment()->setRuntimeVariable($name, $value);
}
/**
* @inheritDoc
* @throws UnsupportedVariableType
*/
public function __toString(): string
{
return sprintf(
self::getType() . ' (variable: %s, value: %s)',
Utilities::entityToString($this->Variable),
self::getType() . ' %s VALUE %s',
Utilities::entityToString($this->Name),
Utilities::entityToString($this->Value)
);
}