|
Martaigne Wanderer
Joined: 05 Jan 2002 Posts: 88 Location: Atlanta, GA
|
Posted: Tue Jul 13, 2010 2:35 am
[3.22] Strange unmatched braces bug |
I just upgraded from 3.20 to 322 today, and code that worked fine in 3.20 was giving me issues. I've sorted out the cause.
Code: |
#SHOW {%ansi(green)...done. Thank you for your patience.%ansi(reset)} |
...threw the unmatched braces error.
Code: |
#SHOW {%ansi(green)Done. Thank you for your patience.%ansi(reset)} |
...fixed it.
For some reason having periods after the closing parens in the first %ansi call blew the script. |
|
|
|
GeneralStonewall Magician
Joined: 02 Feb 2004 Posts: 364 Location: USA
|
Posted: Tue Jul 13, 2010 3:03 am |
It probably interpreted it as something like db.key or item.list. Using concat should fix the issue.
|
|
|
|
charneus Wizard
Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Tue Jul 13, 2010 9:58 am |
Or just putting a ~ in front of the first '.'... quicker that way. GS is probably right on this, though, but it should be a bug as there is no variable being called with @...
Charneus |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Tue Jul 13, 2010 2:26 pm |
You should try using MXP coloring. It's a lot nicer with more color options and you can do things like strong, italics, underline, and so on.
It's really easy.
Code: |
#show {<color green>blah blah</color>} |
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Jul 13, 2010 5:59 pm |
Quote: |
but it should be a bug as there is no variable being called with @... |
CMUD was recently changed to allow the . after a function call so that you could do %db(table,key).key
So when the CMUD parser sees the . after the %ansi call, it thinks that is a valid %function.key syntax. The parser does not look ahead to see that there is another "." following it. But just looking ahead doesn't fix the problem because you'd still have the issue with something simpler like this:
Code: |
#show {%ansi(green).Done} |
There is no way for CMUD to know that ".Done" should not be parsed as a key reference for the %ansi function. Obviously %ansi will never return a table result, but many other functions can.
I have seen this "feature" cause other problems too. I may need to rethink whether to allow the %function.key syntax. Seems like it might cause more problems that it is worth. |
|
|
|
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Tue Jul 13, 2010 8:30 pm |
I don't suppose you can only allow it on specific functions which _can_ return a table? I suppose the code can't be easily be made smart enough to only do it on certain functions, and could lead to confusion, as well.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Jul 13, 2010 10:19 pm |
No, that doesn't really work either and I really hate to make the parser aware of the actual function being executed (that breaks the modularity between the lexer and the parser). Also, somebody is bound to do something like this:
Code: |
#SHOW {Value is %db(table,Key)...Done} |
and have no idea that the "." should work any differently with %db compared to any other function. |
|
|
|
charneus Wizard
Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Tue Jul 13, 2010 10:50 pm |
The problem with that logic, Zugg, is that while it /is/ after a function call, it's also after a function that has properly closed its arguments with parentheses... and since CMUD wouldn't allow %db(@Stuff).key), why in the world would it just think 'Oh, %ansi(green)... must be a %db call!'?
Just curious on this because it doesn't make too much sense to me otherwise.
Charneus |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Wed Jul 14, 2010 12:19 am |
About the only thing I see having a dot notation on functions be useful for is COM calls. It seems like this is another of those cases where implicit concat is getting in the way. Perhaps a better error message would be enough to solve that part of the problem.
There are a few other things that could help in sorting out the use of dot with with functions. First consider how it works with variables.
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<alias name="test" copy="yes">
<value>a=1
#SHOW {@a.d}
#SHOW {@{a}.d}
#SHOW {@{a.d}}
#SHOW {@b.e}</value>
</alias>
</cmud> |
When you use try that alias you will see the first line output is blank, the second has properly split the reference making the '.d' be a concat, but the third line is very telling. The {} provide the means to state what should be done.
The fourth line is just confusing; there is no variable by the name of "b", and the '.e' becomes a late concat. The DOT instruction already knows something about falling back to a text output.
Next we can consider looking at a function
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<alias name="test2" copy="yes">
<value>#SHOW {%item("a|b|c",2).x}
#SHOW {%item("a|b|c",2)..x}
#SHOW {%item("a|b|c",2)...x}
#SHOW {%{item}("a|b|c",2).x}
#SHOW {%{item("a|b|c",2)}.x}
</value>
</alias>
</cmud> |
Again the first line produces a blank output, the second line produces "b..x". Looking at the compiled code we see that there is no use of the DOT instruction for that line; something in the parsing already knows that ".." can't be a valid dot notation. Then we get to the third line and the compiled code says this
Code: |
0228 STR '..'
0240 STR 'x'
0252 DOT
0260 CONCAT |
That shouldn't really be the case, it should be STR '...x';CONCAT
The fourth and fifth lines in the test2 alias points out another possible parsing problem %{function} sort of works, but doesn't. The use of braces in such a fashion is defined for variables under @ and predefined variables under %, but becomes confused when being handed a function with parameters inside the braces.
I think sorting out the problem with "...", and probably higher numbers of periods in a row; and expanding how the %{func(params)} work are required for fixing how the . should work with functions.
The final answer is explified by the usage with a variable "#SHOW @{var.key}". Having functions able to use DOT is fine, just make it required that the user explicitly states that intention with "%{func(params).key}"; no braces should mean a concat. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Wed Jul 14, 2010 3:09 pm |
Charneus, the point is that Cmud _does_ now allow %db(@table,key).otherkey. This works if the value returned by the first %db() is itself a stringlist or key-value list. It also only works (I believe) in cases where the @ is not required in front of a variable name. This is part of the new json stuff.
Vijilante, the first line is blank because there is no key "d" in the variable "a". The second line prints as it does because 1 cannot be a variable name, and besides there is no @ before the 1, so it just concatenates the 1 and .d. The third prints nothing because there is no variable named "a.d", and "a.d" does not resolve into anything else because there is no amperand before the a to make it a variable name. @{@a.d} would show something, if the variable a had a key d, whose value was the name of another variable. I'm not sure what you are trying to show with this script.
Your second script does seem to show an oddity between two dots and three dots. The issue of using %{} is because you can actually have a variable function name. Say you have a variable "a" whose value is "time". If you do: "#show %{@a}", you get the same result as if you did "#show %time". Your proposal would break that. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Jul 14, 2010 5:28 pm |
Yeah, Rahab is correct about the problems trying to use the %{func(param).key} syntax. That is used for indirect execution and not really for what we are trying to do here.
But Vijilante's test results were quite interesting. I didn't expect the case with two dots to work with three dots failing. I thought the code just scanned the characters before the dot to look for a valid @ or % function reference. I think it also stops looking when it sees a (param) list since that often indicates a COM reference.
Definitely some issues for me to look at in this part of the parser. It's very complex and difficult to work on without having side effects that break other stuff, so I have to be really careful with it.
In fact, the line that checks for the % character and allows the dot after a function was previously there but commented out. Almost like I had played with this in the past at some point but then decided it just didn't work. Too bad I don't remember why.
In the case of variables, I think the DOT operator is doing some stuff at run-time where if the variable doesn't exist, it falls back to doing an append. I might be able to do something similar with functions where it actually tests the value on the runtime stack to see if it's a database variable or not. That would make it more consistent with how variables work, even though I tend to dislike parsing syntax that changes behavior at runtime. But since I already do it with variables (and I'm not changing that), then I might as well do the same thing for functions. |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Wed Jul 14, 2010 10:11 pm |
Rahab, I don't wish to seem argumentative, but there are a few things you missed. Here try this one:
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<alias name="test" copy="yes">
<value>#addkey a {b} {2}
#SHOW {@{a}.b}
#SHOW {@{a.b}}</value>
</alias>
</cmud> |
Now look at the compiled code for the alias. You will see that @{a.b} is compiled as "VARREF a.b > (class untitled)". It also properly displays as "2". The @{a}.b compiles as a CONCAT because the use of braces is stating that the variable name is "a". Braces are delimiters.
Looking at functions again I will use a different set of examples that demonstrate indirect functions. Also lets deepen the pit some more by putting user function in the mix.
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<func name="y" copy="yes">
<value>#SHOW got here
#RETURN {%db(%1,%2)}</value>
</func>
<alias name="test2" copy="yes">
<value>a="b=4|c=""1|2|3"""
x="db"
#SHOW {1 %db(@a,c)}
#SHOW {2 %{db}(@a,c)}
#SHOW {3 %{@x}(@a,c)}
#SHOW {4 %{@x(@a,c)}}
#SHOW {5 @{y(@a,c)}}
#SHOW {6 @{y}(@a,c)}</value>
</alias>
</cmud>
|
I can't include this one because the it incorrectly reports as mismatched braces. #SHOW {%{{@x}(@a,c)}}
Both of the last 2 fail, one of them should work. User functions aren't quite happy with braces either.
The use of braces are delimeters, look really closely at the examples above. The ones that use indirection have an additional interpretation character in them, and need the extra delimiters to say what part goes with which @ or %. I am really trying to say is all of these mean something different even if some of them produce the same results.
%{func}(param).key %{func(param)}.key %{func(param).key} %{@something(param)} %{@{something}(param)} %{@{somthing(param)}} %{@something}(param)
Edit: Two more things %{@{something}}(param)(param) would be the currently valid and working syntax, but is somewhat confusing about what the (param) parts should be doing. %{@{something(param)}(param)} has no confusion about what the param parts are.
We could always just erect the SEP field around the braces stuff. %func(param)".key" always works as expected. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Aug 18, 2010 10:21 pm |
Btw, I have dealt with this issue by checking the %function to see if it can return a DB variable. So %list(string).key is allowed, but %ansi(string).key will properly perform the implicit concat of the ".key" string.
I also fixed the issue with multiple dots. I also fixed another related bug having a space (or other nonvalid key value) after the dot.
So the command in the original post will work in the new version. And the only time you'll have trouble with explicit concat is using .key after a function that can return a list or table. Here is the list of functions that can return a list/table:
additem
addkey
db
dbitems
dbkeys
dbvalues
delitem
delkey
delnitem
dups
item
json
list
pop
push
replaceitem
sort |
|
|
|
Derar Novice
Joined: 09 Sep 2006 Posts: 44
|
Posted: Thu Aug 19, 2010 1:57 pm |
Off the top of my head, %countlist should probably be added to the list of viable db functions.
Can't think of any others at the moment. |
|
|
|
Tech GURU
Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Thu Aug 19, 2010 3:25 pm |
I think your mistaken Derar. This isn't a list of functions that can use db variables but a list of function that can return a list or table. %countlist will always return a number.
|
|
_________________ Asati di tempari! |
|
|
|
Derar Novice
Joined: 09 Sep 2006 Posts: 44
|
Posted: Fri Aug 20, 2010 2:51 am |
I think you're thinking of %numitems, actually.
From #HELP countlist:
"Count the number of times each item appears in a string list and return a database record with the items as key properties, and the count of each item as the value of the key." |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri Aug 20, 2010 4:49 pm |
Yep, Derar is correct. I've added %countlist to the list.
|
|
|
|
|
|