mirror of
https://github.com/peklaiho/madlisp.git
synced 2024-11-26 07:04:27 +00:00
handle special characters correctly in printing
This commit is contained in:
parent
ad70c6dbd0
commit
427327003d
@ -135,7 +135,7 @@ Name | Example | Example result | Description
|
||||
----- | ------- | -------------- | -----------
|
||||
doc | `(doc +)` | `"Return the sum of all arguments."` | Show description of a built-in function.
|
||||
read | `(read "(+ 1 2 3)")` | `(+ 1 2 3)` | Read a string as code and return the expression.
|
||||
print | `(print "hello world")` | `"hello world"null` | Print expression on the screen. Print returns null (which is shown due to the extra print in repl).
|
||||
print | `(print "hello world")` | `"hello world"null` | Print expression on the screen. Print returns null (which is shown due to the extra print in repl). Give optional second argument as `true` to show strings in readable format.
|
||||
error | `(error "invalid value")` | `error: invalid value` | Throw an exception with message as argument.
|
||||
|
||||
### Collection functions
|
||||
|
6
run.php
6
run.php
@ -17,7 +17,7 @@ function ml_repl($lisp, $env)
|
||||
$input = readline('> ');
|
||||
|
||||
try {
|
||||
$lisp->rep($input, $env);
|
||||
$lisp->rep($input, $env, true);
|
||||
|
||||
if ($input) {
|
||||
readline_add_history($input);
|
||||
@ -42,10 +42,10 @@ function ml_run()
|
||||
list($lisp, $env) = ml_get_lisp($debug);
|
||||
|
||||
if (array_key_exists('e', $args)) {
|
||||
$lisp->rep($args['e'], $env);
|
||||
$lisp->rep($args['e'], $env, false);
|
||||
} elseif (array_key_exists('f', $args)) {
|
||||
$input = "(load \"{$args['f']}\")";
|
||||
$lisp->rep($input, $env);
|
||||
$lisp->rep($input, $env, false);
|
||||
} elseif (array_key_exists('r', $args)) {
|
||||
ml_repl($lisp, $env);
|
||||
} else {
|
||||
|
10
src/Lisp.php
10
src/Lisp.php
@ -16,7 +16,7 @@ class Lisp
|
||||
$this->printer = $printer;
|
||||
}
|
||||
|
||||
public function rep(string $input, Env $env): void
|
||||
public function rep(string $input, Env $env, bool $printReadable): void
|
||||
{
|
||||
$tokens = $this->tokenizer->tokenize($input);
|
||||
|
||||
@ -24,7 +24,7 @@ class Lisp
|
||||
|
||||
$result = $this->eval->eval($expr, $env);
|
||||
|
||||
$this->printer->print($result);
|
||||
$this->printer->print($result, $printReadable);
|
||||
}
|
||||
|
||||
public function register(Env $env): void
|
||||
@ -43,9 +43,9 @@ class Lisp
|
||||
fn (string $a) => $this->reader->read($this->tokenizer->tokenize($a))
|
||||
));
|
||||
|
||||
$env->set('print', new CoreFunc('print', 'Print argument.', 1, 1,
|
||||
function ($a) {
|
||||
$this->printer->print($a);
|
||||
$env->set('print', new CoreFunc('print', 'Print argument. Give second argument as true to show strings in readable format.', 1, 2,
|
||||
function ($a, bool $readable = false) {
|
||||
$this->printer->print($a, $readable);
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
@ -3,21 +3,21 @@ namespace MadLisp;
|
||||
|
||||
class Printer
|
||||
{
|
||||
public function print($ast): void
|
||||
public function print($ast, bool $readable = true): void
|
||||
{
|
||||
print($this->doPrint($ast));
|
||||
print($this->doPrint($ast, $readable));
|
||||
}
|
||||
|
||||
private function doPrint($a): string
|
||||
private function doPrint($a, bool $readable): string
|
||||
{
|
||||
if ($a instanceof Func) {
|
||||
return '<function>';
|
||||
} elseif ($a instanceof MList) {
|
||||
return '(' . implode(' ', array_map(fn ($b) => $this->doPrint($b), $a->getData())) . ')';
|
||||
return '(' . implode(' ', array_map(fn ($b) => $this->doPrint($b, $readable), $a->getData())) . ')';
|
||||
} elseif ($a instanceof Vector) {
|
||||
return '[' . implode(' ', array_map(fn ($b) => $this->doPrint($b), $a->getData())) . ']';
|
||||
return '[' . implode(' ', array_map(fn ($b) => $this->doPrint($b, $readable), $a->getData())) . ']';
|
||||
} elseif ($a instanceof Hash) {
|
||||
return '{' . implode(' ', array_map(fn ($key, $val) => $this->doPrint($key) . ':' . $this->doPrint($val),
|
||||
return '{' . implode(' ', array_map(fn ($key, $val) => $this->doPrint($key, $readable) . ':' . $this->doPrint($val, $readable),
|
||||
array_keys($a->getData()), array_values($a->getData()))) . '}';
|
||||
} elseif ($a instanceof Symbol) {
|
||||
return $a->getName();
|
||||
@ -28,9 +28,17 @@ class Printer
|
||||
} elseif ($a === null) {
|
||||
return 'null';
|
||||
} elseif (is_string($a)) {
|
||||
if ($readable) {
|
||||
$a = str_replace("\\", "\\\\", $a);
|
||||
$a = str_replace("\n", "\\n", $a);
|
||||
$a = str_replace("\r", "\\r", $a);
|
||||
$a = str_replace("\"", "\\\"", $a);
|
||||
return '"' . $a . '"';
|
||||
} else {
|
||||
return $a;
|
||||
}
|
||||
} else {
|
||||
return $a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user