Jump to content

Plys – AutoIt superset with namespaces and stuff


Recommended Posts

629626601_.png.451805a667e764185531eff0ad97f034.png

Plys represents the inconspicuous wrapper which complements the AutoIt language with

  1. preprocessor keyword #import "filename" loads only public functions and variables
  2. Python-like code blocks by lines indentation (without endfunc, wend etc.)
  3. dim and const outside of functions means global and global const respectively, inside of functions means local and local const
  4. arguments of function are const by default, but with dim prefix it becomes variable
  5. short synonyms for functions as a rule using in large projects: for arrays, files and strings
  6. no “$” prefix in variable names
  7. single-line anonymous functions
  8. and each of this is optional

Overview

; file “mylib.aup”

dim foo*, bar

func baz*()
    foo = quux()

func quux(dim arg="one/two/three")
    bar = Sort(Split(arg, "/", @NoCount))
    return "begin" . @ . bar[0] . @ . "end"
; file “main.aup”

#import "mylib.aup"

In this example variable bar and function quux() are private for module mylib.aup (names at declaration ends with an asterisk) and not visible in main.aup. Variable foo and function baz() will be visible with the “mylib:” prefix:

; file “main.aup”

#import "mylib.aup"

foo = baz()  ; error: no foo and baz() in this scope
mylib:foo = mylib:baz()  ; OK: foo and baz() are public in “mylib” scope
mylib:bar = mylib:quux()  ; error: bar and quux() are private in “mylib” scope

Sort is synonym for _ArraySort, Split is synonym for StringSplit, @NoCount is synonym for $STR_NOCOUNT, “@” is synonym for @CRLF, “.” is synonym for “&” operator.

All synonyms

Spoiler

Add ColDelete ColInsert Combinations Display Extract FindAll Insert Max MaxIndex Min MinIndex Permute Pop Push Search Shuffle Sort Swap ToClip Transpose Trim Unique → _Array*
ToHist → _Array1DToHistogram
BinSearch → _ArrayBinarySearch
Concat → _ArrayConcatenate

ChangeDir Copy CreateShortcut Flush GetAttrib GetEncoding GetLongName GetShortcut GetShortName GetSize GetTime GetVersion Open Opendialog Read ReadLine ReadToArray Recycle RecycleEmpty SaveDialog SelectFolder SetAttrib SetEnd SetPos SetTime Write WriteLine → File*
CreateLink → FileCreateNTFSLink
FirstFile → FileFindFirstFile
NextFile → FileFindNextFile

Struct → DllStructCreate
StructGet → DllStructGetData
StructGetSize → DllStructGetSize
StructGetPtr → DllStructGetPtr
StructSet → DllStructSetData

Echo → ConsoleWrite

AddCR Format InStr IsAlNum IsAlpha IsASCII IsDigit IsLower IsSpace IsUpper IsXDigit Left Len Lower Mid Replace Right Split StripCR StripWS TrimLeft TrimRight Upper → String*
ReFind → StringRegExp
ReReplace → StringRegExpReplace

Activate Active Flash GetCaretPos GetClassList GetClientSize GetProcess GetTitle Kill List MenuSelectItem MinimizeAll MinimizeAllUndo SetOnTop SetTitle SetTrans Wait WaitActive WaitClose WaitNotActive → Win*

@ReMatch → $STR_REGEXPMATCH
@ReArray @ReArrayFull @reArrayGlobal @reArrayGlobalFull → $STR_REGEXP*MATCH

@NoCaseSense @CaseSense @NoCaseSenseBasic @StripLeading @StripTrailing @StripSpaces @StripAll @ChrSplit @EntireSplit @NoCount @EndNotStart @UTF16 @USC2 → $STR_*

@ → @CRLF
@ActiveWin → WinGetHandle("[ACTIVE]")
@CmdLine → $CmdLine

. → &
.= → &=

Setup

Requirements: AutoIt (minimum), AutoIt Script Editor (optionally).

  1. Download and unpack archive from latest release.
  2. Double click the “setup.aup.au3” file and follow to setup instructions.

First steps

  1. Right-click in the any folder and select New > AutoIt Plys Script.

  2. Right-click on the created file again and select Edit Script.

  3. At the bottom of the file type the following:

    #include <MsgBoxConstants.au3>
    dim msg = ""
    for i = 1 to 10
        msg .= "Hello World!" . @
    msg = TrimRight(msg, 1)
    MsgBox(MB_OK, "My First Plys Script", msg)
  4. Save the script and double-click the file for run (or right-click the file and select Run Script).

Extra options

You can use extra options by typing in the script one of this:

#plys dollarprefix  ; refuse to use variables without “$” prefix
#plys noconst  ; use default variable declarations behavior
#plys noindent  ; ignore indentation but obligue to use “endif/wend/etc”.
#plys noimport  ; refuse the import operator
#plys nosynonyms  ; refuse the function and macro synonyms
#plys nolambda  ; refuse the anonymous functions

Environment

After installation Plys already integrated to Windows shell. If you want to run a script by command line use

<AutoIt3.exe path> <AutoIt3exe folder>\Plys\plys.aup.au3 [/Rapid] [/ErrorStdOut] [/NoStdio] <script path> [<arguments>]

/Rapid means that if source files have not be modified since the previous run, they will not be re-translated. This option speeds up script execution startup.

The /ErrorStdOut switch allows the redirection of a fatal error to StdOut which can then be captured by an application.

Also you can turn off data exchange through standard input/output streams, then the shell process will not hang in memory, but then you will not be able to observe the output of your program in the output window of your development environment. You can do this by adding the /NoStdio option.

If you want to translate a script to pure AutoIt code use

<AutoIt3.exe path> <AutoIt3exe folder>\Plys\plys.aup.au3 [/Translate] <script path>

Try AutoIt Plys package for Sublime Text which including syntax highlighting, auto-completions, build systems for run and compile, context help, “goto” feature, comments toggling, Tidy and Include Helper command for AutoIt and AutoIt Plys.

128544520_.png.f8e97997aa5cd7de8187bb3e97def90b.png

 

You can compile the script, specifying to the compiler the translated file *.aup.au3.

How it works

The plys.aup.au3 file contains the code that will run immediately after the launch of your script. On setup this file will copy to AutoIt install dir (as Plys\plys.aup.au3) and aup-files will associated with it. On the launch aup-files are automatically processed, after which the new AutoIt process interprets the already converted code, and the current process remains cycle to continue data exchange with the new process via standard streams. This handler replaces all #import with #include. The processed files get the extension .aup.au3 and are placed in the folder of the original script with “hidden” attribute.

Future

  • #import "filename.aup" noprefix
#import "mylib.aup" noprefix

bar = foo()
; bar and foo will be taken from the “mylib.aup” without “mylib:” prefix
  • #import "filename.aup" as alias
#import "mylib.aup" as ml

ml:bar = ml:foo()  ; bar and foo will be taken from the “mylib.aup”
  • function scope functions

func GlobalFunc()
    dim var1 = "body"
    func LocalFunc(var2)
        return "begin" . @ . var2 . @ . "end"
    return LocalFunc(LocalFunc(var1))

MsgBox(MB_OK, "begin/body/end", GlobalFunc())
  • array values in place and array comprehension

a = [3, 7, 1]
for i in [1, 2, 4]
    Echo(i . @)
    Display([t*3 for t in a if t > i])  ; if i = 2 then Display([9, 21]) etc.

 

Download

Repository on GitHub

Very old version (import only): import

 

Edited by NSUSpray
Version 0.5.0
Link to post
Share on other sites

Fixed: Wrapper used case-sensitive mode instead insensitive (could found “local …” but not “Local …”).

Critical! The algorithm did not work correctly for programs written in the generally accepted style (!), when keywords are started with a capital letter.

Link to post
Share on other sites

Massive update!

  • Python-like blocking by lines indentation (without endfunc, wend etc.)
  • dim and const outside of functions means global and global const respectively, inside of functions means local and local const
  • arguments of function are const by default, but with dim prefix it becomes variable
  • short synonyms for functions as a rule using in large projects: for arrays, files and strings
Edited by NSUSpray
Link to post
Share on other sites
  • NSUSpray changed the title to AutoIt plys – syntax additions for comfortable coding (file scope namespaces and stuff)
  • NSUSpray changed the title to Plys – Light Your AutoIt Code! (AutoIt superset with namespaces and stuff)

Version 0.4.0

  • Rewrited on Plys
  • Added automatic installation
  • Added shell integration: run and translate to AutoIt by double click or context menu
  • Public via * at declaration instead private via _ (underscore)
  • Added operator/macro synonyms for &, &= and @CRLF
  • Added lambda (anonymous functions) feature

Version 0.4.3

  • Added compiled HTML Help with examples (aup-script files)

Version 0.4.4

  • Fixed: incorrect line number and filename in error out

https://github.com/NSUSpray/Plys/releases/tag/v0.4.4

Edited by NSUSpray
Version 0.4.4
Link to post
Share on other sites
  • NSUSpray changed the title to Plys – AutoIt superset with namespaces and stuff

Version 0.5.0

  • Added: rapid start option /Rapid
  • Added: substitution of macros @ScriptFullPath, @ScriptName and @ScriptLineNumber
  • Added: macros @PlysPath and @PlysVersion
  • Added: Unicode support for stderr and stdout streams
  • Added: process the error window message, the notification area tool tip and icon
  • Changed: translation algorithm for better performance
  • Changed: Plys options for each file
  • Changed: /NoStdio command line switch instead “#plys nostdio” line in script
  • Changed: lambda feature enabled by default
  • Fixed: tab to spaces conversion is broken
  • Fixed: dollar prefix is appended for “until” keyword
  • Fixed: incorrect line enumeration
  • Fixed: extra endif after single-line if..then and decreasing indent

https://github.com/NSUSpray/Plys/releases/tag/v0.5.0

Edited by NSUSpray
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By tarretarretarre
      - _____ _____ _ _ - |_ _|___ ___ ___ _ _| __|___ ___|_|___| |_ - | | | -_| -_| | | |__ | _| _| | . | _| - |_| |___|___|_|_|_ |_____|___|_| |_| _|_| - By TarreTarreTarre|___|Build '1.0.0' |_| + F5 = Run script + F6 = Build 'AU3' + F7 = Build 'EXE' + F8 = Options GUI + F10 = Exit TeenyScript All example code and documentation moved to: http://teenyscript.tarre.nu/documentation
      Official Github repo: http://github.com/tarreislam/teenyscript
      F.A.Q Q: What is TeenyScript? A: TeenyScript is a Superset of AutoIt which makes it more advanced Q: How does it work? A: TeenyScript code are parsed into native AutoiT code Q: Does it depend on anything else than AutoIt? A: Just one dependency, that is AutoitObject, the best UDF ever created for AutoIt, besides that, only Native AutoIt is used Features
      "Anonymous" functions Endless scope nesting OOP (powered by AutoitObject) User-friendly integration Powerful macros Namespaces Lists  Project support, for easy deployment Userfriendly GUI for userfriendly Tasks for the Userfriendly person And much more To come
      You decide, I am happy to do requests!  
      Install and Update TeenyScript
       
       
      HOW TO GET STARTED
       Run TeenyScript.au3 Now this should see something like this in your console
        Code Press F8 and navigate to the misc tab to install SciTE calltips Run \ Build \ Compile  
      How to run with Sublime Text
      Here is some examples of TeenyScript code

       
      ;Basic List usage $Example_A = Func() ; Create a list Local $myList = { 'Name': 'Tarre' } ; Add \ Change data on $MyList $myList{'Age'} = 25 ; Create MySecondList Local $MySecondList = { "Name" => "John", "Age" => "00" } ; Using variable instead of a string Local $KeyName = "Age" Local $KeyVal = 1337 $MySecondList{$KeyName} = $KeyVal ; You may also pass lists to lists. however this has to be done in this fashion. Local $oList = {'myList': $myList, 'mySecondList' => $MySecondList} ; Return the objects Return $oList EndFunc();call the function on the variable ; Loop through list and print their values $Example_B = Func() Local $MyList = {'A': 'Hello FROM A', 'B': 'Hello FROM B', 'C': 'Hello FROM C'} Local $aNames = ['A', 'B', 'C'] For $i = 0 To UBound($aNames) -1 MsgBox(0,0,$myList{$aNames[$i]}) Next EndFunc #MAIN MsgBox(0,"Example A 1", $Example_A.myList.Name) MsgBox(0,"Example A 2", $Example_A.myList.Age) MsgBox(0,"Example A 3", $Example_A.mySecondList.Name) MsgBox(0,"Example A 4", $Example_A.mySecondList.Age) $Example_B(); Execute examble B Here is a non class nested function calculator example (calculator.ts.au3)
      $calculator = Func($a, $and, $b) $division = Func($a, $b) if Not $a or Not $b Then Return "Error dividing 0" EndIf Return $a/$b EndFunc Switch $and Case '+' Return $a + $b Case '-' Return $a - $b Case '/' Return $division($a, $b) Case '*' Return $a * $b EndSwitch Return "Unkown attribute "&$and EndFunc #MAIN ConsoleWrite($calculator(25, '*', 25)&@CRLF) ConsoleWrite($calculator(25, '/', 0) & @CRLF) ConsoleWrite($calculator(1, '^', 2) & @CRLF)
       
      teeny-script.zip  (OLD)
      TeenyScript beta2.zip (OLD)
      teeny-script Beta 4.zip (OLD)
      teeny-script Beta 5.zip (OLD)
      teeny-script BETA 6.zip (OLD)
      TeenyScript Beta 7.zip (OLD)
      teeny-script Beta 8.zip (OLD)
      TeenyScript-master 1.0.0.zip (OLD)
      TeenyScript-1.1.0.zip (OLD)
      TeenyScript-1.2.0.zip (OLD)
      TeenyScript-2.0.0.zip (OLRD, Release notes)
      TeenyScript-2.1.3.zip (Newest 2016-09-16, Release notes)
    • By c.haslam
      As I understand it: there is no distinction, when a variable is declared outside any function, between declaring it Global and declaring it Local.
      This is unfortunate when:
      a project has several dialogs: declaration of control variables can conflict. a project has one complex dialog In the latter case, I have one here with a dialog function that is 269 lines!
      I could declare all the control variables as Global, but globals should be aoided where possible.
      I think good practice would be to put each dialog in its own file (unless it is a really simple one).
      Life would be easier if there were a distinction in how variables are declared outside functions:
      Global would mean the variable is known to all .au3 files in the project Local would mean that the variable is known only within the file in which it is declared. So control variables could then be declared as known to all functions in the file (module) by declaring them as Local outside any function. Other languages have this feature.
      I am working on a project with one not-very-complex dialog. I would like to be able to split its 269 lines into several functions, e.g. the creation of the dialog, enabling/disabling controls based on a control, and updating the values of the controls due to user actions (in this case, a listview). I already have factored out into functions parts that do not involve control variables: verifications of user entries and actions when the user clicks on OK (or equivalents).
      Would this be script-breaking change? Probably, but only for those who don't follow the best coding practices: as AutoIt is now, one should not be declaring variables as Local outside functions, because one gets Global anyway. There is nothing Local about a variable declared outside functions.
      I will be interested to learn what others think. If this is an old topic, I apologize. If I have it wrong, do tell me.
       
    • By guinness
      If you are coming from the realm of C# 3.0 then lamda expressions should be pretty familiar to you as it's basic syntactic sugar for creating a function with a conditional return.
       
      Since functions in AutoIt are first class objects, the following code should make some sense. It passes an array of integers to a function called IsTrueForAll() that checks whether the function object matches the return condition of that function (you passed). So for example a function called IsGreaterThanOrEqualTo10() checks if all values are greater than or equal to 10 (TRUE). Similarly, IsLessThan10() checks if all values are less than 10 (FALSE). This example should be nothing new to those of you who use v3.3.10.0+ and have an understanding of Call().

      #include <MsgBoxConstants.au3> Local $aArray[] = [10, 100, 99, 67] If IsTrueForAll($aArray, IsGreaterThanOrEqualTo10) Then MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf If IsTrueForAll($aArray, IsLessThan10) Then MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf Func IsTrueForAll($aArray, $hFunc) ; Loop through the array and check the function passed with a single param matches the condition. For $i = 0 To UBound($aArray) - 1 If Not $hFunc($aArray[$i]) Then Return False EndIf Next Return True EndFunc ;==>IsTrueForAll Func IsGreaterThanOrEqualTo10($x) Return $x >= 10 EndFunc ;==>IsGreaterThanOrEqualTo10 Func IsLessThan10($x) Return $x < 10 EndFunc ;==>IsLessThan10 But, we could easily just forget about writing the functions (less typing is always nice) and let the compiler or pre-processor do all the work for us. It would simply use the lambda expression and create the function for us with whatever we specified. Like so...
      #include <MsgBoxConstants.au3> Local $aArray[] = [10, 100, 99, 67] If IsTrueForAll($aArray, $x => $x >= 10) Then ; $x is the parameter, => tells us it's a lambda expression and then the condition we are checking. MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf If IsTrueForAll($aArray, $x => $x < 10) Then ; $x is the parameter, => tells us it's a lambda expression and then the condition we are checking. MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf Func IsTrueForAll($aArray, $hFunc) ; Loop through the array and check the function passed with a single param matches the condition. For $i = 0 To UBound($aArray) - 1 If Not $hFunc($aArray[$i]) Then Return False EndIf Next Return True EndFunc ;==>IsTrueForAll...which would create the following code with anonymous functions (they're anonymous as we don't care about them in our main script)...
      #include <MsgBoxConstants.au3> Local $aArray[] = [10, 100, 99, 67] If IsTrueForAll($aArray, D3F7B1B92177415CA70C7FFC35C2649C) Then MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf If IsTrueForAll($aArray, DA06B548ABF4045AA32F805E6651004) Then MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf Func IsTrueForAll($aArray, $hFunc) For $i = 0 To UBound($aArray) - 1 If Not $hFunc($aArray[$i]) Then Return False EndIf Next Return True EndFunc ;==>IsTrueForAll Func D3F7B1B92177415CA70C7FFC35C2649C($x) Return $x >= 10 EndFunc ;==>D3F7B1B92177415CA70C7FFC35C2649C Func DA06B548ABF4045AA32F805E6651004($x) Return $x < 10 EndFunc ;==>DA06B548ABF4045AA32F805E6651004 Example of parsing a lambda expression and replacing in the chosen script:
      #include <WinAPICom.au3> ; Script read from a file. Local $sScript = "#include <MsgBoxConstants.au3>" & @CRLF $sScript &= "" & @CRLF $sScript &= "Local $aArray[] = [10, 100, 99, 67]" & @CRLF $sScript &= "If IsTrueForAll($aArray, $x => $x >= 10) Then" & @CRLF ; Lambda expression. $sScript &= " MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.')" & @CRLF $sScript &= "Else" & @CRLF $sScript &= " MsgBox($MB_SYSTEMMODAL, '', 'Condition was False')" & @CRLF $sScript &= "EndIf" & @CRLF $sScript &= "" & @CRLF $sScript &= "If IsTrueForAll($aArray, $x => $x < 10) Then" & @CRLF ; Lambda expression. $sScript &= " MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.')" & @CRLF $sScript &= "Else" & @CRLF $sScript &= " MsgBox($MB_SYSTEMMODAL, '', 'Condition was False')" & @CRLF $sScript &= "EndIf" & @CRLF $sScript &= "" & @CRLF $sScript &= "Func IsTrueForAll($aArray, $hFunc) ; Loop through the array and check the function passed with a single param matches the condition." & @CRLF $sScript &= " For $i = 0 To UBound($aArray) - 1" & @CRLF $sScript &= " If Not $hFunc($aArray[$i]) Then" & @CRLF $sScript &= " Return False" & @CRLF $sScript &= " EndIf" & @CRLF $sScript &= " Next" & @CRLF $sScript &= " Return True" & @CRLF $sScript &= "EndFunc ;==>IsTrueForAll" & @CRLF ReplaceLambdaInScript($sScript, '$x => $x >= 10') ; Parse the lambda expression and replace it in the above script. ReplaceLambdaInScript($sScript, '$x => $x < 10') ; Parse the lambda expression and replace it in the above script. ConsoleWrite($sScript & @CRLF) ; This is the new script with the lamda expression convert to an anonymous method! ClipPut($sScript) Func CreateLambdaMethod($sExpression) ; Currently no error checking of whether parameters match. Local $bIsReturn = False, _ ; Is the return condition. $sFunction = StringRegExpReplace(_WinAPI_CreateGUID(), '[}{-]', ''), $sParam = '', $sReturn = '' $sFunction = StringRegExpReplace($sFunction, '^\d+', '') ; Remove digits at the beginning of the function name. For $i = 1 To StringLen($sExpression) $sChr = StringMid($sExpression, $i, 1) If $bIsReturn Then $sReturn &= $sChr ElseIf $sChr & StringMid($sExpression, $i + 1, 1) == '=>' Then ; Check for => $i += 1 $bIsReturn = True ElseIf Not $bIsReturn Then $sParam &= $sChr EndIf Next If Not $bIsReturn Then Return "" ; Something went wrong as the => was not found. $sParam = '(' & StringRegExpReplace($sParam, '^\h*|\h*$', '') & ')' $sReturn = @TAB & 'Return ' & $sReturn Return 'Func ' & $sFunction & $sParam & @CRLF & $sReturn & @CRLF & 'EndFunc ;==>' & $sFunction & @CRLF EndFunc ;==>CreateLambdaMethod Func ReplaceLambdaInScript(ByRef $sScript, $sLambda) Local $sFunction = CreateLambdaMethod($sLambda) Local $sFunctionName = StringRegExp($sFunction, 'Func (\w*)\(', 3) If @error Then Return False $sFunctionName = $sFunctionName[0] $sScript = StringReplace($sScript, $sLambda, $sFunctionName, 1) $sScript &= @CRLF & $sFunction Return True EndFunc ;==>ReplaceLambdaInScriptIt was a simple idea I had this morning whilst having breakfast.
×
×
  • Create New...