Jump to content



Photo

Strange Syntax


  • Please log in to reply
24 replies to this topic

#1 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 29 June 2012 - 05:46 PM

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, 29 June 2012 - 06:24 PM.








#2 Manadar

Manadar

    Taking a REST.

  • MVPs
  • 10,714 posts

Posted 29 June 2012 - 06:25 PM

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.

#3 BrewManNH

BrewManNH

    באָבקעס מיט קודוצ׳ה

  • MVPs
  • 7,055 posts

Posted 29 June 2012 - 06:27 PM

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

How to ask questions the smart way!

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 editorGUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.

GUIToolTip UDF Demo - Demo script to show how to use the GUIToolTip UDF to create and use customized tooltips.

Posted Image


#4 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 29 June 2012 - 06:48 PM

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
AutoIt         
#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, 29 June 2012 - 10:44 PM.


#5 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 30 June 2012 - 05:56 AM

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.

#6 Mat

Mat

    43 38 48 31 30 4E 34 4F 32

  • MVPs
  • 4,101 posts

Posted 30 June 2012 - 10:28 AM

Look at Au3Int. I wrote a lot of code (and so did wraithdu) to work around these exact problems: http://www.autoitscript.com/forum/topic/114330-autoit3-interpreter/

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, 30 June 2012 - 10:29 AM.

I don't know where I'm going, but I'm on my way.

AutoIt Project Listing


#7 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 30 June 2012 - 10:40 AM

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, 30 June 2012 - 11:22 AM.


#8 Manadar

Manadar

    Taking a REST.

  • MVPs
  • 10,714 posts

Posted 30 June 2012 - 11:25 AM

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?

#9 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 30 June 2012 - 11:38 AM

Write another language LOL. This is just a text editor with some whacky additional features like text rotation 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, 30 June 2012 - 11:54 AM.


#10 Manadar

Manadar

    Taking a REST.

  • MVPs
  • 10,714 posts

Posted 30 June 2012 - 11:50 AM

Writing a language can be as simple as you want it to be. A very basic syntax can be:

rotate 40


#11 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 30 June 2012 - 12:13 PM

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, 30 June 2012 - 12:17 PM.


#12 Shaggi

Shaggi

    Universalist

  • Active Members
  • PipPipPipPipPip
  • 296 posts

Posted 30 June 2012 - 12:43 PM

Are you exposing execute() to user input? Holy.
Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

#13 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 30 June 2012 - 01:02 PM

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, 30 June 2012 - 01:09 PM.


#14 Richard Robertson

Richard Robertson

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 9,716 posts

Posted 30 June 2012 - 01:14 PM

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

#15 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 30 June 2012 - 01:30 PM

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

#16 Valik

Valik

    Former developer.

  • Active Members
  • PipPipPipPipPipPip
  • 18,879 posts

Posted 30 June 2012 - 02:23 PM

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.
  • twitchyliquid64 likes this

#17 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 30 June 2012 - 03:01 PM

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.

#18 AdmiralAlkex

AdmiralAlkex

    I'm on a boat

  • MVPs
  • 4,493 posts

Posted 30 June 2012 - 07:06 PM

#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&)


#19 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 02 July 2012 - 06:25 PM

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:
Spoiler

Edited by czardas, 03 July 2012 - 10:39 AM.


#20 czardas

czardas

  • Active Members
  • PipPipPipPipPipPip
  • 5,173 posts

Posted 06 July 2012 - 02:55 PM

Thank you all for showing interest in this thread. I have just posted an alpha release of AutoMathEdit 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, 07 July 2012 - 01:36 PM.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users