function compile_call($expr, &$oob) { static $php_forms = array("print", "array"); $name = array_shift($expr); $oob["macros"] = is_array($oob["macros"]) ? $oob["macros"] : array(); if (array_key_exists(symbol_str($name), $oob["macros"])) { array_unshift($expr, $oob["macros"][$name . ""]); return compile(call_user_func_array("call", $expr), $oob); } $buf = ","; foreach ($expr as $e) { $buf .= compile(is_symbol($e) ? array(symbol("env"), $e) : $e, $oob) . ","; } $buf = substr($buf, 0, -1); $buf = $buf == "," ? "" : $buf; if (function_exists($name . "") or in_array($name . "", $php_forms)) { return "" . $name . "(" . substr($buf, 1, strlen($buf)) . ")"; } return "call(" . compile($name, $oob) . $buf . ")"; }
static function macro_expand($form) { if (is_array($form)) { $output = array(); foreach ($form as $part) { if (is_array($part)) { array_push($output, self::macro_expand($part)); } else { array_push($output, $part); } } $op = $output[0]; if (is_symbol($op) and substr($op . "", -1) == "." and $op . "" != ".") { $output[0] = symbol(substr($op, 0, strlen($op) - 1)); $op = symbol("new"); array_unshift($output, $op); } if (is_symbol($op) and $op->macro) { $op = Lisp::eval1($op); array_shift($output); $output = Lisp::apply1($op, $output); $output = self::macro_expand($output); } return $output; } else { return $form; } }