It is currently March 29th, 2024, 12:29 am

[BUG] Formula Parser within Inline Lua

Report bugs with the Rainmeter application and suggest features.
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

[BUG] Formula Parser within Inline Lua

Post by Yincognito »

Note: Although noticed by me when working with InputText measures and having a wide array of effects in other situations like mentioned below, this isn't actually about InputText, but about parsing formulas in inline Lua. Skip to my 3rd post here for a clear and simple example illustrating the behavior. I've modified the title of this thread and added this note here to update narrowing down the issue as more tests were performed.

I'm not sure if this is a bug, something that the Rainmeter team forgot to take into account when coding Rainmeter or the expected behavior / order of operations, but, while, for a numerical value in an InputText, using it directly in a formula works without issues, like:

Code: Select all

[SomeInputTextMeasure]
Plugin=InputText
...
Command1=[!SetVariable SomeVariable (Clamp($UserInput$,1,10))]
DynamicVariables=1
when trying the same (i.e. using $InputText$ directly in a formula) for an inline Lua piece, it doesn't work:

Code: Select all

[SomeInputTextMeasure]
Plugin=InputText
...
Command1=[&SomeLuaScript:SomeLuaFunction(3,($UserInput$-[#SomeOtherVariable]),5)]
DynamicVariables=1
and I have to use a temporary variable to do the operation first, followed by using that temporary variable in the inline Lua piece, instead of the direct formula:

Code: Select all

[SomeInputTextMeasure]
Plugin=InputText
...
Command1=[!SetVariable Difference ($UserInput$-[#SomeOtherVariable])][&SomeLuaScript:SomeLuaFunction(3,[#Difference],5)]
DynamicVariables=1
The 3 and 5 in the SomeLuaFunction are simply other arguments that I added since I have no idea if this behavior is the same when using just the single formula argument in the function, and I noticed this while using multiple argument functions (that are a bit too complex to write here, thus the simplified schematics which I'm sure you'd have no problems replicating). You can disregard the 3 and 5 arguments if you like, their only purpose is to better illustrate my usage scenario in which I noticed the above behavior.

For now I can live with using a temporary variable to do the above, so it's not a critical issue, but I would be interested to find out if this is "normal" or "expected" to happen.
Last edited by Yincognito on May 26th, 2021, 4:28 am, edited 2 times in total.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] InputText, Lua and Formula Parser

Post by death.crafter »

Yincognito wrote: May 25th, 2021, 2:08 pm I'm not sure if this is a bug, something that the Rainmeter team forgot to take into account when coding Rainmeter or the expected behavior / order of operations, but, while, for a numerical value in an InputText, using it directly in a formula works without issues, like:

Code: Select all

[SomeInputTextMeasure]
Plugin=InputText
...
Command1=[!SetVariable SomeVariable (Clamp($UserInput$,1,10))]
DynamicVariables=1
when trying the same (i.e. using $InputText$ directly in a formula) for an inline Lua piece, it doesn't work:

Code: Select all

[SomeInputTextMeasure]
Plugin=InputText
...
Command1=[&SomeLuaScript:SomeLuaFunction(3,($UserInput$-[#SomeOtherVariable]),5)]
DynamicVariables=1
and I have to use a temporary variable to do the operation first, followed by using that temporary variable in the inline Lua piece, instead of the direct formula:

Code: Select all

[SomeInputTextMeasure]
Plugin=InputText
...
Command1=[!SetVariable Difference ($UserInput$-[#SomeOtherVariable])][&SomeLuaScript:SomeLuaFunction(3,[#Difference],5)]
DynamicVariables=1
The 3 and 5 in the SomeLuaFunction are simply other arguments that I added since I have no idea if this behavior is the same when using just the single formula argument in the function, and I noticed this while using multiple argument functions (that are a bit too complex to write here, thus the simplified schematics which I'm sure you'd have no problems replicating). You can disregard the 3 and 5 arguments if you like, their only purpose is to better illustrate my usage scenario in which I noticed the above behavior.

For now I can live with using a temporary variable to do the above, so it's not a critical issue, but I would be interested to find out if this is "normal" or "expected" to happen.
I don't think the fault is in Rainmeter at all. Input text being a C++ plugin(most probably) it returns a string value. So it can not directly be added to an integer. So if you try it even without lua for example Command1=[!Log "$UserInput$+3"], it would log "20+3" as a string. You get the gist.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] InputText, Lua and Formula Parser

Post by Yincognito »

death.crafter wrote: May 25th, 2021, 3:03 pm I don't think the fault is in Rainmeter at all. Input text being a C++ plugin(most probably) it returns a string value. So it can not directly be added to an integer. So if you try it even without lua for example Command1=[!Log "$UserInput$+3"], it would log "20+3" as a string. You get the gist.
Well, being a fault or not and its location depends, in this case. You're right that the InputText measure's return value is a string ... BUT the formula parser in Rainmeter (which is triggered by encountering the "(" character in most options and bangs - that's why you have to always enclose formulas between round brackets in Rainmeter in the first place) automatically converts a numerical string into the corresponding number in the appropriate moment (i.e. at usage), as long as it's a part of a valid (formula). Try for example, Command1=[!SetVariable Sum "(20+3)"][!Log "[#Sum]"], Command1=[!SetVariable Sum ("20"+3)][!Log "[#Sum]"] or even (similar to what I mentioned already above) [!SetVariable Sum ($UserInput$+3)][!Log "[#Sum]"] and you'll get 23 in all cases - sure, it's not that directly done, but strings are being used. Similarly, you can even use a string in the Formula option of a Calc measure and, as long as that string is a valid (formula), the measure will yield the actual result.

The question here is more or less of what operations are going on and their order. If the formula parser would happen before the Lua parsing in the inline Lua (it doesn't seem the case, I'm not even sure it happens in the first place for the arguments of an inline Lua function, maybe because inline Lua is basically a section variable and not a bang), then [&SomeLuaScript:SomeLuaFunction(3,($UserInput$-[#SomeOtherVariable]),5)] will be parsed as [&SomeLuaScript:SomeLuaFunction(3,TheSaidOperationResult,5)], where TheSaidOperationResult is the numerical result of the operation. If the formula parser doesn't happen or it happens after the Lua parsing in the inline Lua, then obviously it would explain the behavior and why the stringified formula is passed as the argument instead of its result.

Another proof that this isn't related to the fact that string values are used - I just tried [&SomeLuaScript:SomeLuaFunction(3,(3+7),5)] and got nothing. This means that Rainmeter doesn't convert the (3+7) formula (no strings involved this time, right?) to 10 beforehand, in order to pass the result as the 2nd argument to the aforementioned SomeLuaFunction. I'm just trying to understand if this is normal / expected or not. :confused:

And some excerpt from the manual:
The types of parameters that can be passed to the Lua function() are:

Number Any number literal, formula or variable that resolves to a number.
String Any 'string' literal, or variable that resolves to a string, enclosed in 'single quotes'.
Boolean One of either true or false.
The above (3+7) for example, fits right into the 1st category in the list, i.e. "any number literal, formula or variable that resolves to a number".
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] InputText, Lua and Formula Parser

Post by Yincognito »

Ok, this is definitely a bug, at least according to the note in the manual, that says:
The types of parameters that can be passed to the Lua function() are:

Number ... Any number literal, formula or variable that resolves to a number.
String ...... Any 'string' literal, or variable that resolves to a string, enclosed in 'single quotes'.
Boolean ... One of either true or false.
Further simplifying the test case, consider...

Script.lua, placed in the @Resources folder of the skin:

Code: Select all

function Sum(a, b)
  local result = a + b
  print(result)
  return result
end
Test.ini, aka the skin:

Code: Select all

[Variables]

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=47,47,47,255

---Measures---

[Script]
Measure=Script
ScriptFile=#@#Script.lua
UpdateDivider=-1

---Meters---

[MeterTest]
Meter=STRING
X=0
Y=0
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text="Test = [&Script:Sum(3,3+7)]"
UpdateDivider=-1
DynamicVariables=1
The Lua function sums up its two arguments, so it should print 13 (aka the result of the 3+(3+7) operation) both in the Log (via Lua's print() function) and in the skin, via the Text option of [MeterTest]. It does not though:
- if [&Script:Sum(3,3+7)] is used, it prints 6 (disregarding the +7 part)
- if [&Script:Sum(3,(3+7))] is used, it prints 3 (disregarding the 2nd argument altogether)
This is definitely related to my last post here, on a different issue (but also involving formulas). There, I thought it was related to the use of #CURRENTSECTION#, but it looks like it's more than that.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] InputText, Lua and Formula Parser

Post by death.crafter »

Yincognito wrote: May 25th, 2021, 5:04 pm Ok, this is definitely a bug, at least according to the note in the manual, that says:


Further simplifying the test case, consider...

Script.lua, placed in the @Resources folder of the skin:

Code: Select all

function Sum(a, b)
  local result = a + b
  print(result)
  return result
end
Test.ini, aka the skin:

Code: Select all

[Variables]

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=47,47,47,255

---Measures---

[Script]
Measure=Script
ScriptFile=#@#Script.lua
UpdateDivider=-1

---Meters---

[MeterTest]
Meter=STRING
X=0
Y=0
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text="Test = [&Script:Sum(3,3+7)]"
UpdateDivider=-1
DynamicVariables=1
The Lua function sums up its two arguments, so it should print 13 (aka the result of the 3+(3+7) operation) both in the Log (via Lua's print() function) and in the skin, via the Text option of [MeterTest]. It does not though:
- if [&Script:Sum(3,3+7)] is used, it prints 6 (disregarding the +7 part)
- if [&Script:Sum(3,(3+7))] is used, it prints 3 (disregarding the 2nd argument altogether)
This is definitely related to my last post here, on a different issue (but also involving formulas). There, I thought it was related to the use of #CURRENTSECTION#, but it looks like it's more than that.
I see. In that case it's probably a bug in implementation of inline Lua. When Lua function doing mathematical operations is given a string as argument it throws an error. In this case the wrong argument is just skipped. The latter part gives a hint about it being intentional but it definitely should be flagged as a bug.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] InputText, Lua and Formula Parser

Post by Yincognito »

death.crafter wrote: May 25th, 2021, 6:37 pm I see. In that case it's probably a bug in implementation of inline Lua. When Lua function doing mathematical operations is given a string as argument it throws an error. In this case the wrong argument is just skipped. The latter part gives a hint about it being intentional but it definitely should be flagged as a bug.
Right. Either a bug or incorrect notes in the manual. What makes me think it "should" be considered a bug and not some mistake in the manual notes is that the test scenario has a huge range of applications which wouldn't be possible otherwise. In short, the formulas aren't properly resolved before being sent to the Lua interpreter as function arguments. Which is strange, because Lua itself is able to resolve this kind of simple operations (probably not the more complex ones involving, say, Rainmeter section variables, hence why a similar Rainmeter ability would come handy and be perfectly logical), illustrated if you add an additional "test" function:

Code: Select all

function Try()
  return Sum(3, 3+7)
end
to the Lua script above, and make:

Code: Select all

Text="Test = [&Script:Try()]"
in [MeterTest] in the skin above. The result will be the desired 13, irrespective if you use return Sum(3, 3+7) or return Sum(3, (3+7)) in the Try() function, so even Lua is perfectly able to resolve formulas in the function arguments "on the fly". Of course, this shouldn't be necessary as long Rainmeter resolves the formula before sending the result as a function argument to the Lua interpreter, but it's nevertheless a "proof of concept", so to speak.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] InputText, Lua and Formula Parser

Post by death.crafter »

Yincognito wrote: May 25th, 2021, 7:22 pm Right. Either a bug or incorrect notes in the manual. What makes me think it "should" be considered a bug and not some mistake in the manual notes is that the test scenario has a huge range of applications which wouldn't be possible otherwise. In short, the formulas aren't properly resolved before being sent to the Lua interpreter as function arguments.
Well I don't know if it matters in this case but another thing is formulas are not parsed while being used inside square brackets [].

For example if a section name is [2] and you need a previous section's option say H of [1]. Then you can not use [(#CURRENTSECTION#-1):H] or even [(2-1):H] for that matter. The reason being Rainmeter sections can be named potentially anything.

But then again if you use [(2-1)] as a section name and then do the exact thing as before you still wouldn't get anything. Which is a rather concerning factor.

If they make changes to their regex or something that they use to stop parsing at certain points (if possible), the part after the : can be parsed as well.

And about $UserInput$, it doesn't parse it when used as [!Log ($UserInput$+3)] probably because of the order of events. When after ( it doesn't get an number but $UserInput$, it considers it as a string. Though $UserInput$ is a command for InputText, for Rainmeter it's still a string.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] InputText, Lua and Formula Parser

Post by Yincognito »

death.crafter wrote: May 26th, 2021, 2:46 am Well I don't know if it matters in this case but another thing is formulas are not parsed while being used inside square brackets [].

For example if a section name is [2] and you need a previous section's option say H of [1]. Then you can not use [(#CURRENTSECTION#-1):H] or even [(2-1):H] for that matter. The reason being Rainmeter sections can be named potentially anything.

But then again if you use [(2-1)] as a section name and then do the exact thing as before you still wouldn't get anything. Which is a rather concerning factor.

If they make changes to their regex or something that they use to stop parsing at certain points (if possible), the part after the : can be parsed as well.
Yes, native Rainmeter can't do that at the moment, but my Lua+Rainmeter solution here (or here) can do it.
Script.lua, in the @Resources folder of the skin:

Code: Select all

function SectionIndex(section, occurrence, formula)
  local indexes = {}
  for index in section:gmatch('%d+') do table.insert(indexes, index) end
  if occurrence == 'first' then occurrence = 1 elseif occurrence == 'last' then occurrence = #indexes end
  return tostring(SKIN:ParseFormula(string.gsub(formula, '<x>', tostring(indexes[tonumber(occurrence)] or '0')))) or '0'
end
Test.ini, aka the skin:

Code: Select all

[Variables]
; Inline Lua Usage: [&Script:SectionIndex(SomeSection,SomeOccurrence,SomeFormula)]
; SomeSection     = the name of any section, enclosed by ' (apostrophes), like: 'Measure1' or 'Meter1'
; SomeOccurrence  = the desired occurrence of an index, like: 3 or '5' or 'first' or 'last'
; SomeFormula     = the Rainmeter formula applied to the original <x> index, like: '(<x>)' or '(<x>+1)' or '(Sqrt(<x>))'
; Section variables need to use their nested form, like: [&Script:SectionIndex('[#Section]',[#Occurrence],'[#Formula]')]

; Applicability In:
; - Simulation of a CURRENTSECTIONINDEX "built-in" variable, "last" index scenario, to avoid repeating inline Lua syntax
CURRENTSECTIONINDEX=[&Script:SectionIndex('[#*CURRENTSECTION*]','last','(<x>-1)')]
; - Alternative equivalent using inline Lua in the skin code: [&Script:SectionIndex('[#CURRENTSECTION]','last','(<x>)')]

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=47,47,47,255

---Measures---

[Script]
Measure=Script
ScriptFile=#@#Script.lua
UpdateDivider=-1

---Meters---

[1]
Meter=String
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text="Something"
DynamicVariables=1

[2]
Meter=String
Y=[[#CURRENTSECTIONINDEX]:H]
; Alternative inline Lua syntax
;Y=[[&Script:SectionIndex('[#CURRENTSECTION]','last','(<x>-1)')]:H]
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=16
AntiAlias=1
Text="Something Else"
DynamicVariables=1
The code effectively puts [2] under [1], by using the [1:H] value obtained with the help of the script.
Check the linked thread for more info on how it works, but bear in mind that this is affected too by the current topic's InputText, Lua and Formula Parser problem (which is actually just a Formula Parser in Inline Lua problem, as already proven) - which is why I said earlier that this and another thread are related in that regard.
death.crafter wrote: May 26th, 2021, 2:46 amAnd about $UserInput$, it doesn't parse it when used as [!Log ($UserInput$+3)] probably because of the order of events. When after ( it doesn't get an number but $UserInput$, it considers it as a string. Though $UserInput$ is a command for InputText, for Rainmeter it's still a string.
Maybe, but I've tried "stringifying" the 2nd element in the operation (i.e. 3 in this case) - or even swapping the elements - with the same result, earlier in my tests. Meaning it doesn't necessarily depend on whether it encounters a string right after the opening bracket.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1399
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] InputText, Lua and Formula Parser

Post by death.crafter »

Yincognito wrote: May 26th, 2021, 4:11 am Yes, native Rainmeter can't do that at the moment, but my Lua+Rainmeter solution here (or here) can do it.


Maybe, but I've tried "stringifying" the 2nd element in the operation (i.e. 3 in this case) - or even swapping the elements - with the same result, earlier in my tests. Meaning it doesn't necessarily depend on whether it encounters a string right after the opening bracket.
Ahh there is a solution to this problem. I was trying to do this in a previous project of mine which didn't work.

I got your point tho.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] InputText, Lua and Formula Parser

Post by Yincognito »

death.crafter wrote: May 26th, 2021, 2:46 am Well I don't know if it matters in this case but another thing is formulas are not parsed while being used inside square brackets [].

For example if a section name is [2] and you need a previous section's option say H of [1]. Then you can not use [(#CURRENTSECTION#-1):H] or even [(2-1):H] for that matter.
On a second thought, I see what you mean: just like [(2-1):H] doesn't work in section variables, [&SomeLuaScript:SomeLuaFunction(3,(2-1),5)] doesn't work either when it comes to inline Lua (which is basically a section variable too - although resolving function arguments before sending the result to the Lua interpreter should happen, which would solve the problem when it comes to inline Lua). I guess we'll have to wait for the developers to weigh in on the matter on this one...
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth