<?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 handleWord($lexer, $ast, $token, $directive){
$word = $token->buffer();
$xpn = $lexer->previous('xpn');
$xpn->push('declaration', $word);
$xpn->push('words', $word);
$method = 'wd_'.$word;
// @bug if a variable name `$word` has a matching function `wd_$word`, then the variable will not be recognized
// This means variables have special allowance & the word that is detected cannot be handled normally
// it has to be passed to unhandled_wd
// so where does that logic belong?
// Probably just call it from `wd_namespace()` bc `wd_namespace()` should know when it is viable
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];
}
}