<?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);
}
}