I'd like to get string from user, parse it, then run the parsed commands.
The string input will be something like "F20N20E10L10", guaranteed no spaces.
This input I want to convert to LOGO commands with substitutions like these:
- "F" →
fd - "N" →
seth 0 fd - "E" →
seth 90 fd - "L" →
lt 90 fd
So the string input above would be converted to these LOGO commands:
fd 20 seth 0 fd 20 seth 90 fd 10 lt 90 fd 10
All Forth dialects allow input, and interpreting a string of commands.
But I can't find any with search and replace string operations. Is this possible in any dialect of LOGO? Willing to consider any.
Thank you for reading.
It's been a while since I've written any Logo, so I'm not sure if this is the easiest way, but here's one way you can do it. The general idea is you can work with strings as lists of characters, using
FIRST,LAST,BUTFIRST, andBUTLASTto get at different parts of the string. (I tested this on the first two online Logo interpreters I could find -- http://www.logointerpreter.com/turtle-editor.php and http://www.calormen.com/jslogo/ -- and it ran fine on both, but you might need some small changes for other Logo dialects.)Then, try running:
This prints and executes the following:
Some Explanation
RUN_COMMANDSis the main function. It:GET_NUMBERwhich extracts a number (which could be multiple characters) from the start of the string.RUN_SINGLE_COMMANDIS_DIGITis used withinGET_NUMBERto check if a character is numeric (although I would bet some Logo dialects have a built-in function for this.)MERGE_STRINGis used because I had some multi-character Words ("word" is Logo-speak for a string) which I had turned into Lists of single-character Words, and I wanted to merge the list back into a single Word. This might not actually be necessary, though.RUN_SINGLE_COMMANDexecutes each individual command that was parsed from the input string. I just used a bigIFstatement, rather than using a function which interprets the string as code as you suggested. (Some Logo dialects might have such a function, but I'm not sure of a standard one.)RUN_SINGLE_COMMANDalso callsPRINT_COMMAND, which prints out the unabbreviated command as it's run.Potential Stack Overflows
I used lots of recursion because it's more idiomatic of Logo, and because Logo dialects often don't have a lot of looping constructs (other than
REPEAT). But I did it in a careless way, since I was just writing this quickly to give you the general idea. In particular, I didn't worry about stack overflows (no pun intended), which I think could occur if you provided a long input string. To deal with this, you should make sure any recursive path that can be called arbitrarily many times is a tail call, which Logo will optimize away.At a glance, it looks like
RUN_COMMANDSis fine butMERGE_STRINGandGET_NUMBERare reversed -- instead ofIF <condition> [<recursive_call>]followed byOUTPUT <return_value>, it would be better to doIF (NOT <condition>) [OUTPUT <return_value>]followed by<recursive_call>. Testing for stack overflows and applying this fix I have left as an exercise for the reader. :)