Skip to content

Commit

Permalink
Add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nibra committed Mar 20, 2023
1 parent 0717ccc commit c2fb7d3
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.phpunit.cache/
/vendor/
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Read-Eval-Print Loop (REPL) for PHP

GreenCape REPL is a simple Read-Eval-Print Loop (REPL) written in PHP.
It can be combined with arbitrary evaluators for the Eval step.

## Installation

```bash
composer require greencape/repl
```

## Usage

Create an Evaluator implementing the `GreenCape\REPL\EvaluatorInterface` and pass it to the REPL:

```php
use GreenCape\REPL\EvaluatorInterface;
use GreenCape\REPL\ReadEvalPrintLoop;

class MyEvaluator implements EvaluatorInterface
{
public function init(): void {}
public function exit(): void {}
public function eval(string $input): string
{
// Handle the input and return the result
return $result;
}
}

$evaluator = new MyEvaluator();
$repl = new ReadEvalPrintLoop($evaluator);

$repl->run();
```

With `init()` and `exit()` you can implement a setup and teardown for the REPL.

The loop will read your input after a '> ' prompt' and send it to the `eval()` method of the Evaluator.
The result will be printed to the console.
You can enter multi line input by ending each line with a backslash.
Continuation lines are indicated by a '>> ' prompt.

To terminate the loop, enter `exit`.
24 changes: 24 additions & 0 deletions src/EvaluatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,33 @@

namespace GreenCape\REPL;

/**
* Interface EvaluatorInterface
*
* @package GreenCape\REPL
*/
interface EvaluatorInterface
{
/**
* Set up the evaluator
*
* @return void
*/
public function init(): void;

/**
* Evaluate the query
*
* @param string $query
*
* @return string
*/
public function eval(string $query): string;

/**
* Tear down the evaluator
*
* @return void
*/
public function exit(): void;
}
28 changes: 25 additions & 3 deletions src/ReadEvalPrintLoop.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@

use Throwable;

/**
* Class ReadEvalPrintLoop
*
* @package GreenCape\REPL
*/
final class ReadEvalPrintLoop
{
/**
* @param \GreenCape\REPL\EvaluatorInterface $evaluator
* @param resource $input
* ReadEvalPrintLoop constructor.
*
* @param \GreenCape\REPL\EvaluatorInterface $evaluator The evaluator to use
* @param resource $input An optional input stream, defaults to STDIN
*/
public function __construct(
private readonly EvaluatorInterface $evaluator,
Expand All @@ -21,6 +28,12 @@ public function __construct(
rewind($this->input);
}

/**
* Run the loop
*
* The loop reads a query from the input stream, evaluates it and prints the result.
* The loop is terminated by the query 'exit'.
*/
public function run(): void
{
$this->evaluator->init();
Expand Down Expand Up @@ -53,7 +66,9 @@ public function run(): void
}

/**
* @param \Throwable $e
* Print an exception
*
* @param \Throwable $e The exception to print
*
* @return void
*/
Expand All @@ -68,6 +83,13 @@ private function printException(Throwable $e): void
} while ($e);
}

/**
* Read a line from the input stream
*
* @param string $prompt An optional prompt
*
* @return string
*/
private function readline(string $prompt = ''): string
{
echo $prompt;
Expand Down
25 changes: 24 additions & 1 deletion tests/Evaluator/ExceptionIssuer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,41 @@
namespace GreenCape\REPL\Test\Evaluator;

use GreenCape\REPL\EvaluatorInterface;
use RuntimeException;

/**
* Class ExceptionIssuer
*
* @package GreenCape\REPL\Test
*/
final class ExceptionIssuer implements EvaluatorInterface
{
/**
* Set up the evaluator
*
* @return void
*/
public function init(): void
{
}

/**
* Evaluate the query
*
* @param string $query
*
* @return string
*/
public function eval(string $query): string
{
throw new \RuntimeException($query, 0, new \RuntimeException('Previous exception'));
throw new RuntimeException($query, 0, new RuntimeException('Previous exception'));
}

/**
* Tear down the evaluator
*
* @return void
*/
public function exit(): void
{
}
Expand Down
22 changes: 22 additions & 0 deletions tests/Evaluator/Mocker.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,44 @@

use GreenCape\REPL\EvaluatorInterface;

/**
* Class Mocker
*
* @package GreenCape\REPL\Test
*/
final class Mocker implements EvaluatorInterface
{
public array $history = [];

/**
* Set up the evaluator
*
* @return void
*/
public function init(): void
{
$this->history[] = 'init';
}

/**
* Evaluate the query
*
* @param string $query
*
* @return string
*/
public function eval(string $query): string
{
$this->history[] = $query;

return "Query: $query";
}

/**
* Tear down the evaluator
*
* @return void
*/
public function exit(): void
{
$this->history[] = 'exit';
Expand Down
11 changes: 8 additions & 3 deletions tests/LoopTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
use GreenCape\REPL\Test\Evaluator\Mocker;
use PHPUnit\Framework\TestCase;

/**
* Class LoopTest
*
* @package GreenCape\REPL\Test
*/
class LoopTest extends TestCase
{
/**
* @testdox init() and exit() are called on the evaluator, query is evaluated
*
* @covers \GreenCape\REPL\ReadEvalPrintLoop
* @covers \GreenCape\REPL\ReadEvalPrintLoop
* @return void
*/
public function testLoopSingleLine(): void
Expand Down Expand Up @@ -46,7 +51,7 @@ public function testLoopSingleLine(): void
/**
* @testdox Lines ending with backslash signal continuation
*
* @covers \GreenCape\REPL\ReadEvalPrintLoop
* @covers \GreenCape\REPL\ReadEvalPrintLoop
* @return void
*/
public function testLoopMultiLine(): void
Expand Down Expand Up @@ -78,7 +83,7 @@ public function testLoopMultiLine(): void
/**
* @testdox Exceptions are caught and printed
*
* @covers \GreenCape\REPL\ReadEvalPrintLoop
* @covers \GreenCape\REPL\ReadEvalPrintLoop
* @return void
*/
public function testExceptionHandling(): void
Expand Down

0 comments on commit c2fb7d3

Please sign in to comment.