Minor changes
This commit is contained in:
parent
05cc358eea
commit
e9d033044c
27 changed files with 949 additions and 94 deletions
2
.idea/php.xml
generated
2
.idea/php.xml
generated
|
@ -15,6 +15,8 @@
|
||||||
<path value="/etc/ncc" />
|
<path value="/etc/ncc" />
|
||||||
<path value="/var/ncc/packages/net.nosial.optslib=1.0.1" />
|
<path value="/var/ncc/packages/net.nosial.optslib=1.0.1" />
|
||||||
<path value="/var/ncc/packages/net.nosial.loglib=1.0.0" />
|
<path value="/var/ncc/packages/net.nosial.loglib=1.0.0" />
|
||||||
|
<path value="/var/ncc/packages/net.nosial.rtex_filesystem=1.0.0" />
|
||||||
|
<path value="/var/ncc/packages/com.cheprasov.php_redis_client=1.10.0" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||||
|
|
1
.idea/webResources.xml
generated
1
.idea/webResources.xml
generated
|
@ -6,6 +6,7 @@
|
||||||
<entryData>
|
<entryData>
|
||||||
<resourceRoots>
|
<resourceRoots>
|
||||||
<path value="file://$PROJECT_DIR$/instructions" />
|
<path value="file://$PROJECT_DIR$/instructions" />
|
||||||
|
<path value="file://$PROJECT_DIR$/types" />
|
||||||
</resourceRoots>
|
</resourceRoots>
|
||||||
</entryData>
|
</entryData>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
BIN
InstructionInterface.png
Normal file
BIN
InstructionInterface.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 339 KiB |
32
README.md
32
README.md
|
@ -10,13 +10,28 @@ or you are executing programs written by users,
|
||||||
but you don't want to give them the ability to
|
but you don't want to give them the ability to
|
||||||
execute arbitrary code on your system
|
execute arbitrary code on your system
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
<!-- TOC -->
|
||||||
|
* [RTEX Engine](#rtex-engine)
|
||||||
|
* [Table of Contents](#table-of-contents)
|
||||||
|
* [How does it work?](#how-does-it-work)
|
||||||
|
* [Instructions](#instructions)
|
||||||
|
* [Methods & Namespaces](#methods--namespaces)
|
||||||
|
* [Builtin Instruction Sets](#builtin-instruction-sets)
|
||||||
|
* [License](#license)
|
||||||
|
* [Contributing](#contributing)
|
||||||
|
<!-- TOC -->
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
## How does it work?
|
## How does it work?
|
||||||
|
|
||||||
RTEX Engine operates on the simple principle of executing
|
RTEX Engine operates on the simple principle of executing
|
||||||
instructions in order, and then moving on to the next
|
instructions in order, and then moving on to the next
|
||||||
instruction.
|
instruction.
|
||||||
|
|
||||||
|
[README.md](README.md)
|
||||||
### Instructions
|
### Instructions
|
||||||
|
|
||||||
Instructions are simply associative arrays that contain
|
Instructions are simply associative arrays that contain
|
||||||
|
@ -35,8 +50,6 @@ functions do not provide a way to interact with the host
|
||||||
system or the filesystem, but you can extend the engine
|
system or the filesystem, but you can extend the engine
|
||||||
with your own methods and namespaces
|
with your own methods and namespaces
|
||||||
|
|
||||||
#### JSON Representation
|
|
||||||
|
|
||||||
Since instructions are associative arrays, they can be
|
Since instructions are associative arrays, they can be
|
||||||
represented in JSON, which is a common format for data
|
represented in JSON, which is a common format for data
|
||||||
transfer. The following is an example of a set of
|
transfer. The following is an example of a set of
|
||||||
|
@ -86,6 +99,7 @@ instructions that is shown above in JSON format:
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Methods & Namespaces
|
### Methods & Namespaces
|
||||||
|
|
||||||
Methods are different to instructions in the terms
|
Methods are different to instructions in the terms
|
||||||
|
@ -106,6 +120,18 @@ when they are invoked.
|
||||||
***Note:*** This functionality is a WIP, more
|
***Note:*** This functionality is a WIP, more
|
||||||
information will be added as it is implemented
|
information will be added as it is implemented
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
## Builtin Instruction Sets
|
||||||
|
|
||||||
|
RTEX Engine comes with a limited set of instructions by default,
|
||||||
|
but you can extend the engine with your own methods and namespaces
|
||||||
|
|
||||||
|
- base
|
||||||
|
- [get](docs/instructions/base/get.md)
|
||||||
|
- [set](docs/instructions/base/get.md)
|
||||||
|
- math
|
||||||
|
- [add](docs/instructions/add.md)
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
|
|
81
config_example.yaml
Normal file
81
config_example.yaml
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# Runtime configuration for RTEX, this section defines the configuration
|
||||||
|
# values used for the engine. Allowing you to set a maximum number of
|
||||||
|
# resources a program may use, or disable certain instructions.
|
||||||
|
# you can also import other NCC packages designed to extend RTEX
|
||||||
|
# such as the 'com.nosia.rtex_filesystem' package which adds IO functionality to RTEX.
|
||||||
|
runtime:
|
||||||
|
# The maximum value size in bytes, this is the maximum size of a value
|
||||||
|
# that can be stored in memory. This is used to prevent programs from
|
||||||
|
# using too much memory.
|
||||||
|
# (default: 0)
|
||||||
|
max_variable_size: 0
|
||||||
|
|
||||||
|
# The maximum number of variables that can be stored in memory at once.
|
||||||
|
# (default: 0)
|
||||||
|
max_variables: 0
|
||||||
|
|
||||||
|
# The maximum number of instructions that can be executed before the
|
||||||
|
# program is terminated.
|
||||||
|
# (default: 0)
|
||||||
|
max_stack_size: 0
|
||||||
|
|
||||||
|
# A list of instructions that are disabled, this is used to prevent
|
||||||
|
# programs from using certain instructions.
|
||||||
|
# (default: [])
|
||||||
|
instruction_blacklist:
|
||||||
|
- "eq"
|
||||||
|
- "neq"
|
||||||
|
- "gt"
|
||||||
|
- "gte"
|
||||||
|
|
||||||
|
# A list of packages to import, this is used to import packages that
|
||||||
|
# extend the functionality of RTEX.
|
||||||
|
# (default: [])
|
||||||
|
import_namespaces:
|
||||||
|
- "com.nosial.rtex_filesystem"
|
||||||
|
|
||||||
|
# Enabling supervisor mode will allow the runtime to spawn the program
|
||||||
|
# as a child process and monitor the resource usage of the child process.
|
||||||
|
# This is useful to terminate badly behaving programs. (eg; infinite loops)
|
||||||
|
# The supervisor will terminate the child process if it exceeds the
|
||||||
|
# resource limits set in the runtime section.
|
||||||
|
supervisor:
|
||||||
|
|
||||||
|
# If true, the supervisor will be enabled
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
# The maximum number of seconds a program can run for
|
||||||
|
max_execution_time: 100 # in seconds
|
||||||
|
|
||||||
|
# The maximum number of seconds a program can use the CPU for
|
||||||
|
max_cpu_time: 100 # in seconds
|
||||||
|
|
||||||
|
# The maximum number of bytes a program can use for memory
|
||||||
|
max_memory: 1000000 # in bytes
|
||||||
|
|
||||||
|
|
||||||
|
# Enabling a Redis hook will allow for easier debugging of programs.
|
||||||
|
# This will allow you to view the state of the program at any time
|
||||||
|
# This works by providing a reference ID to the program as a command-line
|
||||||
|
# argument.
|
||||||
|
#
|
||||||
|
# The engine will then connect to a Redis server and store the state of
|
||||||
|
# the program in a Redis hash. This hash will be updated every time the
|
||||||
|
# program executes an instruction.
|
||||||
|
#
|
||||||
|
# Libraries can also use this hook to store data in the Redis hash.
|
||||||
|
redis_hook:
|
||||||
|
# If true, the Redis hook will be enabled
|
||||||
|
enabled: True
|
||||||
|
|
||||||
|
# The host of the Redis server
|
||||||
|
host: "127.0.0.1"
|
||||||
|
|
||||||
|
# The port of the Redis server
|
||||||
|
port: 6379
|
||||||
|
|
||||||
|
# The password of the Redis server (optional)
|
||||||
|
password: null
|
||||||
|
|
||||||
|
# If the information should be destroyed when the program exits
|
||||||
|
destroy_on_exit: False
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"type": "get",
|
|
||||||
"_": {
|
|
||||||
"variable": "foo"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"type": "set",
|
|
||||||
"_": {
|
|
||||||
"variable": "foo",
|
|
||||||
"value": "bar"
|
|
||||||
}
|
|
||||||
}
|
|
11
project.json
11
project.json
|
@ -38,7 +38,10 @@
|
||||||
"build": {
|
"build": {
|
||||||
"source_path": "src",
|
"source_path": "src",
|
||||||
"default_configuration": "release",
|
"default_configuration": "release",
|
||||||
"main_execution": "main",
|
"main": {
|
||||||
|
"policy": "main",
|
||||||
|
"create_symlink": true
|
||||||
|
},
|
||||||
"define_constants": {
|
"define_constants": {
|
||||||
"ASSEMBLY_NAME": "%ASSEMBLY.NAME%",
|
"ASSEMBLY_NAME": "%ASSEMBLY.NAME%",
|
||||||
"ASSEMBLY_PACKAGE": "%ASSEMBLY.PACKAGE%",
|
"ASSEMBLY_PACKAGE": "%ASSEMBLY.PACKAGE%",
|
||||||
|
@ -57,6 +60,12 @@
|
||||||
"version": "latest",
|
"version": "latest",
|
||||||
"source_type": "remote",
|
"source_type": "remote",
|
||||||
"source": "nosial/libs.log=latest@n64"
|
"source": "nosial/libs.log=latest@n64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "com.cheprasov.php_redis_client",
|
||||||
|
"version": "latest",
|
||||||
|
"source_type": "remote",
|
||||||
|
"source": "cheprasov/php-redis-client=latest@composer"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
const Equals = 'eq';
|
const Equals = 'eq';
|
||||||
const NotEquals = 'neq';
|
const NotEquals = 'neq';
|
||||||
const GreaterThan = 'gt';
|
const GreaterThan = 'gt';
|
||||||
const GreaterThanOrEquals = 'gte';
|
const GreaterThanOrEqual = 'gte';
|
||||||
const LessThan = 'lt';
|
const LessThan = 'lt';
|
||||||
const LessThanOrEquals = 'lte';
|
const LessThanOrEqual = 'lte';
|
||||||
|
|
||||||
|
|
||||||
const All = [
|
const All = [
|
||||||
|
@ -52,9 +52,9 @@
|
||||||
|
|
||||||
self::Equals,
|
self::Equals,
|
||||||
self::GreaterThan,
|
self::GreaterThan,
|
||||||
self::GreaterThanOrEquals,
|
self::GreaterThanOrEqual,
|
||||||
self::LessThan,
|
self::LessThan,
|
||||||
self::LessThanOrEquals,
|
self::LessThanOrEqual,
|
||||||
self::NotEquals,
|
self::NotEquals,
|
||||||
];
|
];
|
||||||
}
|
}
|
27
src/RTEX/Classes/RedisHookInstance.php
Normal file
27
src/RTEX/Classes/RedisHookInstance.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?php /** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
|
namespace RTEX\Classes;
|
||||||
|
|
||||||
|
use RedisClient\RedisClient;
|
||||||
|
|
||||||
|
class RedisHookInstance
|
||||||
|
{
|
||||||
|
public function __construct(string $host, int $port, ?string $password=null)
|
||||||
|
{
|
||||||
|
if(extension_loaded('redis'))
|
||||||
|
{
|
||||||
|
$this->Redis = new \Redis();
|
||||||
|
$this->Redis->connect($host, $port);
|
||||||
|
if($password !== null)
|
||||||
|
$this->Redis->auth($password);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->Redis = new RedisClient([
|
||||||
|
'host' => $host,
|
||||||
|
'port' => $port,
|
||||||
|
'password' => $password
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,10 +12,11 @@
|
||||||
* Determines the type of variable, throws an exception if the type is not supported
|
* Determines the type of variable, throws an exception if the type is not supported
|
||||||
*
|
*
|
||||||
* @param $input
|
* @param $input
|
||||||
|
* @param bool $return_unknown
|
||||||
* @return string
|
* @return string
|
||||||
* @throws TypeException
|
* @throws TypeException
|
||||||
*/
|
*/
|
||||||
public static function getType($input): string
|
public static function getType($input, bool $return_unknown=false): string
|
||||||
{
|
{
|
||||||
if ($input instanceof InstructionInterface)
|
if ($input instanceof InstructionInterface)
|
||||||
return VariableType::Instruction;
|
return VariableType::Instruction;
|
||||||
|
@ -33,6 +34,8 @@
|
||||||
return VariableType::Array;
|
return VariableType::Array;
|
||||||
if (is_null($input))
|
if (is_null($input))
|
||||||
return VariableType::Null;
|
return VariableType::Null;
|
||||||
|
if ($return_unknown)
|
||||||
|
return VariableType::Unknown;
|
||||||
|
|
||||||
throw new TypeException(gettype($input));
|
throw new TypeException(gettype($input));
|
||||||
}
|
}
|
||||||
|
@ -43,9 +46,8 @@
|
||||||
*
|
*
|
||||||
* @param $input
|
* @param $input
|
||||||
* @return array|mixed
|
* @return array|mixed
|
||||||
* @noinspection PhpMissingReturnTypeInspection
|
|
||||||
*/
|
*/
|
||||||
public static function toArray($input)
|
public static function toArray($input): mixed
|
||||||
{
|
{
|
||||||
if($input instanceof InstructionInterface)
|
if($input instanceof InstructionInterface)
|
||||||
return $input->toArray();
|
return $input->toArray();
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
namespace RTEX;
|
namespace RTEX;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use LogLib\Log;
|
use LogLib\Log;
|
||||||
use RTEX\Abstracts\VariableTypes;
|
use RTEX\Exceptions\EvaluationException;
|
||||||
use RTEX\Classes\Utilities;
|
|
||||||
use RTEX\Exceptions\Core\UnsupportedVariableType;
|
|
||||||
use RTEX\Interfaces\InstructionInterface;
|
use RTEX\Interfaces\InstructionInterface;
|
||||||
use RTEX\Objects\Environment;
|
use RTEX\Objects\Engine\Environment;
|
||||||
use RTEX\Objects\Program;
|
use RTEX\Objects\Program;
|
||||||
|
|
||||||
class Engine
|
class Engine
|
||||||
|
@ -32,9 +33,9 @@
|
||||||
* Executes the program by running the main script of the program
|
* Executes the program by running the main script of the program
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws UnsupportedVariableType
|
* @throws EvaluationException
|
||||||
*/
|
*/
|
||||||
public function run()
|
public function run(): void
|
||||||
{
|
{
|
||||||
foreach($this->Program->getMain()->getInstructions() as $instruction)
|
foreach($this->Program->getMain()->getInstructions() as $instruction)
|
||||||
{
|
{
|
||||||
|
@ -47,21 +48,25 @@
|
||||||
*
|
*
|
||||||
* @param $input
|
* @param $input
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws UnsupportedVariableType
|
* @throws EvaluationException
|
||||||
* @noinspection PhpMissingReturnTypeInspection
|
|
||||||
*/
|
*/
|
||||||
public function eval($input)
|
public function eval($input): mixed
|
||||||
{
|
{
|
||||||
switch(Utilities::determineType($input))
|
try
|
||||||
{
|
{
|
||||||
case VariableTypes::Instruction:
|
if($input instanceof InstructionInterface)
|
||||||
/** @var InstructionInterface $input */
|
{
|
||||||
|
Log::debug('net.nosial.rtex', $input);
|
||||||
return $input->eval($this);
|
return $input->eval($this);
|
||||||
|
|
||||||
default:
|
|
||||||
return $input;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
throw new EvaluationException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Program
|
* @return Program
|
||||||
|
@ -86,4 +91,18 @@
|
||||||
{
|
{
|
||||||
return $this->Environment;
|
return $this->Environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the method
|
||||||
|
*
|
||||||
|
* @param string $namespace
|
||||||
|
* @param string $method
|
||||||
|
* @param array $arguments
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function callMethod(string $namespace, string $method, array $arguments)
|
||||||
|
{
|
||||||
|
// TODO: Implement callMethod() method.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace RTEX\Exceptions\Core;
|
|
||||||
|
|
||||||
class MalformedInstructionException extends \Exception
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* MalformedInstructionException constructor.
|
|
||||||
*
|
|
||||||
* @param string $message
|
|
||||||
*/
|
|
||||||
public function __construct(string $message)
|
|
||||||
{
|
|
||||||
parent::__construct($message);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace RTEX\Exceptions\Core;
|
|
||||||
|
|
||||||
class UnsupportedInstructionException extends \Exception
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* UnsupportedInstructionException constructor.
|
|
||||||
*
|
|
||||||
* @param string $message
|
|
||||||
*/
|
|
||||||
public function __construct(string $message)
|
|
||||||
{
|
|
||||||
parent::__construct($message);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace RTEX\Exceptions\Core;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class UnsupportedVariableType extends Exception
|
|
||||||
{
|
|
||||||
public function __construct($type)
|
|
||||||
{
|
|
||||||
parent::__construct("Unsupported variable type: $type");
|
|
||||||
}
|
|
||||||
}
|
|
21
src/RTEX/Interfaces/DefinedNamespaceInterface.php
Normal file
21
src/RTEX/Interfaces/DefinedNamespaceInterface.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RTEX\Interfaces;
|
||||||
|
|
||||||
|
interface DefinedNamespaceInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns an array of available methods with their names as keys
|
||||||
|
* and their class names as values (e.g. ['clear' => ClearMethod::class])
|
||||||
|
*
|
||||||
|
* @return MethodInterface[]
|
||||||
|
*/
|
||||||
|
public static function getMethods(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the namespace (e.g. 'console')
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getName(): string;
|
||||||
|
}
|
18
src/RTEX/Interfaces/MethodInterface.php
Normal file
18
src/RTEX/Interfaces/MethodInterface.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RTEX\Interfaces;
|
||||||
|
|
||||||
|
use RTEX\Engine;
|
||||||
|
|
||||||
|
interface MethodInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Invokes the method with the given parameters and returns the result
|
||||||
|
* of the invocation
|
||||||
|
*
|
||||||
|
* @param Engine $engine
|
||||||
|
* @param array $parameters
|
||||||
|
* @return mixed|void
|
||||||
|
*/
|
||||||
|
public static function invoke(Engine $engine, array $parameters);
|
||||||
|
}
|
57
src/RTEX/Objects/Engine/Configuration.php
Normal file
57
src/RTEX/Objects/Engine/Configuration.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
|
namespace RTEX\Objects\Engine;
|
||||||
|
|
||||||
|
use RTEX\Objects\Engine\Configuration\RedisHook;
|
||||||
|
|
||||||
|
class Configuration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The redis hook configuration
|
||||||
|
*
|
||||||
|
* @var RedisHook
|
||||||
|
*/
|
||||||
|
private $RedisHook;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->RedisHook = new RedisHook();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the redis hook configuration
|
||||||
|
*
|
||||||
|
* @return RedisHook
|
||||||
|
*/
|
||||||
|
public function getRedisHook(): RedisHook
|
||||||
|
{
|
||||||
|
return $this->RedisHook;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array representation of the configuration
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'redis_hook' => $this->RedisHook->toArray()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a configuration object from an array
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $data): self
|
||||||
|
{
|
||||||
|
$instance = new self();
|
||||||
|
$instance->RedisHook = RedisHook::fromArray(($data['redis_hook'] ?? []));
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
}
|
172
src/RTEX/Objects/Engine/Configuration/RedisHook.php
Normal file
172
src/RTEX/Objects/Engine/Configuration/RedisHook.php
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
|
namespace RTEX\Objects\Engine\Configuration;
|
||||||
|
|
||||||
|
class RedisHook
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* If the hook is enabled or not
|
||||||
|
* (default: false)
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $Enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The host of the redis server
|
||||||
|
* (default: 127.0.0.1)
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $Host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The port of the redis server
|
||||||
|
* (default: 6379)
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $Port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional. Use it only if Redis server requires password (AUTH)
|
||||||
|
* (default: null)
|
||||||
|
*
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
private $Password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public Constructor
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->Enabled = false;
|
||||||
|
$this->Host = '127.0.0.1';
|
||||||
|
$this->Port = 6379;
|
||||||
|
$this->Password = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the hook is enabled or not
|
||||||
|
*
|
||||||
|
* @return false|string
|
||||||
|
*/
|
||||||
|
public function isEnabled(): false|string
|
||||||
|
{
|
||||||
|
return $this->Enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the hook
|
||||||
|
*
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
public function enable(): void
|
||||||
|
{
|
||||||
|
$this->Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the hook
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function disable(): void
|
||||||
|
{
|
||||||
|
$this->Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the host of the redis server
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getHost(): string
|
||||||
|
{
|
||||||
|
return $this->Host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the host of the redis server
|
||||||
|
*
|
||||||
|
* @param string $Host
|
||||||
|
*/
|
||||||
|
public function setHost(string $Host): void
|
||||||
|
{
|
||||||
|
$this->Host = $Host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the port of the redis server
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getPort(): int
|
||||||
|
{
|
||||||
|
return $this->Port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the port of the redis server
|
||||||
|
*
|
||||||
|
* @param int $Port
|
||||||
|
*/
|
||||||
|
public function setPort(int $Port): void
|
||||||
|
{
|
||||||
|
$this->Port = $Port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the password of the redis server
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getPassword(): ?string
|
||||||
|
{
|
||||||
|
return $this->Password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the password of the redis server
|
||||||
|
*
|
||||||
|
* @param string|null $Password
|
||||||
|
*/
|
||||||
|
public function setPassword(?string $Password): void
|
||||||
|
{
|
||||||
|
$this->Password = $Password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array representation of the configuration
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'enabled' => $this->Enabled,
|
||||||
|
'host' => $this->Host,
|
||||||
|
'port' => $this->Port,
|
||||||
|
'password' => $this->Password
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance from an array
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return RedisHook
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $data): self
|
||||||
|
{
|
||||||
|
$instance = new self();
|
||||||
|
$instance->Enabled = ($data['enabled'] ?? false);
|
||||||
|
$instance->Host = ($data['host'] ?? '127.0.0.1');
|
||||||
|
$instance->Port = ($data['port'] ?? 6379);
|
||||||
|
$instance->Password = ($data['password'] ?? null);
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
}
|
211
src/RTEX/Objects/Engine/Configuration/Runtime.php
Normal file
211
src/RTEX/Objects/Engine/Configuration/Runtime.php
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
|
namespace RTEX\Objects\Engine\Configuration;
|
||||||
|
|
||||||
|
class Runtime
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The maximum size a variable value can have (in bytes)
|
||||||
|
* (default: 0) (no limit)
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $MaxVariableSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of variables that can be defined
|
||||||
|
* (default: 0) (no limit)
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $MaxVariables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of instructions that can be executed
|
||||||
|
* (default: 0) (no limit)
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $MaxStackSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of instructions that are not allowed to be executed
|
||||||
|
* if the script attempts to execute one of these instructions
|
||||||
|
* the engine will treat it as a fatal error and stop the execution
|
||||||
|
*
|
||||||
|
* For production environments it is recommended to disable dangerous
|
||||||
|
* instructions such as regex if you aren't supervising the engine
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
private $InstructionBlacklist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of ncc packages to import as a namespace into the engine
|
||||||
|
* (The engine will look for a file named 'rtex.conf' in the package
|
||||||
|
* source directory and register the defined methods for that namespace)
|
||||||
|
*
|
||||||
|
* This will only work for packages designed for the engine and will
|
||||||
|
* not work for regular PHP packages (unless they include support for RTEX)
|
||||||
|
*
|
||||||
|
* Values must be in the format of 'com.example.package' (The same format as
|
||||||
|
* importing packages via the import() function)
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
private $ImportNamespaces;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public Constructor
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->MaxVariableSize = 0;
|
||||||
|
$this->MaxVariables = 0;
|
||||||
|
$this->MaxStackSize = 0;
|
||||||
|
$this->InstructionBlacklist = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getMaxVariableSize(): int
|
||||||
|
{
|
||||||
|
return $this->MaxVariableSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $MaxVariableSize
|
||||||
|
*/
|
||||||
|
public function setMaxVariableSize(int $MaxVariableSize): void
|
||||||
|
{
|
||||||
|
$this->MaxVariableSize = $MaxVariableSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getMaxVariables(): int
|
||||||
|
{
|
||||||
|
return $this->MaxVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $MaxVariables
|
||||||
|
*/
|
||||||
|
public function setMaxVariables(int $MaxVariables): void
|
||||||
|
{
|
||||||
|
$this->MaxVariables = $MaxVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getMaxStackSize(): int
|
||||||
|
{
|
||||||
|
return $this->MaxStackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $MaxStackSize
|
||||||
|
*/
|
||||||
|
public function setMaxStackSize(int $MaxStackSize): void
|
||||||
|
{
|
||||||
|
$this->MaxStackSize = $MaxStackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the instruction blacklist
|
||||||
|
*
|
||||||
|
* @return array|string[]
|
||||||
|
*/
|
||||||
|
public function getInstructionBlacklist(): array
|
||||||
|
{
|
||||||
|
return $this->InstructionBlacklist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the instruction blacklist
|
||||||
|
*
|
||||||
|
* @param array|string[] $InstructionBlacklist
|
||||||
|
*/
|
||||||
|
public function setInstructionBlacklist(array $InstructionBlacklist): void
|
||||||
|
{
|
||||||
|
$this->InstructionBlacklist = $InstructionBlacklist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an instruction to the blacklist
|
||||||
|
*
|
||||||
|
* @param string $instruction
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addInstructionToBlacklist(string $instruction): void
|
||||||
|
{
|
||||||
|
if (in_array($instruction, $this->InstructionBlacklist))
|
||||||
|
return;
|
||||||
|
|
||||||
|
$this->InstructionBlacklist[] = $instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an instruction from the blacklist
|
||||||
|
*
|
||||||
|
* @param string $instruction
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function removeInstructionFromBlacklist(string $instruction): void
|
||||||
|
{
|
||||||
|
if (!in_array($instruction, $this->InstructionBlacklist))
|
||||||
|
return;
|
||||||
|
|
||||||
|
$this->InstructionBlacklist = array_diff($this->InstructionBlacklist, [$instruction]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getImportNamespaces(): array
|
||||||
|
{
|
||||||
|
return $this->ImportNamespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $ImportNamespaces
|
||||||
|
*/
|
||||||
|
public function setImportNamespaces(array $ImportNamespaces): void
|
||||||
|
{
|
||||||
|
$this->ImportNamespaces = $ImportNamespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a namespace to the import list
|
||||||
|
*
|
||||||
|
* @param string $namespace
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addNamespaceToImport(string $namespace): void
|
||||||
|
{
|
||||||
|
if (in_array($namespace, $this->ImportNamespaces))
|
||||||
|
return;
|
||||||
|
|
||||||
|
$this->ImportNamespaces[] = $namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a namespace from the import list
|
||||||
|
*
|
||||||
|
* @param string $namespace
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function removeNamespaceFromImport(string $namespace): void
|
||||||
|
{
|
||||||
|
if (!in_array($namespace, $this->ImportNamespaces))
|
||||||
|
return;
|
||||||
|
|
||||||
|
$this->ImportNamespaces = array_diff($this->ImportNamespaces, [$namespace]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace RTEX\Objects;
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
|
namespace RTEX\Objects\Engine;
|
||||||
|
|
||||||
use LogLib\Log;
|
use LogLib\Log;
|
||||||
|
use RTEX\Exceptions\Runtime\NameException;
|
||||||
|
|
||||||
class Environment
|
class Environment
|
||||||
{
|
{
|
||||||
|
@ -24,10 +27,15 @@
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
* @throws NameException
|
||||||
*/
|
*/
|
||||||
public function getRuntimeVariable(string $name)
|
public function getRuntimeVariable(string $name): mixed
|
||||||
{
|
{
|
||||||
Log::debug('net.nosial.rtex', $name);
|
Log::debug('net.nosial.rtex', $name);
|
||||||
|
|
||||||
|
if (!$this->variableExists($name))
|
||||||
|
throw new NameException("Variable '$name' is not defined");
|
||||||
|
|
||||||
return $this->RuntimeVariables[$name];
|
return $this->RuntimeVariables[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,22 +45,42 @@
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
public function setRuntimeVariable(string $name, $value): void
|
public function setRuntimeVariable(string $name, mixed $value): void
|
||||||
{
|
{
|
||||||
Log::debug('net.nosial.rtex', $name);
|
Log::debug('net.nosial.rtex', $name);
|
||||||
$this->RuntimeVariables[$name] = $value;
|
$this->RuntimeVariables[$name] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function variableExists(string $name): bool
|
||||||
|
{
|
||||||
|
return array_key_exists($name, $this->RuntimeVariables);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the value of the specified variable
|
* Clears the value of the specified variable
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @noinspection PhpUnused
|
||||||
*/
|
*/
|
||||||
public function clearRuntimeVariables(): void
|
public function clearRuntimeVariables(): void
|
||||||
{
|
{
|
||||||
$this->RuntimeVariables = [];
|
$this->RuntimeVariables = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of variables in the environment
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function countRuntimeVariables(): int
|
||||||
|
{
|
||||||
|
return count($this->RuntimeVariables);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array representation of the object
|
* Returns an array representation of the object
|
||||||
*
|
*
|
|
@ -1,10 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
namespace RTEX\Objects\Program;
|
namespace RTEX\Objects\Program;
|
||||||
|
|
||||||
use RTEX\Classes\Utilities;
|
use RTEX\Classes\InstructionBuilder;
|
||||||
use RTEX\Exceptions\Core\MalformedInstructionException;
|
use RTEX\Exceptions\InstructionException;
|
||||||
use RTEX\Exceptions\Core\UnsupportedVariableType;
|
|
||||||
use RTEX\Interfaces\InstructionInterface;
|
use RTEX\Interfaces\InstructionInterface;
|
||||||
|
|
||||||
class Script
|
class Script
|
||||||
|
@ -50,6 +51,7 @@
|
||||||
* Returns the number of instructions in the script
|
* Returns the number of instructions in the script
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
|
* @noinspection PhpUnused
|
||||||
*/
|
*/
|
||||||
public function getInstructionCount(): int
|
public function getInstructionCount(): int
|
||||||
{
|
{
|
||||||
|
@ -73,18 +75,34 @@
|
||||||
* @param int $index
|
* @param int $index
|
||||||
* @param InstructionInterface $instruction
|
* @param InstructionInterface $instruction
|
||||||
* @return void
|
* @return void
|
||||||
|
* @noinspection PhpUnused
|
||||||
*/
|
*/
|
||||||
public function replaceInstruction(int $index, InstructionInterface $instruction): void
|
public function replaceInstruction(int $index, InstructionInterface $instruction): void
|
||||||
{
|
{
|
||||||
$this->Instructions[$index] = $instruction;
|
$this->Instructions[$index] = $instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reorders the instructions in the script
|
||||||
|
*
|
||||||
|
* @param int $index
|
||||||
|
* @param int $newIndex
|
||||||
|
* @return void
|
||||||
|
* @noinspection PhpUnused
|
||||||
|
*/
|
||||||
|
public function reorderInstruction(int $index, int $newIndex): void
|
||||||
|
{
|
||||||
|
$instruction = $this->getInstruction($index);
|
||||||
|
$this->deleteInstruction($index);
|
||||||
|
array_splice($this->Instructions, $newIndex, 0, [$instruction]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all instructions from the script
|
* Clears all instructions from the script
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function clear()
|
public function clear(): void
|
||||||
{
|
{
|
||||||
$this->Instructions = [];
|
$this->Instructions = [];
|
||||||
}
|
}
|
||||||
|
@ -110,15 +128,14 @@
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return Script
|
* @return Script
|
||||||
* @throws MalformedInstructionException
|
* @throws InstructionException
|
||||||
* @throws UnsupportedVariableType
|
|
||||||
*/
|
*/
|
||||||
public static function fromArray(array $data): Script
|
public static function fromArray(array $data): Script
|
||||||
{
|
{
|
||||||
$script = new Script();
|
$script = new Script();
|
||||||
|
|
||||||
foreach ($data as $instruction)
|
foreach ($data as $instruction)
|
||||||
$script->addInstruction(Utilities::constructInstruction($instruction));
|
$script->addInstruction(InstructionBuilder::fromRaw($instruction));
|
||||||
|
|
||||||
return $script;
|
return $script;
|
||||||
}
|
}
|
||||||
|
@ -130,4 +147,18 @@
|
||||||
{
|
{
|
||||||
return $this->Instructions;
|
return $this->Instructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the script (for debugging)
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString(): string
|
||||||
|
{
|
||||||
|
$results = [];
|
||||||
|
foreach ($this->Instructions as $instruction)
|
||||||
|
$results[] = $instruction->__toString();
|
||||||
|
|
||||||
|
return implode("\n", $results);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,69 @@
|
||||||
|
|
||||||
namespace RTEX;
|
namespace RTEX;
|
||||||
|
|
||||||
|
use OptsLib\Parse;
|
||||||
|
|
||||||
class RTEX
|
class RTEX
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The main CLI entry point for the RTEX program
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @noinspection PhpNoReturnAttributeCanBeAddedInspection
|
||||||
|
*/
|
||||||
|
public static function main(): void
|
||||||
|
{
|
||||||
|
$args = Parse::getArguments();
|
||||||
|
|
||||||
|
$file = $args['path'] ?? $args['p'] ?? null;
|
||||||
|
|
||||||
|
if(($args['version'] ?? $args['v'] ?? false))
|
||||||
|
{
|
||||||
|
self::displayVersion(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($file == null || ($args['help'] ?? $args['h'] ?? false))
|
||||||
|
{
|
||||||
|
self::displayHelp(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the version of the RTEX program and optionally exits the program
|
||||||
|
*
|
||||||
|
* @param bool $exit
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function displayVersion(bool $exit=false): void
|
||||||
|
{
|
||||||
|
print('RTEX 0.1.0' . PHP_EOL);
|
||||||
|
|
||||||
|
if($exit)
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the help menu and optionally exits the program
|
||||||
|
*
|
||||||
|
* @param bool $exit
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function displayHelp(bool $exit=false): void
|
||||||
|
{
|
||||||
|
print('RTEX - Runtime Execution' . PHP_EOL);
|
||||||
|
print('Usage: rtex [options] [file]' . PHP_EOL);
|
||||||
|
print('Options:' . PHP_EOL);
|
||||||
|
print(' -h, --help Display this help message' . PHP_EOL);
|
||||||
|
print(' -p, --path Specify the path to the program file' . PHP_EOL);
|
||||||
|
print(' -v, --version Display the version of RTEX' . PHP_EOL);
|
||||||
|
|
||||||
|
if($exit)
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
14
src/RTEX/bin/main
Normal file
14
src/RTEX/bin/main
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require 'ncc';
|
||||||
|
import('net.nosial.rtex', 'latest');
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
\RTEX\RTEX::main();
|
||||||
|
}
|
||||||
|
catch(\Exception $e)
|
||||||
|
{
|
||||||
|
print($e->getMessage() . PHP_EOL);
|
||||||
|
exit(1);
|
||||||
|
}
|
24
tests/pure_runner.php
Normal file
24
tests/pure_runner.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use RTEX\Classes\InstructionBuilder;
|
||||||
|
use RTEX\Engine;
|
||||||
|
use RTEX\Objects\Program;
|
||||||
|
|
||||||
|
require 'ncc';
|
||||||
|
|
||||||
|
import('net.nosial.rtex', 'latest');
|
||||||
|
|
||||||
|
$program = new Program();
|
||||||
|
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::set('foo', 'bar'));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::set('bar', 500));
|
||||||
|
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::set('results',
|
||||||
|
InstructionBuilder::sum(
|
||||||
|
500,
|
||||||
|
InstructionBuilder::get('bar')
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
$engine = new Engine($program);
|
||||||
|
$engine->run();
|
35
tests/script_builder.php
Normal file
35
tests/script_builder.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use RTEX\Classes\InstructionBuilder;
|
||||||
|
use RTEX\Objects\Program;
|
||||||
|
|
||||||
|
require('ncc');
|
||||||
|
import('net.nosial.rtex', 'latest');
|
||||||
|
|
||||||
|
$program = new Program();
|
||||||
|
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::abs(-2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::div(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::floor(2.5));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::mod(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::mul(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::pow(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::round(2.5));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::sqrt(2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::sub(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::sum(2, 2));
|
||||||
|
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::array_set(["test"=>["foo"=>"bar"]], 'test.foo', 'baz'));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::array_get(["test"=>["foo"=>"bar"]], 'test.foo'));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::set('test', 'foo'));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::get('test'));
|
||||||
|
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::eq(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::gt(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::gte(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::lt(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::lte(2, 2));
|
||||||
|
$program->getMain()->addInstruction(InstructionBuilder::neq(2, 2));
|
||||||
|
|
||||||
|
print(json_encode($program->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL);
|
||||||
|
print((string)$program->getMain() . PHP_EOL);
|
72
tests/syntax_parse.php
Normal file
72
tests/syntax_parse.php
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function parseSyntax($syntax) {
|
||||||
|
// Initialize an empty array to hold the parsed instructions
|
||||||
|
$instructions = array();
|
||||||
|
|
||||||
|
// Split the syntax into an array of tokens
|
||||||
|
$tokens = preg_split('/[\s,()]+/', $syntax, -1, PREG_SPLIT_NO_EMPTY);
|
||||||
|
|
||||||
|
// Get the type of instruction
|
||||||
|
$type = array_shift($tokens);
|
||||||
|
$instructions['type'] = $type;
|
||||||
|
|
||||||
|
// Initialize an empty array to hold the instruction parameters
|
||||||
|
$params = array();
|
||||||
|
|
||||||
|
// Loop through the tokens
|
||||||
|
while (!empty($tokens)) {
|
||||||
|
// Get the next token
|
||||||
|
$token = array_shift($tokens);
|
||||||
|
|
||||||
|
// Check if the token is a key
|
||||||
|
if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $token) && !empty($tokens) && $tokens[0] == ':') {
|
||||||
|
// Remove the colon
|
||||||
|
array_shift($tokens);
|
||||||
|
|
||||||
|
// Get the value of the key-value pair
|
||||||
|
$value = array_shift($tokens);
|
||||||
|
|
||||||
|
// Check if the value is a string
|
||||||
|
if (preg_match('/^["\'].*["\']$/', $value)) {
|
||||||
|
// Strip the quotes from the string value
|
||||||
|
$value = substr($value, 1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the key-value pair to the instruction parameters
|
||||||
|
$params[$token] = $value;
|
||||||
|
} else {
|
||||||
|
// The token is not a key-value pair.
|
||||||
|
// Check if the token is a value for the previous key.
|
||||||
|
$last_key = array_key_last($params);
|
||||||
|
if ($last_key !== NULL) {
|
||||||
|
// The token is a value for the previous key.
|
||||||
|
// Add it to the instruction parameters as an array.
|
||||||
|
$params[$last_key] = array($params[$last_key], $token);
|
||||||
|
} else {
|
||||||
|
// The token is not a value for the previous key.
|
||||||
|
// Add it as a separate element to the instruction parameters.
|
||||||
|
$params[] = $token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the instruction parameters to the instructions array
|
||||||
|
$instructions['_'] = $params;
|
||||||
|
|
||||||
|
// Return the parsed instructions
|
||||||
|
return $instructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
$syntax = 'equals(1, 2)';
|
||||||
|
$instructions = parseSyntax($syntax);
|
||||||
|
print_r($instructions);
|
||||||
|
|
||||||
|
$syntax = 'equals(1, get("foo"))';
|
||||||
|
$instructions = parseSyntax($syntax);
|
||||||
|
print_r($instructions);
|
||||||
|
|
||||||
|
$syntax = 'invoke(namespace: "std", method: "print", continue_on_error: false, params: {"value":"Hello World","second_value":{"type":"get","_":"foo"}})';
|
||||||
|
$instructions = parseSyntax($syntax);
|
||||||
|
print_r($instructions);
|
Loading…
Add table
Reference in a new issue