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];
    }
}