Sign in to follow this  
Followers 0
czardas

Strange Syntax

25 posts in this topic

#1 ·  Posted (edited)

While playing around with an edit control I discovered I could select and execute several lines of AutoIt in sequence using the function Execute. There appear to be several drawbacks to using such a primative method, but I only want basic functionality - nothing fancy. The main problem seemed to be declaring variables. I started out by trying a few things, but was never satisfied with the overcomplexity introduced by parsing the code.

Anyway after several attempts I decided to abandon declaring variables in the conventional manner and opted for using Assign. I couldn't get several operators to work neither (the ones which include the equals sign), but I managed to find a compromise. The veterans around here might have something to say about this. Anyway the code that seems to work with Execute looks really strange.

Example Edit Control Contents:

Assign("isThisReal","hello")
Assign("isThisReal",$isThisReal & " world")
msgbox(0, "", $isThisReal)

Assign("number",10)
Assign("number",$number^3 + 24)
$number

$isThisReal & " " & $number

Result:

Assign("isThisReal","hello") ==> 1
Assign("isThisReal",$isThisReal & " world") ==> 1
msgbox(0, "", $isThisReal) ==> 1

Assign("number",10) ==> 1
Assign("number",$number^3 + 24) ==> 1
$number ==> 1024

$isThisReal & " " & $number ==> hello world 1024

You will notice some of the code is not even correct AutoIt syntax, but it runs. Perhaps someone can contribute some valuable input. I wonder how the current alpha release will perform with the Assign function, because the dollar sign isn't always there. :D

Edited by czardas

Share this post


Link to post
Share on other sites



Ok, we talked a little bit on MSN and I understand the confusion. For the sake of completeness, I will share the keynotes of our chat here. The most important part is: Execute evaluates expressions. An expression can always work in these contexts:

If <expression> Then
While <expression>
For <expression> To <expression> Step <expression>

In the chat you gave me two examples:

Execute("Dim $myvar = 10")
Execute("$myvar += 1")

Both of those when put inside an If-statement, will yield a syntax error. Since they are both statements, those examples will not work with Execute. The confusion grows, as expressions and statements are sometimes interchangeable. You'd think an example like this would work:

$herp = 0
Execute("$herp = 5")
MsgBox(0, "", $herp)

Since you execute the line "$herp = 5", you'd expect it to work like an assignment. However, Execute will always interpreter that as being the expression where 5 needs to be compared to whatever the value of $herp is. It's the technical equivalent to doing this:

If $herp = 5 Then

AutoIt won't assign values to variables inside an expression, because it will always do a comparison instead (unlike some other languages). However, with a bit of AutoIt knowledge, you can get a lot done with Execute for the price of a bit more verbosity.

#1: Assignment

The assignment example from above can be made to work. Function calls are expressions, and inside functions are several statements. You can do anything, provided enough helper functions. The assignment example works like so:

$herp = 0
Execute("_Assign($herp, 5)")
MsgBox(0, "", $herp)

Func _Assign(ByRef $var, $val)
    $var = $val
EndFunc

#2 If-statements with expression(s) as branches

It's a rather special case of if-statement, but combined with other tricks you can write code like the following:

If $a = 123 Then
    $b = 456
Else
    $c = 789
EndIf

You'd do that with the built-in AutoIt function _Iif from Misc.au3. You'd write it like so:

_IIf($a = 123, _Assign($b, 456), _Assign($c, 789))

Wrap that inside an Execute call and you're good to go.

Share this post


Link to post
Share on other sites

Is this pseudo code that is supposed to be highlighting something? Because as written, it doesn't run for me.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Great responce Manadar. Thanks a lot for the useful tips. I find it very interesting. I'm very glad that I asked about this.

@BrewmanNH

It's half pseudocode and half real, but you need to add some additional code to make it run in SciTE: :D

#include <Array.au3>

Dim $sString = _ ; Selected Text sent to function
'Assign("isThisReal","hello")' & @CRLF & _
'Assign("isThisReal",$isThisReal & " world")' & @CRLF & _
'msgbox(0, "", $isThisReal)' & @CRLF & _
@CRLF & _
'Assign("number",10)' & @CRLF & _
'Assign("number",$number^3 + 24)' & @CRLF & _
'$number' & @CRLF & _
@CRLF & _
'$isThisReal & " " & $number'

MsgBox(0, "Selected Text", $sString)
MsgBox(0, "Replacement Text", _ExecuteInSequence($sString))

Func _ExecuteInSequence($sString)
Local $asCode = StringSplit($sString, @CRLF, 1)
For $i = 1 To $asCode[0]
     If StringLen($asCode[$i]) Then
         $asCode[$i] &= " ==> " & Execute($asCode[$i])
         If @error Then
             MsgBox(0, "Oops", @error)
             Exit
         EndIf
     EndIf
Next
Return _ArrayToString($asCode, @CRLF, 1)
EndFunc

Edit

Silly mistakes in the code. The idea is to be able to select a few lines of code from within a larger piece of text and just execute those expressions. I will mainly use it for mathematical formulas, but it's interesting to know how far you can go with it. The expressions execute perfectly well in the half built GUI I'm working on. It will be an advanced feature.

Edited by czardas

Share this post


Link to post
Share on other sites

OMG I just relised that I can delete the Edit control by executing the code it contains. The user could accidentally end up rewriting parts of the program. :D That's insane - I need to think about this.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Look at Au3Int. I wrote a lot of code (and so did wraithdu) to work around these exact problems:

I don't think manadar's if test is quite right though:

#include<misc.au3>

Local $a, $b, $c

$a = 123

ConsoleWrite(StringFormat("Before: %i, %i, %in", $a, $b, $c))

_IIf($a = 123, _Assign($b, 456), _Assign($c, 789))

ConsoleWrite(StringFormat("After: %i, %i, %in", $a, $b, $c))

Func _Assign(ByRef $var, $val)
    $var = $val
EndFunc

It executes both branches. Quick solution is:

#cs

If exprA Then
    exprB
Else
    exprC
EndIf

#ce

$exprA = "$a = 123"
$exprB = "_Assign($b, 456)"
$exprC = "_Assign($c, 789)"

Execute(_IIf(Execute($exprA), $exprB, $exprC))

Edit: Just reread manadars post. He did say "Wrap that inside an Execute call and you're good to go." so this may have been what he meant all along.

Edited by Mat

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Thanks Mat. That appears to be far more extensive than what I have in mind, but I'll definately take a look. I really want to avoid too many helper functions if I can. However I have mastered declaring 1D arrays using Execute. The idea is that Execute is just an option in a menu of about 50 other options. It's not intended to be an AutoIt interpreter.

Assign("aFor", StringSplit(_StringRepeat(",",2), ","))
_AssignElement($aFor, 1, "Hello ")
_AssignElement($aFor, 2, "World")
_AssignElement($aFor, 3, $aFor[1] & $aFor[2])
_ArrayDisplay($aFor)

Requires the Helper function:

Func _AssignElement(ByRef $aArray, $iElement, $vVal)
    $aArray[$iElement] = $vVal
EndFunc

I'll probably avoid using any functions that are not documented in the AutoIt Help File. So arrays may end up as constant variables declared using StringSplit. Not very flexible but an advanced AutoIt user would most likely type:

Run("C:Program FilesAutoIt3SciTESciTE.exe")

Knowing the limitations of the menu item on the application I am making: Sellected > Execute > AutoIt Expression.

Edited by czardas

Share this post


Link to post
Share on other sites

Edit: Just reread manadars post. He did say "Wrap that inside an Execute call and you're good to go." so this may have been what he meant all along.

Actually, it was a thinking error. When I was typing that post I had to leave in a hurry by the end of it and didn't test it out. I knew it was possible, and this is the first that came to mind. : )

My next post (this one) was going to suggest writing his own domain specific language. That seems to be by far the easiest and most flexible route. If that was too much, then I was going to suggest Au3Int as well. Does that have an Execute like function that works for statements as well?

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Write another language LOL. This is just a text editor with some whacky additional features like with this Execute AutoIt Expression thing and lot's of useful string functions. I just want to select text and hit a hotkey to transform it to whatever eg sort a list.

Having said all that, there's definately food for thought here. :D

Edited by czardas

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

I will probably end up with some sort of compromise. It's certainly useful to try out these ideas; as a vehicle for learning, if nothing else. If I want to use loops then I will probably be forced to compromise. For the time being I just want to get the rest of the program working. It can always be updated and several types of code execution could be implimented. I made AutoIt Expression a submenu of the Execute menu in case I add some more functionality in the future. For example display html in seleced browser.

I like the idea of having several languages within the same document and being able to select parts of the document with the mouse and only run the code you select.

Edited by czardas

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Hmm maybe I'll have to add a disclaimer. Anyhow, there will be clearly limited functionality as I intend to use it and, I doubt people will try to use it for anything other than writing functional pseudo code (I know it sounds like a contrdiction) to save time under certain circumstances. I am contemplating the possibly of creating an antiscript kiddie filter. :D

Edited by czardas

Share this post


Link to post
Share on other sites

As with anything, you should always sanitize user input. It applies on web pages and just as much in programs.

Share this post


Link to post
Share on other sites

I had not overlooked this, but thanks. It is currently under consideration.

Share this post


Link to post
Share on other sites

Whether you want to call it that or not you are writing a simple language if you intend to sanitize user input. If you don't sanitize user input then you have knowingly written a security hole.

1 person likes this

Share this post


Link to post
Share on other sites

I can see their being potential issues, though I don't have your degree of insight. For example deleting the edit in which the code was meant to be running earlier should not have been possible. Like I said, I only need a few simple functions, some maths, boolean, binary and a few macros. I reckon I will find a secure and stable solution, but I need to think about exactly what I want it to be able to do (evaluate expressions), and what to not allow it to do. I had not even contemplated using variables at all until I started experimenting with Execute. String variables, number variables, conditional statements and static arrays are much more than I had first envisaged.

Share this post


Link to post
Share on other sites

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Run_AU3Check=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Local $s1 = "What", $s2 = " now?"
MsgBox(0, "", $s1$s2&)

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

Valik you gave me quite a compliment. It is indeed writing a language (as you say) but of an extremely simple and limited nature.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Run_AU3Check=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Local $s1 = "What", $s2 = " now?"
MsgBox(0, "", $s1$s2&)

Don't need keywords, loops, conditionals, arrays, strings or macros. In fact I got rid of everything not directly pertaining to single line numeric operations. Code will write it's own comments. It will serve its (original) purpose as an alternative to running the calculator. While writing in some kind of document, you just simply type in your expression(s), select the code, hit run and it will append or overwrite previous results as and wherever you decide. The code itself will be left intact, so you can trace any errors later on. Still needs some work, but it should be easy enough.

List of functions to be included:

Native Functions

Mod Random Sin Cos Tan ASin ACos ATan

Log Exp Floor Ceiling Round Abs

Dec Hex BitOR BitNOT BitAND BitXOR BitRotate BitShift

UDF functions

_Radian _Degree _Max _Min _ATan2

_permutations _combinations _factorial

Operators

+ - / * ^ = += -= /= *=

Variables

integers floats binary

Constants

$MATH_PI = 3.14159265358979323846264338328 ; Pi

$MATH_PHI = 1.61803398874989484820458683436563811772 ; Golden Ratio

$MATH_E = 2.71828182845904523536028747135266249 ; Napiers Constant

$MATH_PSI = 3.359885666243177553172011302918927179688905133731 ; Reciprocal Fibonacci constant

End of line comments

; Semicolon

Parenthesis

( ... )

This is a preliminary list. I will add several more functions of my own

Edited by czardas

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

Thank you all for showing interest in this thread. I have just posted an alpha release of in example scripts, so you can get a clear picture of my idea. I have made one or two small changes to the above specs and made the $ (dollar sign) optional for naming variables. What a job that was!

I was surprised by the amount of error checking involved in creating something like this. It was harder than I thought it would be. It's taken me a week to get this far and Ii's been a valuable learning experience.

Edited by czardas

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0