Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added the command line interface.

  • Loading branch information...
commit abfe49b63b8288a74ddf2fc0dcd791eb5f4dc742 1 parent f86e688
Hong Minhee dahlia authored
2  Lisphp.php
View
@@ -1,4 +1,6 @@
<?php
+define('LISPHP_VERSION', '0.9.0');
+
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__));
require_once 'Lisphp/Program.php';
7 Lisphp/Scope.php
View
@@ -50,5 +50,12 @@ function offsetUnset($symbol) {
unset($this->superscope[$symbol]);
}
}
+
+ function listSymbols() {
+ $symbols = array_keys($this->values);
+ if (!$this->superscope) return $symbols;
+ $symbols = array_merge($this->superscope->listSymbols(), $symbols);
+ return array_unique($symbols);
+ }
}
14 Lisphp/Test/ScopeTest.php
View
@@ -53,5 +53,19 @@ function testLet() {
$scope->let('abc', 'overridden');
$this->assertEquals('overridden', $scope['abc']);
}
+
+ function testListSymbols() {
+ $this->assertEquals(
+ array(),
+ array_diff(array('abc', 'def', 'ghi'), $this->scope->listSymbols())
+ );
+ $scope = new Lisphp_Scope($this->scope);
+ $scope->let('jkl', 123);
+ $scope->let('abc', 456);
+ $this->assertEquals(
+ array(),
+ array_diff(array('def', 'ghi', 'jkl', 'abc'), $scope->listSymbols())
+ );
+ }
}
101 lis.php
View
@@ -0,0 +1,101 @@
+<?php
+require_once 'Lisphp.php';
+
+define('LISPHP_COLUMN', 80);
+define('LISPHP_REPL_PROMPT', '>>> ');
+
+function Lisphp_usage() {
+ static $commands = array(
+ '-c <code>' => 'Evaluate the code.',
+ '-h' => 'Print this help message.',
+ '-s' => 'Safe sandbox mode.',
+ '-v' => 'Print the Lisphp version number.'
+ );
+ $cmdlen = max(array_map('strlen', array_keys($commands)));
+ $helplen = LISPHP_COLUMN - $cmdlen - 3;
+ $usage = '';
+ foreach ($commands as $cmd => $help) {
+ preg_match_all("/.{0,{$helplen}}/", $help, $lines);
+ $usage .= sprintf(" %-{$cmdlen}s %s", $cmd, join("\n", $lines[0]));
+ }
+ return $usage;
+}
+
+function Lisphp_printParsingError(Lisphp_ParsingException $e) {
+ echo $e->getMessage(), "\n";
+ $lines = explode("\n", $e->code);
+ echo $lines[$e->getLisphpLine() - 1], "\n";
+ echo str_repeat(' ', $e->getLisphpColumn() - 1), "^\n";
+}
+
+$options = getopt('hvsc:');
+if (isset($options['h']) || isset($options['v'])) {
+ echo 'Lisphp ' . LISPHP_VERSION . "\n";
+ if (isset($options['v'])) {
+ echo 'PHP-', PHP_VERSION, "\n", php_uname(), "\n";
+ }
+ if (isset($options['h'])) {
+ echo "Usage: {$_SERVER['argv'][0]} [options] <file>\n\n";
+ echo Lisphp_usage(), "\n";
+ }
+ exit;
+}
+
+$environment = isset($options['s'])
+ ? Lisphp_Environment::sandbox()
+ : Lisphp_Environment::full();
+
+$scope = new Lisphp_Scope($environment);
+$scope['echo'] = new Lisphp_Runtime_PHPFunction(create_function('', '
+ $args = func_get_args();
+ foreach ($args as $arg) echo $arg;
+'));
+
+class Lisphp_EnterREPL extends Exception {}
+
+try {
+ $file = end($_SERVER['argv']);
+ if (isset($options['c'])) {
+ $program = new Lisphp_Program($options['c']);
+ } else if (count($_SERVER['argv']) > 1 && $file != '-s') {
+ $program = Lisphp_Program::load($file);
+ } else {
+ throw new Lisphp_EnterREPL;
+ }
+ $program->execute($scope);
+} catch (Lisphp_ParsingException $e) {
+ Lisphp_printParsingError($e);
+} catch (Lisphp_EnterREPL $e) {
+ $scope['exit'] = new Lisphp_Runtime_PHPFunction(
+ create_function('$status = null', '
+ if (is_null($status)) die;
+ else die($status);
+ ')
+ );
+ readline_completion_function(create_function('$line', '
+ global $scope;
+ $symbols = array();
+ foreach ($scope->listSymbols() as $symbol) {
+ if ($line != "" && strpos($symbol, $line) !== 0) continue;
+ $symbols[] = $symbol;
+ }
+ if (!isset($symbols[0])) {
+ $symbols[] = $line;
+ }
+ return $symbols;
+ '));
+ while (true) {
+ $code = readline(LISPHP_REPL_PROMPT);
+ try {
+ $form = Lisphp_Parser::parseForm($code, $_);
+ var_export($form->evaluate($scope));
+ echo "\n";
+ } catch (Lisphp_ParsingException $e) {
+ Lisphp_printParsingError($e);
+ } catch (Exception $e) {
+ echo $e->getMessage();
+ }
+ readline_add_history($code);
+ }
+}
+
Please sign in to comment.
Something went wrong with that request. Please try again.