The whole picture:

Activity diagram of the interpreter: value

  • entry: a pair of lists whose first list is a set, and also the two lists must be of equal length.
  • table/environment: a list of entries.
  • application: a list of expression whose car position contains an expression whose value is a function.
Scheme PHP [Source Code]
new-entry
use function build as new_entry;
lookup-in-entry
function lookup_in_entry
($name, $entry, $entry_f) 
{return 
    lookup_in_entry_help($name,
                         first($entry), 
                         second($entry), 
                         $entry_f);
}
lookup-in-entry-help
function lookup_in_entry_help
($name, $names, $values, $entry_f) 
{return
    is_nulll($names) ? $entry_f($name)
    : (is_eq(car($names), $name) ? car($values)
      : lookup_in_entry_help($name,
                             cdr($names), 
                             cdr($values),
                             $entry_f));
}
extend-table
use function cons as extend_table;
lookup-in-table
function lookup_in_table
($name, $table, $table_f)
{return
    is_nulll($table) ? $table_f($name)
    : lookup_in_entry($name, car($table), 
                      function ($name) use ($table, $table_f)
                      {return 
                          lookup_in_table($name, 
                                          cdr($table), 
                                          $table_f);
                      });
}
atom-to-function
function atom_to_action
($e)
{return
    is_number($e)
    ||  is_eq($e, '#t')
    ||  is_eq($e, '#f')
    ||  is_eq($e, 'cons')
    ||  is_eq($e, 'car')
    ||  is_eq($e, 'cdr')
    ||  is_eq($e, 'null?')
    ||  is_eq($e, 'eq?')
    ||  is_eq($e, 'atom?')
    ||  is_eq($e, 'zero?')
    ||  is_eq($e, 'add1?')
    ||  is_eq($e, 'sub1?')
    ||  is_eq($e, 'number?') ? 
      '_const'
    : '_identifier';
}
list-to-action
function list_to_aciton 
($e)
{return
    is_atom(car($e)) ? 
        is_eq(car($e), 'quote') ? '_quote'
        : (is_eq(car($e), 'lambda') ? '_lambda' 
          : (is_eq(car($e), 'cond') ? '_cond'
            : '_application'))
    : '_application';
}
expression-to-action
function expression_to_action
($e)
{return
    is_atom($e) ? atom_to_action($e)
    : list_to_aciton($e);
}
value
function value
($e)
{return
    meaning($e, []);
}
meaning
function meaning
($e, $table)
{return
    expression_to_action($e)($e, $table);
}
*const
function _const
($e, $table)
{return
    is_number($e) ? $e
    : (is_eq($e, '#t') ? TRUE
      : (is_eq($e, '#f') ? FALSE
        : build('primitive', $e)));
}
*quote
function _quote
($e, $table)
{return
    text_of($e);
}
text-of
use function second as text_of;
*identifier
function _identifier
($e, $table) 
{return
    lookup_in_table($e, $table, 'initial_table');
}
initial-table
function initial_table
($name)
{return
    car([]);
}
*lambda
function _lambda
($e, $table)
{return
    build('non-primitive', cons($table, cdr($e)));
}
table-of
use function first as table_of;
formals-of
use function second as formals_of;
body-of
use function third as body_of;
evcon
function evcon
($lines, $table)
{return
    is_else(question_of(car($lines))) ? 
      meaning(answer_of(car($lines)), $table)
    : (meaning(question_of(car($lines)), $table) ?
        meaning(answer_of(car($lines)), $table)
      : evcon(cdr($lines), $table));
}
else?
function is_else
($x)
{return
    is_atom($x) && is_eq($x, 'else');
}
question-of
use function first as question_of;
answer-of
use function second as answer_of;
*cond
function _cond
($e, $table)
{return
    evcon(cond_lines_of($e), $table);
}
cond-line-of
use function cdr as cond_lines_of;
*application
function _application
($e, $table)
{return
    apply(meaning(function_of($e), $table),
          evlis(arguments_of($e), $table));
}
evlis
function evlis
($args, $table)
{return
    is_nulll($args) ? []
    : cons(meaning(car($args), $table),
           evlis(cdr($args), $table));
}
function-of
use function car as function_of;
arguments-of
use function cdr as arguments_of;
primitive?
function is_primitive
($l)
{return
    is_eq(first($l), 'primitive');
}
non-primitive?
function is_non_primitive
($l)
{return
    is_eq(first($l), 'non-primitive');
}
apply
function apply
($fun, $vals)
{return
    is_primitive($fun) ?
      apply_primitive(second($fun), $vals)
    : (is_non_primitive($fun) ?
        apply_closure(second($fun), $vals)
      : $fun);  // no answer
}
apply-primitive
function apply_primitive
($name, $vals)
{return
    is_eq($name, 'car') ? car(first($vals))
    : (is_eq($name, 'cdr') ? cdr(first($vals))
    : (is_eq($name, 'cons') ? cons(first($vals), second($vals))
    : (is_eq($name, 'null?') ? is_nulll(first($vals))
    : (is_eq($name, 'atom?') ? _is_atom(first($vals))
    : (is_eq($name, 'eq?') ? is_eq(first($vals), second($vals))
    : (is_eq($name, 'zero?') ? is_zero(first($vals))
    : (is_eq($name, 'add1') ? add1(first($vals))
    : (is_eq($name, 'sub1') ? sub1(first($vals))
    : (is_eq($name, 'number?') ? is_number(first($vals))
    : $name))))))))); // no answer
}
:atom?
function _is_atom
($s)
{return
    is_atom($s) ? TRUE
    : (is_nulll($s) ? FALSE
      : (is_eq(car($s), 'primitive') ? TRUE
        : (is_eq(car($s), 'non-primitive') ? TRUE
          : FALSE)));
}
apply-closure
function apply_closure
($closure, $vals)
{return
    meaning(body_of($closure),
            extend_table(new_entry(formals_of($closure),
                                   $vals),
                         table_of($closure)));
}