Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Icon (programming language)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===String scanning=== A further simplification for handling strings is the ''scanning'' system, invoked with {{code|?}}, which calls functions on a string: <syntaxhighlight lang="icon"> s ? write(find("the")) </syntaxhighlight> Icon refers to the left-hand-side of the {{code|?}} as the ''subject'', and passes it into string functions. Recall the {{code|find}} takes two parameters, the search text as parameter one and the string to search in parameter two. Using {{code|?}} the second parameter is implicit and does not have to be specified by the programmer. In the common cases when multiple functions are being called on a single string in sequence, this style can significantly reduce the length of the resulting code and improve clarity. Icon function signatures identify the subject parameter in their definitions so the parameter can be [[Loop-invariant code motion|hoisted]] in this fashion. The {{code|?}} is not simply a form of syntactic sugar, it also sets up a "string scanning environment" for any following string operations. This is based on two internal variables, {{code|&subject}} and {{code|&pos}}; {{code|&subject}} is simply a pointer to the original string, while {{code|&pos}} is the current position within it, or cursor. Icon's various string manipulation procedures use these two variables so they do not have to be explicitly supplied by the programmer. For example: <syntaxhighlight lang="icon"> s := "this is a string" s ? write("subject=[",&subject,"], pos=[",&pos,"]") </syntaxhighlight> would produce: <syntaxhighlight lang="text"> subject=[this is a string], pos=[1] </syntaxhighlight> Built-in and user-defined functions can be used to move around within the string being scanned. All of the built-in functions will default to {{code|&subject}} and {{code|&pos}} to allow the scanning syntax to be used. The following code will write all blank-delimited "words" in a string: <syntaxhighlight lang="icon"> s := "this is a string" s ? { # Establish string scanning environment while not pos(0) do { # Test for end of string tab(many(' ')) # Skip past any blanks word := tab(upto(' ') | 0) # the next word is up to the next blank -or- the end of the line write(word) # write the word } } </syntaxhighlight> There are a number of new functions introduced in this example. {{code|pos}} returns the current value of {{code|&pos}}. It may not be immediately obvious why one would need this function and not simply use the value of {{code|&pos}} directly; the reason is that {{code|&pos}} is a variable and thus cannot take on the value {{code|&fail}}, which the procedure {{code|pos}} can. Thus {{code|pos}} provides a lightweight wrapper on {{code|&pos}} that allows Icon's goal-directed flow control to be easily used without having to provide hand-written Boolean tests against {{code|&pos}}. In this case, the test is "is &pos zero", which, in the odd numbering of Icon's string locations, is the end of the line. If it is ''not'' zero, {{code|pos}} returns {{code|&fail}}, which is inverted with the {{code|not}} and the loop continues. {{code|many}} finds one or more examples of the provided Cset parameter starting at the current {{code|&pos}}. In this case, it is looking for space characters, so the result of this function is the location of the first non-space character after {{code|&pos}}. {{code|tab}} moves {{code|&pos}} to that location, again with a potential {{code|&fail}} in case, for instance, {{code|many}} falls off the end of the string. {{code|upto}} is essentially the reverse of {{code|many}}; it returns the location immediately prior to its provided Cset, which the example then sets the {{code|&pos}} to with another {{code|tab}}. Alternation is used to also stop at the end of a line. This example can be made more robust through the use of a more appropriate "word breaking" Cset which might include periods, commas and other punctuation, as well as other whitespace characters like tab and non-breaking spaces. That Cset can then be used in {{code|many}} and {{code|upto}}. A more complex example demonstrates the integration of generators and string scanning within the language. <syntaxhighlight lang="icon"> procedure main() s := "Mon Dec 8" s ? write(Mdate() | "not a valid date") end # Define a matching function that returns # a string that matches a day month dayofmonth procedure Mdate() # Define some initial values static dates static days initial { days := ["Mon","Tue","Wed","Thr","Fri","Sat","Sun"] months := ["Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec"] } every suspend (retval <- tab(match(!days)) || # Match a day =" " || # Followed by a blank tab(match(!months)) || # Followed by the month =" " || # Followed by a blank matchdigits(2) # Followed by at least 2 digits ) & (=" " | pos(0) ) & # Either a blank or the end of the string retval # And finally return the string end # Matching function that returns a string of n digits procedure matchdigits(n) suspend (v := tab(many(&digits)) & *v <= n) & v end </syntaxhighlight>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)