function _equal_Q($a, $b) { $ota = gettype($a) === "object" ? get_class($a) : gettype($a); $otb = gettype($b) === "object" ? get_class($b) : gettype($b); if (!($ota === $otb or _sequential_Q($a) and _sequential_Q($b))) { return false; } elseif (_symbol_Q($a)) { #print "ota: $ota, otb: $otb\n"; return $a->value === $b->value; } elseif (_list_Q($a) or _vector_Q($a)) { if ($a->count() !== $b->count()) { return false; } for ($i = 0; $i < $a->count(); $i++) { if (!_equal_Q($a[$i], $b[$i])) { return false; } } return true; } elseif (_hash_map_Q($a)) { if ($a->count() !== $b->count()) { return false; } $hm1 = $a->getArrayCopy(); $hm2 = $b->getArrayCopy(); foreach (array_keys($hm1) as $k) { if ($hm1[$k] !== $hm2[$k]) { return false; } } return true; } else { return $a === $b; } }
public function __construct($outer, $binds = NULL, $exprs = NULL) { $this->outer = $outer; if ($binds) { if (_sequential_Q($exprs)) { $exprs = $exprs->getArrayCopy(); } for ($i = 0; $i < count($binds); $i++) { if ($binds[$i]->value === "&") { if ($exprs !== NULL && $i < count($exprs)) { $lst = call_user_func_array('_list', array_slice($exprs, $i)); } else { $lst = _list(); } $this->data[$binds[$i + 1]->value] = $lst; break; } else { if ($exprs !== NULL && $i < count($exprs)) { $this->data[$binds[$i]->value] = $exprs[$i]; } else { $this->data[$binds[$i]->value] = NULL; } } } } }
function _equal_Q($a, $b) { $ota = gettype($a) === "object" ? get_class($a) : gettype($a); $otb = gettype($b) === "object" ? get_class($b) : gettype($b); if (!($ota === $otb or _sequential_Q($a) and _sequential_Q($b))) { return false; } elseif (_symbol_Q($a)) { #print "ota: $ota, otb: $otb\n"; return $a->value === $b->value; } elseif (_list_Q($a) or _vector_Q($a)) { if ($a->count() !== $b->count()) { return false; } for ($i = 0; $i < $a->count(); $i++) { if (!_equal_Q($a[$i], $b[$i])) { return false; } } return true; } else { return $a === $b; } }
function eval_ast($ast, $env) { if (_symbol_Q($ast)) { return $env->get($ast); } elseif (_sequential_Q($ast)) { if (_list_Q($ast)) { $el = _list(); } else { $el = _vector(); } foreach ($ast as $a) { $el[] = MAL_EVAL($a, $env); } return $el; } elseif (_hash_map_Q($ast)) { $new_hm = _hash_map(); foreach (array_keys($ast->getArrayCopy()) as $key) { $new_hm[$key] = MAL_EVAL($ast[$key], $env); } return $new_hm; } else { return $ast; } }
}, 'map?' => function ($a) { return _hash_map_Q($a); }, 'assoc' => function () { return call_user_func_array('assoc', func_get_args()); }, 'dissoc' => function () { return call_user_func_array('dissoc', func_get_args()); }, 'get' => function ($a, $b) { return get($a, $b); }, 'contains?' => function ($a, $b) { return contains_Q($a, $b); }, 'keys' => function ($a) { return keys($a); }, 'vals' => function ($a) { return vals($a); }, 'sequential?' => function ($a) { return _sequential_Q($a); }, 'cons' => function ($a, $b) { return cons($a, $b); }, 'concat' => function () { return call_user_func_array('concat', func_get_args()); }, 'nth' => function ($a, $b) { return nth($a, $b); }, 'first' => function ($a) { return first($a); }, 'rest' => function ($a) { return rest($a); }, 'empty?' => function ($a) { return empty_Q($a); }, 'count' => function ($a) { return scount($a); }, 'conj' => function () {