From 7e5207c45adb70017793a87635e59e445684e6be Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 23 Dec 2022 00:10:02 -0500 Subject: [PATCH] Added base files, with the basic ability to add/remove variables from the Runtime. --- Makefile | 14 ++ instructions/get_var.json | 6 + instructions/set_var.json | 7 + src/RTEX/Abstracts/InstructionType.php | 10 ++ src/RTEX/Abstracts/VariableTypes.php | 30 ++++ src/RTEX/Classes/InstructionBuilder.php | 43 ++++++ src/RTEX/Classes/Utilities.php | 81 +++++++++++ src/RTEX/Classes/Validate.php | 31 ++++ src/RTEX/Engine.php | 89 ++++++++++++ .../Core/MalformedInstructionException.php | 16 +++ .../Core/UnsupportedInstructionException.php | 16 +++ .../Core/UnsupportedVariableType.php | 13 ++ src/RTEX/Interfaces/InstructionInterface.php | 40 ++++++ src/RTEX/Objects/Environment.php | 81 +++++++++++ src/RTEX/Objects/Program.php | 79 +++++++++++ .../Program/Instructions/GetVariable.php | 94 +++++++++++++ .../Program/Instructions/SetVariable.php | 116 +++++++++++++++ src/RTEX/Objects/Program/Script.php | 133 ++++++++++++++++++ src/RTEX/RTEX.php | 7 + 19 files changed, 906 insertions(+) create mode 100644 Makefile create mode 100644 instructions/get_var.json create mode 100644 instructions/set_var.json create mode 100644 src/RTEX/Abstracts/InstructionType.php create mode 100644 src/RTEX/Abstracts/VariableTypes.php create mode 100644 src/RTEX/Classes/InstructionBuilder.php create mode 100644 src/RTEX/Classes/Utilities.php create mode 100644 src/RTEX/Classes/Validate.php create mode 100644 src/RTEX/Engine.php create mode 100644 src/RTEX/Exceptions/Core/MalformedInstructionException.php create mode 100644 src/RTEX/Exceptions/Core/UnsupportedInstructionException.php create mode 100644 src/RTEX/Exceptions/Core/UnsupportedVariableType.php create mode 100644 src/RTEX/Interfaces/InstructionInterface.php create mode 100644 src/RTEX/Objects/Environment.php create mode 100644 src/RTEX/Objects/Program.php create mode 100644 src/RTEX/Objects/Program/Instructions/GetVariable.php create mode 100644 src/RTEX/Objects/Program/Instructions/SetVariable.php create mode 100644 src/RTEX/Objects/Program/Script.php create mode 100644 src/RTEX/RTEX.php diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..65e1b31 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +debug: + ncc build --config="debug" + +release: + ncc build --config="release" + +install: + ncc package install --package="build/release/net.nosial.rtex.ncc" --skip-dependencies --reinstall -y + +install-debug: + ncc package install --package="build/debug/net.nosial.rtex.ncc" --skip-dependencies --reinstall -y + +uninstall: + ncc package uninstall -y --package="net.nosial.rtex" \ No newline at end of file diff --git a/instructions/get_var.json b/instructions/get_var.json new file mode 100644 index 0000000..928e166 --- /dev/null +++ b/instructions/get_var.json @@ -0,0 +1,6 @@ +{ + "type": "get", + "_": { + "variable": "foo" + } +} \ No newline at end of file diff --git a/instructions/set_var.json b/instructions/set_var.json new file mode 100644 index 0000000..83b586e --- /dev/null +++ b/instructions/set_var.json @@ -0,0 +1,7 @@ +{ + "type": "set", + "_": { + "variable": "foo", + "value": "bar" + } +} \ No newline at end of file diff --git a/src/RTEX/Abstracts/InstructionType.php b/src/RTEX/Abstracts/InstructionType.php new file mode 100644 index 0000000..c523ab5 --- /dev/null +++ b/src/RTEX/Abstracts/InstructionType.php @@ -0,0 +1,10 @@ +setVariable($name); + + return $instruction; + } + + /** + * Constructs a new set variable instruction + * + * @param $name + * @param $value + * @return InstructionInterface + * @throws UnsupportedVariableType + */ + public static function setVariable($name, $value): InstructionInterface + { + $instruction = new SetVariable(); + $instruction->setVariable($name); + $instruction->setValue($value); + + return $instruction; + } + } \ No newline at end of file diff --git a/src/RTEX/Classes/Utilities.php b/src/RTEX/Classes/Utilities.php new file mode 100644 index 0000000..8f511ac --- /dev/null +++ b/src/RTEX/Classes/Utilities.php @@ -0,0 +1,81 @@ + $input->toArray(), + default => $input, + }; + } + + /** + * Constructs an instruction from an array representation + * + * @param array $array + * @return InstructionInterface + * @throws MalformedInstructionException + * @throws UnsupportedVariableType + */ + public static function constructInstruction(array $array): InstructionInterface + { + if(!isset($array['type'])) + throw new MalformedInstructionException(sprintf('Instruction type not specified')); + if(!isset($array['_'])) + throw new MalformedInstructionException(sprintf('Instruction data not specified')); + + switch($array['type']) + { + case InstructionType::GetVariable: + return GetVariable::fromArray($array['_']); + case InstructionType::SetVariable: + return SetVariable::fromArray($array['_']); + default: + throw new MalformedInstructionException(sprintf('Instruction type "%s" not supported', $array['type'])); + } + } + } \ No newline at end of file diff --git a/src/RTEX/Classes/Validate.php b/src/RTEX/Classes/Validate.php new file mode 100644 index 0000000..606c358 --- /dev/null +++ b/src/RTEX/Classes/Validate.php @@ -0,0 +1,31 @@ +Program = $program; + $this->Environment = new Environment(); + } + + /** + * Executes the program by running the main script of the program + * + * @return void + * @throws UnsupportedVariableType + */ + public function run() + { + foreach($this->Program->getMain()->getInstructions() as $instruction) + { + $this->eval($instruction); + } + } + + /** + * Evaluates the variable or instruction and returns the result + * + * @param $input + * @return mixed + * @throws UnsupportedVariableType + * @noinspection PhpMissingReturnTypeInspection + */ + public function eval($input) + { + switch(Utilities::determineType($input)) + { + case VariableTypes::Instruction: + /** @var InstructionInterface $input */ + return $input->eval($this); + + default: + return $input; + } + } + + /** + * @return Program + */ + public function getProgram(): Program + { + return $this->Program; + } + + /** + * @param Program $Program + */ + public function setProgram(Program $Program): void + { + $this->Program = $Program; + } + + /** + * @return Environment + */ + public function getEnvironment(): Environment + { + return $this->Environment; + } + } \ No newline at end of file diff --git a/src/RTEX/Exceptions/Core/MalformedInstructionException.php b/src/RTEX/Exceptions/Core/MalformedInstructionException.php new file mode 100644 index 0000000..361b92f --- /dev/null +++ b/src/RTEX/Exceptions/Core/MalformedInstructionException.php @@ -0,0 +1,16 @@ +RuntimeVariables = []; + } + + /** + * Returns the value of the specified variable + * + * @param string $name + * @return mixed + */ + public function getRuntimeVariable(string $name) + { + Log::debug('net.nosial.rtex', $name); + return $this->RuntimeVariables[$name]; + } + + /** + * Sets the value of the specified variable + * + * @param string $name + * @param mixed $value + */ + public function setRuntimeVariable(string $name, $value): void + { + Log::debug('net.nosial.rtex', $name); + $this->RuntimeVariables[$name] = $value; + } + + /** + * Clears the value of the specified variable + * + * @return void + */ + public function clearRuntimeVariables(): void + { + $this->RuntimeVariables = []; + } + + /** + * Returns an array representation of the object + * + * @return array + */ + public function toArray(): array + { + return [ + 'variables' => $this->RuntimeVariables + ]; + } + + /** + * Constructs a new environment from an array representation + * + * @param array $data + * @return Environment + */ + public static function fromArray(array $data): Environment + { + $environment = new Environment(); + $environment->RuntimeVariables = $data['variables']; + + return $environment; + } + } \ No newline at end of file diff --git a/src/RTEX/Objects/Program.php b/src/RTEX/Objects/Program.php new file mode 100644 index 0000000..b2e8537 --- /dev/null +++ b/src/RTEX/Objects/Program.php @@ -0,0 +1,79 @@ +Main = new Script(); + } + + /** + * Returns an array representation of the object + * + * @return array + */ + public function toArray(): array + { + return [ + 'main' => $this->Main->toArray() + ]; + } + + /** + * Constructs a new program from an array representation + * + * @param array $data + * @return Program + */ + public static function fromArray(array $data): Program + { + $program = new Program(); + $program->Main = Script::fromArray($data['main']); + + return $program; + } + + /** + * @return Script + */ + public function getMain(): Script + { + return $this->Main; + } + + /** + * Saves the program to a file + * + * @param string $path + * @return void + */ + public function save(string $path): void + { + file_put_contents($path, json_encode($this->toArray())); + } + + /** + * Loads a program from a file + * + * @param string $path + * @return Program + */ + public static function load(string $path): Program + { + return self::fromArray(json_decode(file_get_contents($path), true)); + } + } \ No newline at end of file diff --git a/src/RTEX/Objects/Program/Instructions/GetVariable.php b/src/RTEX/Objects/Program/Instructions/GetVariable.php new file mode 100644 index 0000000..e7b3e0c --- /dev/null +++ b/src/RTEX/Objects/Program/Instructions/GetVariable.php @@ -0,0 +1,94 @@ + $this->getType(), + '_' => [ + 'variable' => Utilities::toArray($this->Variable) + ] + ]; + } + + /** + * Returns + * + * @return bool|float|int|InstructionInterface|string|null + * @noinspection PhpMissingReturnTypeInspection + */ + public function getVariable() + { + return $this->Variable; + } + + /** + * @param bool|float|int|InstructionInterface|string|null $variable + * @throws UnsupportedVariableType + */ + public function setVariable($variable): void + { + switch(Utilities::determineType($variable)) + { + + + default: + $this->Variable = $variable; + } + } + + /** + * Constructs a new GetVariable instruction from an array representation + * + * @throws UnsupportedVariableType + */ + public static function fromArray(array $data): InstructionInterface + { + $instruction = new GetVariable(); + $instruction->setVariable($data['variable'] ?? null); + return $instruction; + } + + /** + * @inheritDoc + */ + public function eval(Engine $engine) + { + return $engine->getEnvironment()->getRuntimeVariable( + $engine->eval($this->Variable) + ); + } + } \ No newline at end of file diff --git a/src/RTEX/Objects/Program/Instructions/SetVariable.php b/src/RTEX/Objects/Program/Instructions/SetVariable.php new file mode 100644 index 0000000..091350b --- /dev/null +++ b/src/RTEX/Objects/Program/Instructions/SetVariable.php @@ -0,0 +1,116 @@ + $this->getType(), + '_' => [ + 'variable' => Utilities::toArray($this->Variable), + 'value' => Utilities::toArray($this->Value) + ] + ]; + } + + /** + * @inheritDoc + */ + public static function fromArray(array $data): InstructionInterface + { + $instruction = new self(); + $instruction->setVariable($data['variable'] ?? null); + $instruction->setValue($data['value'] ?? null); + + return $instruction; + } + + /** + * @return bool|float|int|InstructionInterface|InstructionInterface[]|string|null + */ + public function getVariable() + { + return $this->Variable; + } + + /** + * @param bool|float|int|InstructionInterface|InstructionInterface|string|null $variable + * @throws UnsupportedVariableType + * @noinspection PhpMissingParamTypeInspection + */ + public function setVariable($variable): void + { + Utilities::determineType($variable); + $this->Variable = $variable; + } + + /** + * @return bool|float|int|InstructionInterface|InstructionInterface[]|string|null + */ + public function getValue() + { + return $this->Value; + } + + /** + * @param bool|float|int|InstructionInterface|InstructionInterface|string|null $value + * @throws UnsupportedVariableType + * @noinspection PhpMissingParamTypeInspection + */ + public function setValue($value): void + { + Utilities::determineType($value); + $this->Value = $value; + } + + /** + * @param Engine $engine + * @return mixed|void + * @throws UnsupportedVariableType + */ + public function eval(Engine $engine) + { + $engine->getEnvironment()->setRuntimeVariable( + $engine->eval($this->Variable), + $engine->eval($this->Value) + ); + } + } \ No newline at end of file diff --git a/src/RTEX/Objects/Program/Script.php b/src/RTEX/Objects/Program/Script.php new file mode 100644 index 0000000..1b185fa --- /dev/null +++ b/src/RTEX/Objects/Program/Script.php @@ -0,0 +1,133 @@ +Instructions = []; + } + + /** + * Adds an instruction to the script and returns the index of the instruction + * + * @param InstructionInterface $instruction + * @return int + */ + public function addInstruction(InstructionInterface $instruction): int + { + return array_push($this->Instructions, $instruction); + } + + /** + * Returns the instruction at the specified index + * + * @param int $index + * @return InstructionInterface + */ + public function getInstruction(int $index): InstructionInterface + { + return $this->Instructions[$index]; + } + + /** + * Returns the number of instructions in the script + * + * @return int + */ + public function getInstructionCount(): int + { + return count($this->Instructions); + } + + /** + * Deletes the instruction at the specified index + * + * @param int $index + * @return void + */ + public function deleteInstruction(int $index): void + { + unset($this->Instructions[$index]); + } + + /** + * Replaces the instruction at the specified index + * + * @param int $index + * @param InstructionInterface $instruction + * @return void + */ + public function replaceInstruction(int $index, InstructionInterface $instruction): void + { + $this->Instructions[$index] = $instruction; + } + + /** + * Clears all instructions from the script + * + * @return void + */ + public function clear() + { + $this->Instructions = []; + } + + /** + * Returns an array representation of the object + * + * @return array + */ + public function toArray(): array + { + $instructions = []; + foreach ($this->Instructions as $instruction) + { + $instructions[] = $instruction->toArray(); + } + + return $instructions; + } + + /** + * Constructs a script from an array representation + * + * @param array $data + * @return Script + * @throws MalformedInstructionException + * @throws UnsupportedVariableType + */ + public static function fromArray(array $data): Script + { + $script = new Script(); + + foreach ($data as $instruction) + $script->addInstruction(Utilities::constructInstruction($instruction)); + + return $script; + } + + /** + * @return array|InstructionInterface[] + */ + public function getInstructions(): array + { + return $this->Instructions; + } + } \ No newline at end of file diff --git a/src/RTEX/RTEX.php b/src/RTEX/RTEX.php new file mode 100644 index 0000000..5c63be0 --- /dev/null +++ b/src/RTEX/RTEX.php @@ -0,0 +1,7 @@ +