Skip to content

Architecture Overview

Tejas Manohar edited this page Feb 28, 2015 · 1 revision

This section of the README only applies to those curious enough to read the code. Boris is quite different to other PHP REPLs, because it deals with fatal errors (not Exceptions, fatal errors) in a special way.

Boris will only work on POSIX systems (Linux and Mac OS). This is primarily because it depends on the ability to fork, but also because it plays with signals a lot too.

Boris is made up of two parts:

  1. A REPL worker process, which receives expressions to evaluate and print
  2. A readline client, which simply takes your input, sends it to the worker and then loops

If all errors in PHP were exceptions, building a REPL would be simple. This is not the case, however. Some PHP errors are truly fatal and cannot be caught. In order to prevent such fatal errors from killing the REPL, the worker looks something like this:

for(;;) {
  $input = accept_some_input();
  if (fork_child()) {
    wait_for_child();
  } else { // inside child
    var_dump(eval($input));
    kill_parent();
  }
}

The child is forked with all current variables and resources. It evaluates the input then kills the parent, then the loop continues inside the child, waiting for the next input.

While the child is evaluating the input, the parent waits. The parent is expecting the worst—that the child will die abnormally—at which point the parent continues waiting for input and does not terminate. The state remains unchanged.

After each expression is evaluated, the worker reports back to the main process with a status code of 0 (keep running) or 1 (terminate).

The main process (readline) of Boris is much more straightforward. It takes your input, performs a (very) shallow parse on it, in order to decide if it needs to wait for further input, or evaluate the input (one statement at a time) it has received. If the worker reports back with a status code of 1, the process terminates, otherwise the next iteration of the loop is entered.

Clone this wiki locally