Exemple #1
0
 function group($string, $inquote = false)
 {
     $ast = array();
     $parens = array('(' => ')', '[' => ']', '{' => '}');
     $reserved = array('each', 'for', 'string');
     $special = array('!' => 'exc', '?' => 'que', '+' => 'add', '-' => 'sub', '*' => 'mul', '/' => 'div', '%' => 'per', '>' => 'gt', '<' => 'lt', '=' => 'eql');
     $stringLength = strlen($string);
     $token = false;
     $splice = false;
     $quoteone = false;
     for ($index = 0; $index <= $stringLength; $index++) {
         $char = isset($string[$index]) ? $string[$index] : false;
         if ($char == '`') {
             $inquote = 'quasi';
             continue;
         }
         if ($char == '\'') {
             if (!$inquote) {
                 $quoteone = true;
             }
             $inquote = 'single';
             continue;
         }
         if ($char == ',') {
             $splice = 'unquote';
             continue;
         }
         if ($splice && $char == '@') {
             $splice = 'unquotesplice';
             continue;
         }
         //handle parens of all sort
         if (!$token && isset($parens[$char])) {
             $start = $char;
             $stop = $parens[$char];
             $block = '';
             $count = 0;
             $lambda = false;
             for ($subindex = $index + 1; $subindex < $stringLength; $subindex++) {
                 $subchar = $string[$subindex];
                 if ($subchar == $start) {
                     $count++;
                 }
                 if ($subchar == '|' && !$lambda && !$count && $start == '[') {
                     $lambda = array('lambda', $this->group($block, $inquote));
                     $block = '';
                     continue;
                 }
                 if ($subchar == $stop) {
                     if ($count) {
                         $count--;
                     } else {
                         $block = trim($block);
                         if ($start == '[' && $this->atomCount($block) > 1 && $block[0] != '"' && !isset($parens[$block[0]]) && $block[0] != '`') {
                             $block = '(' . $block . ')';
                         }
                         $block = $this->group($block, $splice && $inquote != 'single' ? false : $inquote);
                         break;
                     }
                 }
                 $block .= $subchar;
             }
             if ($lambda) {
                 $lambda[] = array_shift($block);
                 $block = $lambda;
                 $lambda = false;
             } else {
                 if ($start == '[') {
                     $block = array('lambda', array(array('gensym', '_')), array_shift($block));
                 } else {
                     if ($start == '{') {
                         array_unshift($block, 'ndict');
                     } else {
                         if ($start == '(' && $block[0] == 'while') {
                             $block = array($block);
                         }
                     }
                 }
             }
             if ($inquote == 'quasi' && !$splice) {
                 array_unshift($block, 'quasiquote');
                 $block = array($block);
                 $inquote = false;
             } else {
                 if ($inquote == 'single') {
                     array_unshift($block, 'list');
                     if ($quoteone) {
                         $inquote = false;
                     }
                 }
             }
             if ($splice) {
                 $block = array($splice, $block);
                 $splice = false;
             }
             if ($start == '(' && $block[0] == 'macro') {
                 array_shift($block);
                 list($args, $body) = $block;
                 $name = array_shift($args);
                 LisphpSpecialForms::$macros[$name] = evalLisp(array('lambda', $args, $body));
             } else {
                 $ast[] = $block;
             }
             $index = $subindex;
             continue;
         }
         //handle comments
         if ($char == ';') {
             $comment = '';
             for ($subindex = $index + 1; $subindex < $stringLength; $subindex++) {
                 $subchar = $string[$subindex];
                 if ($subchar == "\n" || $subchar == "\r") {
                     break;
                 }
                 $comment .= $subchar;
             }
             $ast[] = array('comment', $comment);
             $index = $subindex;
         }
         //handle strings
         if ($char == '"') {
             $escaped = false;
             $subString = '';
             for ($subindex = $index + 1; $subindex < $stringLength; $subindex++) {
                 $subchar = $string[$subindex];
                 if ($subchar == '\\' && !$escaped) {
                     $escaped = true;
                     continue;
                 }
                 if ($subchar == '"' && !$escaped) {
                     break;
                 } else {
                     $subString .= $subchar;
                     $escaped = false;
                 }
             }
             //parse strings further to allow for code interpolation and lexical scoping
             $ast[] = array('string', $subString);
             $index = $subindex;
             continue;
         }
         //handle tokens
         $char = preg_replace('/[\\s\\n\\r]+/', '', $char);
         $char = isset($special[$char]) ? '__lphp_' . $special[$char] : $char;
         if ($token === false) {
             $token = empty($char) && !is_numeric($char) ? false : $char;
         } else {
             if (!empty($char) || is_numeric($char)) {
                 $token .= $char;
             } else {
                 if (is_numeric($token)) {
                     $number = false;
                 } else {
                     if ($token[0] == '#') {
                         $token = array('literal', $token);
                         $literal = false;
                     } else {
                         if ($token[0] == ':') {
                             $token = array('symbol', substr($token, 1));
                             $symbol = false;
                         } else {
                             if (in_array($token, $reserved)) {
                                 $token = '__lphp_' . $token;
                             } else {
                                 if ($splice) {
                                     $token = array($splice, $token);
                                     $splice = false;
                                 } else {
                                     if ($token == '_') {
                                         $token = array('gensym', $token);
                                     }
                                 }
                             }
                         }
                     }
                 }
                 $ast[] = !is_array($token) && $inquote ? array('quote', $token) : $token;
                 if ($quoteone) {
                     $quoteone = $inquote = false;
                 }
                 if ($token == 'quote') {
                     $inquote = 'single';
                 }
                 $token = false;
             }
         }
     }
     return $ast;
 }
Exemple #2
0
    if (isset($_POST['showSource'])) {
        echo implode("\n\n", LisphpSpecialForms::$lambdas) . "\n\n";
    }
    eval(implode(LisphpSpecialForms::$lambdas));
    foreach (LisphpSpecialForms::$macros as $macro => $mac) {
        if (isset($_POST['showSource'])) {
            echo "macro {$macro} :: {$mac}\n\n";
        }
        eval('LisphpSpecialForms::$macros["' . $macro . '"] = ' . $mac . ';');
        $globalMacros .= '$' . $macro . ' =& LisphpSpecialForms::$macros["' . $macro . '"];' . "\n";
    }
    LisphpSpecialForms::$lambdas = array();
    //   $this->ast = $this->expandMacros($this->ast);
    $ast = $lisp->getAst();
    array_unshift($ast, 'begin');
    $php = evalLisp($ast);
    $transformed = implode("\n", LisphpSpecialForms::$lambdas) . $globalMacros . implode(";\n", $php) . ";";
    if (isset($_POST['showAst'])) {
        echo json_encode($lisp->getAst()) . "\n\n";
    }
    if (isset($_POST['showSource'])) {
        foreach (explode("\n", $transformed) as $num => $line) {
            echo (isset($_POST['showLineNumbers']) ? '#' . ($num + 1) . ' ' : '') . "{$line}\n";
        }
    }
    eval($transformed);
}
?>
</div>
<script>
  parent.displayResult(document.getElementById('output').innerHTML);
Exemple #3
0
 static function listForm($options, $env)
 {
     foreach ($options as &$option) {
         $option = evalLisp($option, $env);
     }
     return 'array(' . implode(',', $options) . ')';
 }