Handlers.php
<?php
namespace Tlf\Lexer\PhpNew;
trait Handlers {
//
//
//Helper methods
//
//
/**
* add a docblock to the ast if there is a previous docblock set. unset the previous docblock.
*
* @param $ast an object
*/
public function docblock(object $ast){
if ($docblock = $this->lexer->unsetPrevious('docblock')){
$ast->docblock = $docblock;
}
}
public function setArgDeclaration($arg){
$lexer = $this->lexer;
$xpn = $lexer->previous('xpn');
$declaration = $xpn->declaration;
$pos = count($declaration);
while (--$pos>=0&&$declaration[$pos]!='('&&$declaration[$pos]!=','){}
if ($pos>0)$declaration = array_slice($declaration,$pos+1);
$arg->declaration = trim(implode('',$declaration));
$lexer->popHead();
$xpn->words = [];
}
public function closeArg($arg){
$lexer = $this->lexer;
$xpn = $lexer->previous('xpn');
$declaration = $xpn->declaration;
$pos = count($declaration);
while (--$pos>=0&&$declaration[$pos]!='('&&$declaration[$pos]!=','){}
if ($pos>0)$declaration = array_slice($declaration,$pos+1);
$arg->declaration = trim(implode('',$declaration));
if ($xpn->waiting_for == 'value'){
$arg->value = implode('',$xpn->words);
$xpn->waiting_for = null;
}
$lexer->popHead();
$xpn->words = [];
}
//
//
// operation / word routers
//
//
public function handleComment($lexer, $ast, $token, $directive){
$ast->push('comments', trim($token->buffer()));
}
/**
* move the string_backslash directive to the front of the directives list
*/
public function handleStringBackslash($lexer, $ast, $token, $directive){
// print_r($directive);
// exit;
$stack = &$lexer->directiveStack[count($lexer->directiveStack)-1]['unstarted'];
// echo "\n\n\n-----------\n\n";
// print_r(array_keys($stack));
// echo "\n\n\n-----------\n\n";
$backslash = $stack['string_backslash'];
unset($stack['string_backslash']);
$new_stack = [];
$new_stack['string_backslash'] = $backslash;
foreach ($stack as $key=>$value){
$new_stack[$key] = $value;
}
$stack = $new_stack;
return;
$string_backslash_hopefully = array_pop($stack);
array_unshift($stack, $string_backslash_hopefully);
print_r(array_keys($stack));
exit;
}
public function handleString($lexer, $ast, $token, $directive){
// $lexer->abort();
if (substr($token->buffer(),-2,1)=='\\'){
echo "\n\n\n\n\nThere was a string backslash error!\n\n\n\n\n";
$lexer->abort();
// exit;
return;
}
$string = $token->buffer();
$xpn = $lexer->previous('xpn');
$xpn->push('declaration', $string);
$xpn->push('words', $string);
}
public function handleWhitespace($lexer, $ast, $token, $directive){
$whitespace = $token->buffer();
$xpn = $lexer->previous('xpn');
$xpn->push('declaration', $whitespace);
}
public function handleWord($lexer, $ast, $token, $directive){
$word = $token->buffer();
$xpn = $lexer->previous('xpn');
$xpn->push('declaration', $word);
$xpn->push('words', $word);
$method = 'wd_'.$word;
if (method_exists($this,$method)){
if ($lexer->debug){
echo "\n call ".$method.'()';
}
$this->$method($lexer,$xpn,$ast);
} else {
if ($lexer->debug){
echo "\n unhandled_wd '$word'";
}
$this->unhandled_wd($lexer, $xpn, $ast, $word);
}
$xpn->last_word = $word;
}
/**
* Convert an expression into an informational ast
*/
public function handleOperation($lexer, $ast, $token, $directive){
$xpn = $lexer->previous('xpn');
//I'm gonna have to also handle multi-character operations like:
// == === && ||
// ... (vararg)
$map = $this->get_operations();
$char = $token->buffer();
if (!isset($map[$char])){
$lexer->haltInstructions();
$lexer->directiveStopped($directive);
$token->next();
echo "\n --Invalid operator: $char";
return;
// echo "\n\n--ERROR--\n\n";
// echo "Char '$char' does not have any operations associated with it. Available operations are:";
// print_r($map);
// throw new \Exception("Invalid character matched");
}
$method = 'op_'.$map[$char];
if ($lexer->debug){
echo "\n call '$method'";
}
if (!method_exists($this,$method)){
return;
}
$this->$method($lexer, $ast, $xpn);
// $this->$method($lexer, $expression, $token, $directive);
$lexer->unsetPrevious('docblock');
$lexer->previous('xpn')->last_op = $map[$char];
}
}