NewLanguage.php

<?php

namespace Tlf\Lexer\Test;

class NewLanguage extends \Tlf\Tester {

    public function get_parser_code(){
        $parser_code = <<<'PARSER'
            main: # Entry function.  (or is it a Directive?)
                if_unstarted: (is this a function? a branch?)
                    head.is_root # 'main' only runs if the head ast is the root ast
                        # May want 'state.is root' to check what the top of the state stack is. 
                            # (basically just the type of the head ast)
                    buffer.ends_with " # else execution stops
                        # 1. Marks main as started. SEE Note 1
                    buffer.clear
                    start
                    add_directive_layer
                    :person_name # previously, this was a 'then' statement.
                        # calling :person_name will: 
                            # 1. create a new layer on the function stack
                                # - this pauses main until the new layer is popped and
                                    # main is in the top of the function stack.
                            # 2. add person_name function to top layer of function stack
                            # 3. On the next loop, the top layer of the function stack will
                                # be called, so person_name:if_unstarted: should be executed
                if_started:
                    buffer.ends_with "
                    buffer.clear
                    stop 
                        # returns to 'unstarted' state, but remains in the stack.
                        # Unstarted functions are only run if no functions are started in the stack.
                            # I might change this. It is confusing?.
                            # What about more states? paused? stopped?
                    
            person_name: 
                if_unstarted:
                    head.is_root
                    buffer.padLeft
                    hook end_execute_commands buffer.removeLeft 1 
                    buffer.match /\s([a-zA-Z]+)\'s/ # regex to match a-zA-Z followed by a space
                    set_arg Person !new Ast\Person:
                        name=$1
                    #head.create_array People
                    head.People.push_or_get $Person
                    debug.die
                    # Person= !head.head_ast.get_where People:
                        # name=Reed
                    # Person.push !new Ast\Person:
                     #   name=$1
                    buffer.clear
                    pop directive_stack 
                    add_directive_layer
                    :pet_name # a new directive stack is created and pet_name is added to it
                        # How to add function to current stack?
                            # function_stack.append :pet_name
                            # or maybe? append function_stack :pet_name 
            pet_name: 
                if_unstarted:
                    head.is Person 
                    hook end_execute_commands buffer.reset
                    buffer.padLeft
                    buffer.match /\s([a-zA-Z]+)[^a-zA-Z]/
                    buffer.rewind 1
                    buffer.clear
                    head.Pets.push $1
                    pop ast_stack
                    pop directive_stack
                    :main
                    # pop directive_stack # pop is in stdlib
        PARSER;
        return $parser_code;
    }


    public function testNewPhp(){
        $text_to_parse = <<<PHP
            <?php
                echo "abc";
        PHP;

        $lexer2 = new \Tlf\Lexer2();
        $lexer2->addLanguage(new \Tlf\Lexer2\Language\Php());
        $lexer2->addLanguage(new \Tlf\Lexer2\Language\Docblock());
        $ast = $lexer2->parse($text_to_parse);

        print_r($ast->getTree());

    }
    public function testMain(){
        $text_to_parse = '"Reed\'s Bear"'
            ."\n\"Reed's Cat\""
            ."\n\"Reed's Dog\""
            ."\n\"Baby's Parakeet\""
            ."\n\"Fushulu's Dragon\"";
        $parser_code = $this->get_parser_code();
        $TargetProgramAst = [
            'type'=>'Program',
            'context'=>[
                // TODO: figure out Program Context.
            ],
            'input_type'=>'string',
            'input'=>$parser_code,
            'People'=>[
                0=> [
                    'type'=>'Person',
                    'name'=>'Reed',
                    'Pets'=>[
                        'Bear'
                    ],
                ],
            ],

        ];

        // TODO: FIX THE PARSER CODE
        // Loop 13 activates PetOwner:main[unstarted] 
        // But it shouldn't because this is the closing " mark at the end of "Reed's Bear"
        // So the current parser code ... THINKS that this question mark is the start of a new "Person's Pet" definition
        // But its not. It is the END of the first person's pet.
        // I think I may need some major restructure on that.
        // But


        $newLexer = new \Tlf\Lexer2();
        $code_ast = $newLexer->addCode($parser_code,'PetOwner');
        //print_r($newLexer);
        $output_ast = $newLexer->parse($text_to_parse);

        echo "\n\n\nFINAL AST: \n\n";
        //print_r($newLexer->program->ast_stack);
        print_r($output_ast->getTree());
        //print_r($code_ast);
        //exit;

        //print_r($output_ast);

    }

}