I've been thinking about how I create a function in scheme that builds itself depending on an input.
The way a character is defined in scheme is #(character here), so if I were to check, with a function, if my character is indeed a character, I would have to take the input from the function and insert it instead of (character here), and make it work.
I am not sure how this is done, if I input a random character without the #\, I get that it is an undefined function, so how do I do this?
(define check-char?
(lambda (v)
(char? #\v)))
that is what I have, but as said, this is not working.
A character is a value. How exactly the value is stored in memory varies from from implementation to implementation. If we as programmers want to create a character we can do it various ways:
If we know ahead of time what character we need, we can use the literal syntax: #\x . When the reader reads the program, it will construct a character representing the letter x.
The actual character is stored in memory as a number. If we know that number, we can also produce an x using integer->char.
> (integer->char 120)
#\x
Strings are made from series of characters, so we can also produce characters using string-ref:
> (string-ref "x" 0)
#\x
The procedure used to check whether a value is a character is called char?.
> (char? #\x)
#t
> (char? (string-ref "x" 0))
#t
Your check-char? command can be written as:
(define check-char?
(lambda (v)
(char? v)))
Or simply as:
(define check-char? char?)
Let's test it:
> (check-char? #'x)
#t
> (check-char? 3)
#f
Related
I've a big dilemma how can I do a condition to remove this type of color from my string (ex: {dd2e22}) using sscanf, which is only func I want to use. So the string provided will be some random text:
Te{dd2e22}xt is {3f53ec}here
The condition what I tried
sscanf(buf,"%[^\{[0-9a-fA-F]{6,8}\}]s",output);
This isn't working, the result are only first character "T".
Try using the format specifier:
"%*6X"
Analysis:
% -- starts a format specifier.
* -- tells scanf not to assign field to variable.
6x -- says that field is 6 hex digits.
See scanf format specifier
result are only first character "T".
Well, the next character is 'e', which matches the set \{[0-9a-fA-F]{6,8}\ and thus doesn't match the inverted set specified by '^'.
This task can be achieved with a regular expression. The standard library provides you with appropriate tools in the <regex> header.
I can't understand how assignments and use of variables work in Tcl.
Namely:
If I do something like
set a 5
set b 10
and I do
set c [$a + $b]
Following what internet says:
You obtain the results of a command by placing the command in square
brackets ([]). This is the functional equivalent of the back single
quote (`) in sh programming, or using the return value of a function
in C.
So my statement should set c to 15, right?
If yes, what's the difference with
set c [expr $a + $b]
?
If no, what does that statement do?
Tcl's a really strict language at its core; it always follows the rules. For your case, we can therefore analyse it like this:
set c [$a + $b]
That's three words, set (i.e., the standard “write to a variable” command), c, and what we get from evaluating the contents of the brackets in [$a + $b]. That in turn is a script formed by a single command invocation with another three words, the contents of the a variable (5), +, and the contents of the b variable (10). That the values look like numbers is irrelevant: the rules are the same in all cases.
Since you probably haven't got a command called 5, that will give you an error. On the other hand, if you did this beforehand:
proc 5 {x y} {
return "flarblegarble fleek"
}
then your script would “work”, writing some (clearly defined) utter nonsense words into the c variable. If you want to evaluate a somewhat mathematical expression, you use the expr command; that's it's one job in life, to concatenate all its arguments (with a space between them) and evaluate the result as an expression using the documented little expression language that it understands.
You virtually always want to put braces around the expression, FWIW.
There are other ways to make what you wrote do what you expect, but don't do them. They're slow. OTOH, if you are willing to put the + first, you can make stuff go fast with minimum interference:
# Get extra commands available for Lisp-like math...
namespace path ::tcl::mathop
set c [+ $a $b]
If you're not a fan of Lisp-style prefix math, use expr. It's what most Tcl programmers do, after all.
set c [$a + $b]
Running the above command, you will get invalid command name "5" error message.
For mathematical operations, we should rely on expr only as Tcl treats everything as string.
set c [expr $a + $b]
In this case, the value of a and b is passed and addition is performed.
Here, it is always safe and recommended to brace the expressions as,
set c [expr {$a+$b}]
To avoid any possible surprises in the evaluation.
Update 1 :
In Tcl, everything is based on commands. It can a user-defined proc or existing built-in commands such as lindex. Using a bare-word of string will trigger a command call. Similarly, usage of [ and ] will also trigger the same.
In your case, $a replaced with the value of the variable a and since they are enclosed within square brackets, it triggers command call and since there is no command with the name 5, you are getting the error.
I am declaring a array in TCL say
set JDSU-12-1(key) element
parray JDSU-12-1
I am getting error saying JDSU is not a array
Even simple puts statement is not working
% puts $JDSU-12-1(key)
can't read "JDSU": no such variable
Is there any way i can declare array name with hyphen. I know _ works in array but not sure about hyphen
You can use special characters in Tcl variable names. You need the braces for those though:
% puts ${JDSU-12-1(key)}
element
You can even use $:
% set \$word "Hello world" ;# Or set {$word} "Hello world"
% puts ${$word}
Hello world
EDIT: Some reference:
beedub.com (Emphasis mine)
The set command is used to assign a value to a variable. It takes two arguments: the first is the name of the variable and the second is the value. Variable names can be any length, and case is significant. In fact, you can use any character in a variable name.
You can use almost any character for the name of a variable in Tcl — the only restrictions relate to :: as that is a namespace separator, and ( as that is used for arrays — but the $ syntax is more restrictive; the name it accepts (without using the ${…} form) has to consist of just ASCII letters, ASCII digits, underscores or namespace separators. Dashes aren't on that list.
The standard (and simplest) way of reading from a variable with a “weird” name is to use set with only one argument, as that happily accepts any legal variable name at all:
puts "the element is '[set JDSU-12-1(key)]'"
However, if you're doing this a lot it is actually easier to make an alias to the (array) variable name:
upvar 0 JDSU-12-1 theArray
puts "the element is $theArray(key)"
That's exactly how parray does it, though it uses upvar 1 because it is aliasing to a variable in the calling scope and not in the current scope.
Although you can use such special characters, you can only use a few when you try to access variables with $varname.
To quote the relevant section from the manual:
$name
Name is the name of a scalar variable; the name is a sequence of one or more characters that are a letter, digit, underscore, or namespace separators (two or more colons). Letters and digits are only the standard ASCII ones (0-9, A-Z and a-z).
$name(index)
Name gives the name of an array variable and index gives the name of an element within that array. Name must contain only letters, digits, underscores, and namespace separators, and may be an empty string. Letters and digits are only the standard ASCII ones (0-9, A-Z and a-z). Command substitutions, variable substitutions, and backslash substitutions are performed on the characters of index.
${name}
Name is the name of a scalar variable or array element. It may contain any characters whatsoever except for close braces. It indicates an array element if name is in the form “arrayName(index)” where arrayName does not contain any open parenthesis characters, “(”, or close brace characters, “}”, and index can be any sequence of characters except for close brace characters. No further substitutions are performed during the parsing of name.
There may be any number of variable substitutions in a single word. Variable substitution is not performed on words enclosed in braces.
Note that variables may contain character sequences other than those listed above, but in that case other mechanisms must be used to access them (e.g., via the set command's single-argument form).
I want to empathis the last paragraph a bit:
You are always able to read any variable with set varname:
set JDSU-12-1(key) element
puts [set JDSU-12-1(key)]
Unlike the ${varname} access, you can substitute a part of the variable name (in your case the array key), the entire variable, while set k "key"; puts ${JDSU-12-1($k)} does not work.
You can easily do that:
set set-var "test"
while accessing so ${set-var}
Like in most other programming languages, TCL variable must be alphanumeric starting with letter (A to Z, or _). Hyphen or dash (-) is not permitted as part of variable name, otherwise it would be confused with arithmetic minus or subtraction: there would be no difference between $x-1 as variable with name "x-1" or $x-1 as variable x minus 1.
Try this :)
subst $\{[subst ${conn}](phan)\}
Which version are you working ??
my tcl works.
% set JDSU-12-1(key) element
element
% parray JDSU-12-1
JDSU-12-1(key) = element
I have a HTML file with a few non-ASCII characters, say encoded in UTF-8 or UTF-16. To save the file in ASCII, I would like to replace them with their (SGML/HTML/XML) entity codes. So for example, every ë should become ë and every ◊ should become ◊. How do I do that?
I use Emacs as an editor. I'm sure it has a function to do the replace, but I cannot find it. What am I missing? Or how do I implement it myself?
I searched high and low but it seems Emacs (or at least version 24.3.1) doesn't have such a function. Nor can I find it somewhere.
Based on a similar (but different) function I did find, I implemented it myself:
(require 'cl)
(defun html-nonascii-to-entities (string)
"Replace any non-ascii characters with HTML (actually SGML) entity codes."
(mapconcat
#'(lambda (char)
(case char
(t (if (and (<= 8 char)
(<= char 126))
(char-to-string char)
(format "&#%02d;" char)))))
string
""))
(defun html-nonascii-to-entities-region (region-begin region-end)
"Replace any non-ascii characters with HTML (actually SGML) entity codes."
(interactive "r")
(save-excursion
(let ((escaped (html-nonascii-to-entities (buffer-substring region-begin region-end))))
(delete-region region-begin region-end)
(goto-char region-begin)
(insert escaped))))
I'm no Elisp guru at all, but this works!
I also found find-next-unsafe-char to be of value.
Edit: an interactive version!
(defun query-replace-nonascii-with-entities ()
"Replace any non-ascii characters with HTML (actually SGML) entity codes."
(interactive)
(perform-replace "[^[:ascii:]]"
`((lambda (data count)
(format "&#%02d;" ; Hex: "&#x%x;"
(string-to-char (match-string 0)))))
t t nil))
There is a character class which includes exactly the ASCII character set. You can use a regexp that matches its complement to find occurrences of non-ASCII characters, and then replace them with their codes using elisp:
M-x replace-regexp RET
[^[:ascii:]] RET
\,(concat "&#" (number-to-string (string-to-char \&)) ";") RET
So when, for example, á is matched: \& is "á", string-to-char converts it to ?á (= the number 225), and number-to-string converts that to "225". Then, concat concatenates "&#", "225" and ";" to get "á", which replaces the original match.
Surround these commands with C-x ( and C-x ), and apply C-x C-k n and M-x insert-kbd-macro as usual to make a function out of them.
To see the elisp equivalent of calling this function interactively, run the command and then press C-x M-: (Repeat complex command).
A simpler version, which doesn't take into account the active region, could be:
(while (re-search-forward "[^[:ascii:]]" nil t)
(replace-match (concat "&#"
(number-to-string (string-to-char (match-string 0)))
";")))
(This uses the recommended way to do search + replace programmatically.)
I think you are looking for iso-iso2sgml
Suppose I got this string to be expected: 100:~# or 100:~/tmp
This really means, I need to match the terminal prompt for a machine (which may or may not contain the path). Normally, with this regex pattern:
100:(~|/)(/+[a-zA-Z0-9]*)*#
It works for an input string such as: 100:~/foo/bar/foo/baz#
You can test it here: Regex Pal
But using Expect in TCL, I have to add -re to match such pattern. However, I am not allowed to do so. I tried the above pattern without regex, and it failed.
The current pattern for matching 100:~# or 100:~/tmp is very simple: 100:[~/]*#, and I was told that it is shell expression for matching strings, not regular expression. The 100:[~/]*# pattern means it matches anything between 100:[~/] (~ and / are optional) and #. The * character is meant to match anything, as opposed to the regular * which is zero or more in traditional regex sense.
What exactly is pattern matching expression in Expect withou -re flag?
They are known as "glob" patterns. They are styled after the shell's pattern matching. The documentation is here: http://tcl.tk/man/tcl8.5/TclCmd/string.htm#M40
*
Matches any sequence of characters in string, including a null string.
?
Matches any single character in string.
[chars]
Matches any character in the set given by chars. If a sequence of the form x-y appears in chars, then any character between x and y, inclusive, will match. When used with -nocase, the end points of the range are converted to lower case first. Whereas {[A-z]} matches “_” when matching case-sensitively (since “_” falls between the “Z” and “a”), with -nocase this is considered like {[A-Za-z]} (and probably what was meant in the first place).
\x
Matches the single character x. This provides a way of avoiding the special interpretation of the characters *?[]\ in pattern.