-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for closures, loops, classes in REPL #4
Comments
wow interesting problem, I hadn't even contemplated trying to do this type of thing. but clearly it's cool! Did you get to a solution? I am too tired to think about it myself atm :) |
maybe we need some special multi-line mode? |
I had it working sort of kind of but them that way would break when it was serialized so multi-line mode = no serialization of anything The real problem isn't getting a multi-line mode working its this block of code ob_start(); \$_ = {$command}; \$__out = ob_get_contents(); ob_end_clean(); Sticking "class Foo {}" into the $_ = class Foo {} throws a syntax error |
Wow yeah so irb lets you write any ruby. no wonder they have "reload"! I think we could accomplish that with some kind of "eval vs define" mode. Currently we have eval mode, but we could have certain keywords trigger "define" mode, like "class, interface, function, etc". Then store that data separately in a single "multiline_require" file that would be included just before the $_ = {$command} Does that sound promising? |
Actually maybe this is an ideal situation to use the built-in php tokenizer: http://us2.php.net/manual/en/function.token-get-all.php Pre-parse the entered line and see what it looks like. No idea how it deals with syntax errors. |
well you run php_check_syntax($file) then you tokenize it |
and the way i was doing it was running this huge regex i made "/^(class|function|interface|foreach|etc)/" |
php_check_syntax is deprecated/obselete. based on the way irb looks like it works, I think we just have to keep track of what's being entered. When you hit ENTER look at the line for quotes, foreach, etc and maintain state... then keep a single file with all of these commands and keep appending them. they'd have to be run each time in the repl exec tho which could get slow for certain things (and certianly not be idempotent either). |
the way i had it working for classes was it detected the { operator and } operator and tracked nested operators so making class Foo { public function __construct() { } } Had a nested of index of 2 and stored each entered line in and array until the last } was captured setting the nested counter to zero then i was injecting them into the doCommand() as a array imploded on "\n" |
it's def a start, but I think too primitive. it'd be ideal to follow the PHP parsing rules by using token_get_all(), then we won't have to educate people on how to hack iphp to enable multi-line stuff... |
started working on a tokenizer class |
cool! looks promising. I think it might be wiser to have more than just a "multi-line" boolean; rather use a state stack which effects what action happens on RETURN. For instance, "" will just let the NL through since NL is a valid char for quoted strings. But certain keywords or blocks will enter multi-line mode, and who knows if we'll need different ones. We can just maintain an internal stack of "inputMode" with options like MODE_QUOTED_STRING, MODE_BLOCK, etc as needed, and then each mode can look for its "close" tag. Make sense? |
well i created the boolean to run a test from inside doCommand if that passes i was going to write a buffering class (that implements the state stack) that can handle the multi line input and store it until its valid executable syntax i see no need ot crud up the main class with this |
Yeah i like the idea of a buffering class... could be used to do multi-line php input in any project (although not sure how big of a need that is...) |
Few things as im hacking through this im working on the doCommand function and was wondering why eval will not work for the main code execution so we don't need to use tempfiles? |
that's how it used to work but there is a big problem with that. The "host" of eval() dies if there's a fatal error. Thus if you did something like $a->foo() you'd get a FATAL error that would kill the shell. IMO the "fatal-safety" of iphp is the killer feature it has; I'd never seen it done anywhere else before and this problem severely limited the utility of the shell for me since it would die after you'd built up state because of a simple typo. |
totally understand i didn't know you couldn't try catch an eval |
just finished moving some stuff out and writing some tests going to start working on test cases for the main class so i can build out a multi line function without breaking everything |
i have made a bunch of mods; please rebase your feature branch on my master, thanks! |
i have already merged in most of bermi's changes ill get around to pulling yours down tomorrow |
Scott not sure if you're working on this any more, but I did hook up iphp to token_get_all() tonight and managed to get iphp working gracefully when the "command" doesn't return data. I would be very interested in your multiline stuff now... |
This was bugging me for awhile and i hacked away for about 2.5 hours trying to figure out a work about but
example:
Same goes for defining functions and classes
function:
Classes:
While i had a work around working the storing of $_ and $__out are not possible when you create a a special case even "foreach" will explode using serialization
Solution is avoid serialization and store the code input unserialized in a file and keep appending to it and re-executing, As for returning output some string parsing may be in order to find variables and var_dump-ing them may be in order or just rely or just print tokenize the last returnable line;
edit: fixed typo's my brain is fried
The text was updated successfully, but these errors were encountered: