5 class Error
extends Exception
{
7 public function __construct($obj) {
8 parent
::__construct("Mal Error", 0, null);
16 function _equal_Q($a, $b) {
17 $ota = gettype($a) === "object" ?
get_class($a) : gettype($a);
18 $otb = gettype($b) === "object" ?
get_class($b) : gettype($b);
19 if (!($ota === $otb or (_sequential_Q($a) and _sequential_Q($b)))) {
21 } elseif (_symbol_Q($a)) {
22 #print "ota: $ota, otb: $otb\n";
23 return $a->value
=== $b->value
;
24 } elseif (_list_Q($a) or _vector_Q($a)) {
25 if ($a->count() !== $b->count()) { return false; }
26 for ($i=0; $i<$a->count(); $i++
) {
27 if (!_equal_Q($a[$i], $b[$i])) { return false; }
30 } elseif (_hash_map_Q($a)) {
31 if ($a->count() !== $b->count()) { return false; }
32 $hm1 = $a->getArrayCopy();
33 $hm2 = $b->getArrayCopy();
34 foreach (array_keys($hm1) as $k) {
35 if (!_equal_Q($hm1[$k], $hm2[$k])) { return false; }
43 function _sequential_Q($seq) { return _list_Q($seq) or _vector_Q($seq); }
47 function _nil_Q($obj) { return $obj === NULL; }
48 function _true_Q($obj) { return $obj === true; }
49 function _false_Q($obj) { return $obj === false; }
50 function _string_Q($obj) {
51 return is_string($obj) && strpos($obj, chr(0x7f)) !== 0;
59 public function __construct($value) {
60 $this->value
= $value;
63 function _symbol($name) { return new SymbolClass($name); }
64 function _symbol_Q($obj) { return ($obj instanceof SymbolClass
); }
67 function _keyword($name) { return chr(0x7f).$name; }
68 function _keyword_Q($obj) {
69 return is_string($obj) && strpos($obj, chr(0x7f)) === 0;
77 public $type = 'native'; // 'native' or 'platform'
81 public $params = NULL;
82 public $ismacro = False;
83 public function __construct($func, $type,
84 $ast, $env, $params, $ismacro=False) {
90 $this->params
= $params;
91 $this->ismacro
= $ismacro;
93 public function __invoke() {
94 $args = func_get_args();
95 if ($this->type
=== 'native') {
96 $fn_env = new Env($this->env
,
97 $this->params
, $args);
99 return $evalf($this->ast
, $fn_env);
101 return call_user_func_array($this->func
, $args);
104 public function gen_env($args) {
105 return new Env($this->env
, $this->params
, $args);
107 public function apply($args) {
108 return call_user_func_array(array(&$this, '__invoke'),$args);
112 function _function($func, $type='platform',
113 $ast=NULL, $env=NULL, $params=NULL, $ismacro=False) {
114 return new FunctionClass($func, $type, $ast, $env, $params, $ismacro);
116 function _function_Q($obj) { return $obj instanceof FunctionClass
; }
119 // Parent class of list, vector, hash-map
120 // http://www.php.net/manual/en/class.arrayobject.php
121 class SeqClass
extends ArrayObject
{
122 public function slice($start, $length=NULL) {
124 if ($start >= count($this)) {
127 $arr = array_slice($this->getArrayCopy(), $start, $length);
129 $sc->exchangeArray($arr);
136 class ListClass
extends SeqClass
{
141 $v = new ListClass();
142 $v->exchangeArray(func_get_args());
145 function _list_Q($obj) { return $obj instanceof ListClass
; }
149 class VectorClass
extends SeqClass
{
154 $v = new VectorClass();
155 $v->exchangeArray(func_get_args());
158 function _vector_Q($obj) { return $obj instanceof VectorClass
; }
162 class HashMapClass
extends ArrayObject
{
166 function _hash_map() {
167 $args = func_get_args();
168 if (count($args) %
2 === 1) {
169 throw new Exception("Odd number of hash map arguments");
171 $hm = new HashMapClass();
172 array_unshift($args, $hm);
173 return call_user_func_array('_assoc_BANG', $args);
175 function _hash_map_Q($obj) { return $obj instanceof HashMapClass
; }
177 function _assoc_BANG($hm) {
178 $args = func_get_args();
179 if (count($args) %
2 !== 1) {
180 throw new Exception("Odd number of assoc arguments");
182 for ($i=1; $i<count($args); $i+
=2) {
184 $vtoken = $args[$i+
1];
185 // TODO: support more than string keys
186 if (gettype($ktoken) !== "string") {
187 throw new Exception("expected hash-map key string, got: " . gettype($ktoken));
189 $hm[$ktoken] = $vtoken;
194 function _dissoc_BANG($hm) {
195 $args = func_get_args();
196 for ($i=1; $i<count($args); $i++
) {
198 if ($hm && $hm->offsetExists($ktoken)) {
208 public $value = NULL;
210 public function __construct($value) {
211 $this->value
= $value;
214 function _atom($val) { return new Atom($val); }
215 function _atom_Q($atm) { return $atm instanceof Atom
; }