forked from dahlia/lisphp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlis.php
More file actions
executable file
·120 lines (111 loc) · 3.74 KB
/
lis.php
File metadata and controls
executable file
·120 lines (111 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
require_once 'Lisphp.php';
define('LISPHP_COLUMN', 80);
define('LISPHP_REPL_PROMPT', '>>> ');
define('LISPHP_REPL_VALUE_PROMPT', '==> ');
define('LISPHP_REPL_EXCEPTION_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);
')
);
if (extension_loaded('readline')) {
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;
'));
$readline = 'readline';
$add_history = 'readline_add_history';
$exit = false;
} else {
$readline = create_function('$prompt', '
echo $prompt;
return fread(STDIN, 8192);
');
$add_history = create_function('', '');
$exit = '';
}
while (true) {
$code = $readline(LISPHP_REPL_PROMPT);
if ($code === $exit) die("\n");
else if (trim($code) == '') continue;
try {
$form = Lisphp_Parser::parseForm($code, $_);
echo LISPHP_REPL_VALUE_PROMPT;
var_export($form->evaluate($scope));
echo "\n";
} catch (Lisphp_ParsingException $e) {
Lisphp_printParsingError($e);
} catch (Exception $e) {
echo LISPHP_REPL_EXCEPTION_PROMPT, $e->getMessage(), "\n",
preg_replace('/^|\n/', '\\0 ', $e->getTraceAsString()),
"\n";
}
$add_history($code);
}
}