rewrite run.php

This commit is contained in:
Pekka Laiho 2020-12-13 14:33:33 +07:00
parent cf75c6eefd
commit 5c4836d3ff
2 changed files with 102 additions and 32 deletions

124
run.php
View File

@ -5,6 +5,19 @@ if (php_sapi_name() != 'cli') {
exit('Currently only cli usage is supported.'); exit('Currently only cli usage is supported.');
} }
function ml_help()
{
print("Usage:" . PHP_EOL);
print("-d :: Enable debug mode" . PHP_EOL);
print("-e <code> :: Evaluate code" . PHP_EOL);
print("-h :: Show this help" . PHP_EOL);
print("-q :: Skip the init file" . PHP_EOL);
print("-r :: Run the interactive REPL" . PHP_EOL);
print("<file> :: Evaluate file" . PHP_EOL);
print(" :: Read from stdin" . PHP_EOL);
exit(0);
}
function ml_repl($lisp) function ml_repl($lisp)
{ {
// Read history // Read history
@ -48,42 +61,89 @@ function ml_repl($lisp)
} }
} }
// Parse command line arguments
$debugMode = false;
$evalCode = null;
$loadInit = true;
$runRepl = false;
$filename = null;
$lastArg = null;
// Arguments after -- are passed to the script
$dividerFound = false;
$passedArgs = [];
for ($i = 1; $i < $argc; $i++) {
$a = $argv[$i];
if ($dividerFound) {
$passedArgs[] = $a;
} elseif ($a == '--') {
$dividerFound = true;
} elseif ($a == '-d') {
$debugMode = true;
} elseif ($a == '-e') {
} elseif ($a == '-h') {
ml_help(); // exit
} elseif ($a == '-q') {
$loadInit = false;
} elseif ($a == '-r') {
$runRepl = true;
} else {
if ($lastArg == '-e') {
$evalCode = $a;
} else {
$filename = $a;
}
}
$lastArg = $a;
}
// Create the Lisp interpreter // Create the Lisp interpreter
$factory = new MadLisp\LispFactory(); $factory = new MadLisp\LispFactory();
$lisp = $factory->make(); $lisp = $factory->make();
// Load the user's init file if present // Pass command line arguments
$initfile = $_SERVER['HOME'] . DIRECTORY_SEPARATOR . '.madlisp_init'; $lisp->setEnvValue('argc', count($passedArgs));
if (is_readable($initfile)) { $lisp->setEnvValue('argv', new MadLisp\Vector($passedArgs));
$lisp->readEval("(load \"$initfile\")");
}
if ($argc < 2) { // Load the user's init file if present
// Read input from stdin if ($loadInit) {
$input = file_get_contents('php://stdin'); $initfile = $_SERVER['HOME'] . DIRECTORY_SEPARATOR . '.madlisp_init';
$lisp->rep($input, false); if (is_readable($initfile)) {
} elseif ($argv[1] == '-r') { $lisp->readEval("(load \"$initfile\")");
// Run the repl
ml_repl($lisp);
} elseif ($argv[1] == '-e') {
// Evaluate next argument
$lisp->rep($argv[2] ?? '', false);
} elseif ($argv[1] == '-h') {
// Show help
print("Usage:" . PHP_EOL);
print("-e <code> :: Evaluate code" . PHP_EOL);
print("-h :: Show this help" . PHP_EOL);
print("-r :: Run the interactive Repl" . PHP_EOL);
print("<filename> :: Evaluate file" . PHP_EOL);
print("<no arguments> :: Read from stdin" . PHP_EOL);
} else {
// Read file
$file = $argv[1];
if (is_readable($file)) {
$input = "(load \"$file\")";
$lisp->rep($input, false);
} else {
print("Unable to read file: $file\n");
exit(1); // exit with error code
} }
} }
// Enable debug mode if requested
if ($debugMode) {
$lisp->setDebug(true);
}
// Eval code passed via -e
if ($evalCode) {
$lisp->rep($evalCode, false);
}
// Eval file
if ($filename) {
if (is_readable($filename)) {
$lisp->rep("(load \"$filename\")", false);
} else {
print("Unable to read file: $filename" . PHP_EOL);
exit(1);
}
}
// Run REPL
if ($runRepl) {
ml_repl($lisp);
}
// Finally, if we had no other actions, read input from stdin
if (!$evalCode && !$filename) {
$input = file_get_contents('php://stdin');
$lisp->rep($input, false);
}

View File

@ -38,8 +38,18 @@ class Lisp
$this->print($this->readEval($input), $printReadable); $this->print($this->readEval($input), $printReadable);
} }
public function setDebug(bool $value): void
{
$this->eval->setDebug($value);
}
public function setEnv(Env $env): void public function setEnv(Env $env): void
{ {
$this->env = $env; $this->env = $env;
} }
public function setEnvValue(string $key, $value): void
{
$this->env->set($key, $value);
}
} }