madlisp/src/Printer.php

68 lines
2.2 KiB
PHP

<?php
/**
* MadLisp language
* @link http://madlisp.com/
* @copyright Copyright (c) 2020 Pekka Laiho
*/
namespace MadLisp;
class Printer
{
public function print($ast, bool $readable): void
{
print($this->pstr($ast, $readable));
}
public function pstr($ast, bool $readable): string
{
return $this->doPrint($ast, $readable);
}
private function doPrint($a, bool $readable): string
{
if ($a instanceof Func) {
if ($a->isMacro()) {
return '<macro>';
} else {
return '<function>';
}
} elseif ($a instanceof MList) {
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, $readable), $a->getData())) . ']';
} elseif ($a instanceof Hash) {
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();
} elseif (is_object($a)) {
$class = get_class($a);
return "<object<$class>>";
} elseif (is_resource($a)) {
return '<resource>';
} elseif ($a === true) {
return 'true';
} elseif ($a === false) {
return 'false';
} 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("\t", "\\t", $a);
$a = str_replace("\v", "\\v", $a);
$a = str_replace("\0", "\\0", $a);
$a = str_replace("\"", "\\\"", $a);
return '"' . $a . '"';
} else {
return $a;
}
} else {
return $a;
}
}
}