2020-05-27 09:27:47 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class MadLispException extends Exception {}
|
|
|
|
|
2020-05-27 11:54:39 +00:00
|
|
|
abstract class MLCollection
|
2020-05-27 09:27:47 +00:00
|
|
|
{
|
2020-05-27 11:54:39 +00:00
|
|
|
protected array $data = [];
|
2020-05-27 09:27:47 +00:00
|
|
|
|
2020-05-27 11:54:39 +00:00
|
|
|
public function __construct(array $data = [])
|
2020-05-27 09:27:47 +00:00
|
|
|
{
|
2020-05-27 11:54:39 +00:00
|
|
|
$this->data = $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function count(): int
|
|
|
|
{
|
|
|
|
return count($this->data);
|
2020-05-27 09:27:47 +00:00
|
|
|
}
|
|
|
|
|
2020-05-27 11:54:39 +00:00
|
|
|
public function has(string $key): bool
|
2020-05-27 09:27:47 +00:00
|
|
|
{
|
|
|
|
return array_key_exists($key, $this->data);
|
|
|
|
}
|
|
|
|
|
2020-05-27 11:54:39 +00:00
|
|
|
public function getData(): array
|
|
|
|
{
|
|
|
|
return $this->data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class MLList extends MLCollection
|
|
|
|
{
|
|
|
|
public function get(int $index)
|
|
|
|
{
|
|
|
|
if ($this->has($index)) {
|
|
|
|
return $this->data[$index];
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new MadLispException("list does not contain index $index");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class MLHash extends MLCollection
|
|
|
|
{
|
|
|
|
public function get(string $key)
|
|
|
|
{
|
|
|
|
if ($this->has($key)) {
|
|
|
|
return $this->data[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new MadLispException("hash does not contain key $key");
|
|
|
|
}
|
|
|
|
|
|
|
|
public function set(string $key, $value): void
|
|
|
|
{
|
|
|
|
$this->data[$key] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class MLEnv extends MLHash
|
|
|
|
{
|
|
|
|
protected ?MLEnv $parent;
|
|
|
|
|
|
|
|
public function __construct(?MLEnv $parent = null)
|
|
|
|
{
|
|
|
|
$this->parent = $parent;
|
|
|
|
}
|
|
|
|
|
2020-05-27 09:27:47 +00:00
|
|
|
public function get(string $key)
|
|
|
|
{
|
|
|
|
if ($this->has($key)) {
|
|
|
|
return $this->data[$key];
|
|
|
|
} elseif ($this->parent) {
|
|
|
|
return $this->parent->get($key);
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new MadLispException("symbol $key not defined");
|
|
|
|
}
|
2020-05-27 11:54:39 +00:00
|
|
|
}
|
2020-05-27 09:27:47 +00:00
|
|
|
|
2020-05-27 11:54:39 +00:00
|
|
|
class MLSymbol
|
|
|
|
{
|
|
|
|
protected string $name;
|
|
|
|
|
|
|
|
public function __construct(string $name)
|
2020-05-27 09:27:47 +00:00
|
|
|
{
|
2020-05-27 11:54:39 +00:00
|
|
|
$this->name = $name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function name(): string
|
|
|
|
{
|
|
|
|
return $this->name;
|
2020-05-27 09:27:47 +00:00
|
|
|
}
|
|
|
|
}
|