:: 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(" :: Evaluate file" . PHP_EOL); print(" :: Read from stdin" . PHP_EOL); exit(0); } function ml_repl($lisp) { // Read history $historyFile = $_SERVER['HOME'] . DIRECTORY_SEPARATOR . '.madlisp_history'; if (is_readable($historyFile)) { readline_read_history($historyFile); } while (true) { $input = readline('> '); try { $lisp->rep($input, true); } catch (MadLisp\MadLispUserException $ex) { print('error: '); $lisp->print($ex->getValue(), true); } catch (MadLisp\MadLispException $ex) { print('error: ' . $ex->getMessage()); } catch (TypeError $ex) { // Clean up the error message a little if (preg_match('/must be an instance of ([^,]+), (.+) given/', $ex->getMessage(), $matches)) { $message = 'expected ' . $matches[1] . ', ' . $matches[2] . ' given'; } elseif (preg_match('/must be of the type ([^,]+), (.+) given/', $ex->getMessage(), $matches)) { $message = 'expected ' . $matches[1] . ', ' . $matches[2] . ' given'; } else { $message = $ex->getMessage(); } print('error: invalid argument type: ' . $message); } catch (Throwable $ex) { // Catch all other exceptions print('error: ' . $ex->getMessage()); } print(PHP_EOL); if ($input) { readline_add_history($input); readline_write_history($historyFile); } } } // 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 $factory = new MadLisp\LispFactory(); $lisp = $factory->make(); // Pass command line arguments $lisp->setEnvValue('argc', count($passedArgs)); $lisp->setEnvValue('argv', new MadLisp\Vector($passedArgs)); // Load the user's init file if present if ($loadInit) { $initfile = $_SERVER['HOME'] . DIRECTORY_SEPARATOR . '.madlisp_init'; if (is_readable($initfile)) { $lisp->readEval("(load \"$initfile\")"); } } // 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); }