-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trouble identifying end-of-label-block during label-to-function conversion #236
Comments
i imagine this will be difficult i dont even like the existing conversion of label to function, because labels were not really "subroutines" despite the gosub syntax |
It will be a task. I played with it awhile and nearly re-wrote that entire function (lol) and had it all working fine, until I ran into the if block on one of the tests. That's when I realized masking will be required. I think once that is applied, it should be much easier and cleaner conversion function. I could be wrong... we will see. If it wasn't a challenge, it wouldn't be any fun. lol. |
Just thinking out loud. Couldn't the converter be made to format the V1 code, e.g. ... gosub Label1
MsgBox, % "global msg"
Return
Label1:
var := 5
if var < 5
return ; this return can fool any attempt to detect end of block
MsgBox, label/func msg
Return ; final return should be used to detect end of label
MsgBox Not part of Label1 This would make it easier to find the final return for the label? |
a final return isnt even necessary i dont think.. the code could theoretically run to the end of the file and what about situations like this Label1:
var := 5
Label2:
if var < 5
return ; this return can fool any attempt to detect end of block
MsgBox, label/func msg
Return ; final return should be used to detect end of label |
Lable1 drops through to Label2, so you are still only looking for the final return for both labels.. |
yes i know that, but i havent tried the existing conversion yet, but it seems the converter tries to convert labels to funcs does this end up as a nested func? gosub label1
gosub label2
return
Label1:
var := 5
Label2:
if var < 5
return ; this return can fool any attempt to detect end of block
MsgBox, label/func msg
Return ; final return should be used to detect end of label |
To maintain the same functionality as the V1 code, the algorithm to produce the V2 conversion would have to be somehow adjusted to produce ... Label1()
Label2()
MsgBox("global msg")
Return
Label1()
{ ; V1toV2: Added opening brace
global ; V1toV2: Made function global
var := 5
Label2()
} ; V1toV2: Added closing brace
Label2()
{ ; V1toV2: Added opening brace
global ; V1toV2: Made function global
if (var < 5)
return ; this return can fool any attempt to detect end of block
MsgBox("label/func msg")
Return ; final return should be used to detect end of label
} ; V1toV2: Added closing brace |
Just tried it... it does become nested functions. I have finished the label names fix (#238 unless one of you find an error - lol). I don't have power right now due to a storm but will dig into this soon. Should be interesting. But this will need to build on top of the label fix (once it is approved). |
GoSub MyFunc()
MsgBox, C
GoSub MyFunc2()
MyFunc():
MsgBox, A
MyFunc2():
MsgBox, B
Return Handling this one should be fun |
lmao |
Alternative conversion that fixes falling in problems GoSub, LabelA
MsgBox, After Label
LabelA:
MsgBox, In Label
Return In_LabelA := true
Goto("LabelA")
After_LabelA:
MsgBox("After Label")
LabelA:
MsgBox("In Label")
if (In_LabelA = true) {
In_LabelA := false
Goto("After_LabelA")
} It isn't the prettiest solution, but behaves identically (atleast in my testing) |
I didn't realize that v2 had retained the Goto command
This conversion makes clearer sense to my brain, compared to the function
conversion. Only thing I'd change is the variable name, something like
"return_from_LabelA"
I suppose the function conversion ends up equivalent functionality so it
might not matter in the end. I also don't know if other issues will arise,
and tend to prefer "if it ain't broke don't fix it"
Ping @Lexikos what do you think is better conversion?
…On Tue, Jul 9, 2024, 8:23 PM Banaanae ***@***.***> wrote:
Alternative conversion that fixes falling in problems
GoSub, LabelAMsgBox, After Label
LabelA:MsgBox, In LabelReturn
In_LabelA := trueGoto("LabelA")After_LabelA:MsgBox("After Label")
LabelA:MsgBox("In Label")if (In_LabelA = true) {
In_LabelA := falseGoto("After_LabelA")
}
It isn't the prettiest solution, but behaves identically (atleast in my
testing)
—
Reply to this email directly, view it on GitHub
<#236 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAOQBDHIEFVVRIED6BLI6ILZLR5JHAVCNFSM6AAAAABKPULC4GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMJZGE2DANZQGY>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Of course, if we want to take an opinionated stance, to
force/suggest/coerce users to migrate towards using functions rather than
labels, then that's a good reason to continue working on the function
conversion style
…On Tue, Jul 9, 2024, 8:33 PM Michael Wong ***@***.***> wrote:
I didn't realize that v2 had retained the Goto command
This conversion makes clearer sense to my brain, compared to the function
conversion. Only thing I'd change is the variable name, something like
"return_from_LabelA"
I suppose the function conversion ends up equivalent functionality so it
might not matter in the end. I also don't know if other issues will arise,
and tend to prefer "if it ain't broke don't fix it"
Ping @Lexikos what do you think is better conversion?
On Tue, Jul 9, 2024, 8:23 PM Banaanae ***@***.***> wrote:
> Alternative conversion that fixes falling in problems
>
> GoSub, LabelAMsgBox, After Label
> LabelA:MsgBox, In LabelReturn
>
> In_LabelA := trueGoto("LabelA")After_LabelA:MsgBox("After Label")
> LabelA:MsgBox("In Label")if (In_LabelA = true) {
> In_LabelA := falseGoto("After_LabelA")
> }
>
> It isn't the prettiest solution, but behaves identically (atleast in my
> testing)
>
> —
> Reply to this email directly, view it on GitHub
> <#236 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAOQBDHIEFVVRIED6BLI6ILZLR5JHAVCNFSM6AAAAABKPULC4GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMJZGE2DANZQGY>
> .
> You are receiving this because you commented.Message ID:
> ***@***.***>
>
|
Had to take a break from coding... hope to get back to this issue soon. |
I was thinking something like this might be easier... CombineLabelFunc1() ; redirect when referencing a top-most label
MsgBox("C")
MyFunc2__()
CombineLabelFunc1() ; redirect when referencing a top-most label
MyFunc__()
{ ; V1toV2: Added bracket
global ; V1toV2: Made function global
MsgBox("A")
} ; V1toV2: Added bracket in end of label (before next detected block)
MyFunc2__()
{ ; V1toV2: Added bracket
global ; V1toV2: Made function global
MsgBox("B")
Return
} ; V1toV2: Added bracket in end of label (before next detected block)
CombineLabelFunc1() ; redirected to here
{
myFunc__()
MyFunc2__()
} Should be easy to detect, and easy to implement, with no side-effects, and fairly clean. Although I have not fully tested all scenarios yet.
A > B > D > C > B > D > A > B > D |
You can't replace gosub with goto. Subroutines utilize a stack, with the return point (the line which called the subroutine) being variable. The only sane replacement for a label-based subroutine is a non-label-based subroutine: a function. Fall-through can often be viewed as an implicit tail call to the subroutine, since by definition, the subroutine ends with GoSub, LabelA
MsgBox, After Label
GoSub, LabelA ; Implied
Return ; Implied
LabelA:
MsgBox, In Label
Return LabelA()
MsgBox "After Label"
LabelA()
Return
LabelA() {
MsgBox "In Label"
} If A_ThisLabel was used to determine which label execution originally started at, it can be replaced by a function parameter used by the implicit tail calls. |
V1:
V2 (Converted):
V2 (Expected):
I ran into this while working on label name conversions (current project). I played with it and see that the labelToFunc conversion relies on detecting the beginning of hotkeys/hotstrings/functions to know where the previous block ends. This is very unreliable and should be fixed. I plan to tackle this issue next (after the label/func names).
Looks like the fix will require dipping into the masking bucket. I will need to add masking support for other blocks such as If/While/Loop/Switch, etc... Anything that can redirect the target label/func block using return/exitapp/ etc. Masking the sub-blocks temporarily should hide those conditional redirect commands and allow the the lableToFunc to reliably identify the final return/exitapp/exit within the label/func block. I have already have a very long If block needle and it works well for standard If/If-Else/Else, but will need to make sure all legacy IFs have been handle first. The needle handles most of the legacy IFs as well but I recently ran into a couple that were not detected. Might need to write a callout function that compliments the needle, or a dedicated function to make things easier. We will see how it goes.
The text was updated successfully, but these errors were encountered: