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

View file

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

View file

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