Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/03/2012 in all areas

  1. For a long time now, I have been curious about the dealing of Interpreters, and compilers, and often, this curiousity manifests into some experimentation. My Interpreter (nicknamed PARADIME) is an attempt at interpreting the autoit syntax, to gain a better understanding of how AutoIT 'ticks' and also to cure my curiousity to see if I can write an interpreter for an existing language. The current (UNFINISHED) result I am quite happy with. A great deal of the syntatical features of autoit are implemented, with most intended to be implemented. The Following functionality operates correctly in my Interpreter: Global Declarations '=' Assignments Function calls (including recursive) Variant Datatype (Implementing Arrays, INT32, INT64, double, string) Operators: + - / * > < <> >= <= = == Singleline IF Multiline IF WHILE statements About 20 macros About 12 Builtin Functions{ ConsoleWrite FileRead FileOpen FileClose MsgBox(Non optional params only) Stringlen StringLeft/Right StringTrimLeft/Right TimerInit (TimerDiff() is bugged, however) } Arrays For example, the following code will execute correctly. $t = 1 $t2 = 2 if $t = $t2 then MsgBox(48, "TEST", "EQUALITY") if $t <> $t2 then MsgBox(48, "TEST", "NOT EQUALITY") Global $mate = 89, $eee, $f = 55, $arraydestroytest[65000] MsgBox(48, "TEST", "This Code is running in Paradime: " & $eee) While $mate < 4000 $arraydestroytest[$mate] = $mate $mate = $mate + 1 $r = "FFFF" & "00043" WEnd MsgBox(48, "TEST", "This Code is running in Paradime: " & $mate & " " & $arraydestroytest[$mate-1]) COnsoleWrite(Stringlen("LOL RECURSION")) ConsoleWrite("Macro Test:" & @LF) ConsoleWrite("Program files: " & @PROGRAMFILESDIR & @LF) ConsoleWrite("Common files: " & @CommonFilesDir & @CR) ConsoleWrite("My Documents: " & @MyDocumentsDir & @CR) ConsoleWrite("AppDataC files: " & @AppDataCommonDir & @CR) ConsoleWrite("DesktopC files: " & @DesktopCommonDir & @CR) ConsoleWrite("DocumentsC files: " & @DocumentsCommonDir & @CR) ConsoleWrite("FavouritesC files: " & @FavoritesCommonDir & @CR) ConsoleWrite("ProgramsC files: " & @ProgramsCommonDir & @CR) ConsoleWrite("StartMC files: " & @StartMenuCommonDir & @CR) ConsoleWrite("Startup files: " & @StartupCommonDir & @CR) ConsoleWrite("AppData files: " & @AppDataDir & @CR) ConsoleWrite("Desktop files: " & @DesktopDir & @CR) ConsoleWrite("Favs files: " & @FavoritesDir & @CR) ConsoleWrite("Program files: " & @ProgramsDir & @CR) ConsoleWrite("Start Menu files: " & @StartMenuDir & @CR) ConsoleWrite("Startup files: " & @StartupDir & @CR) ConsoleWrite(@CRLF & "Computer: " & @ComputerName & @CR) ConsoleWrite("WIN: " & @WindowsDir & @CR) ConsoleWrite("Working: " & @WorkingDir & @CR) ConsoleWrite("System: " & @SystemDir & @CR) ConsoleWrite("IP1: " & @IPAddress1 & @CR) ConsoleWrite("IP2: " & @IPAddress2 & @CR) ConsoleWrite("IP3: " & @IPAddress3 & @CR) ConsoleWrite("IP4: " & @IPAddress4 & @CR) ConsoleWrite("TempDir: " & @TempDir & @CR) ConsoleWrite("Username: " & @UserName & @CR) ConsoleWrite("HomeDrive: " & @HomeDrive & @CR) ConsoleWrite("HomePath: " & @HomePath & @CR) ConsoleWrite("HomeShare: " & @HomeShare & @CR) ConsoleWrite("LogonServer: " & @LogonServer & @CR) ConsoleWrite("LogonDomain: " & @LogonDomain & @CR) ConsoleWrite("LogonDNSDomain: " & @LogonDNSDomain & @CR) Academic Discourse: The biggest thing that surprised me was how well written/optimized AutoIT was (or how inefficient a C++ coder I am, having 6 months of experience ^^') My interpreter runs approximately 5.4X slower than the AutoIT interpreter, dispite the datastructures being similar. My guess is that these speed differences are due to two things: -Pointer passing: nearly everything large in the public autoit source has its pointer passed around as opposed to the datatype. Substantial portions of my code do not pointer-pass, reducing speed. Also, my inexperience/rush in writing this would attenuate this with potentially inferior code (relative to autoIT) -Operator evaluation: I originally thought that AutoIT's decision to treat every operand as a VARIANT class would incur a noticable overhead, so I thought I could sidestep it by using my original TOKEN datastructure from the lexing stage. Now I realise that this overhead is unavoidable, as im still doing typechecking and conversions with the token datatype. The only difference is Jonathon is doing it in a pretty little variant class and my parser_eval.cpp is littered with switch statements for every operand possibility for every operator. (Please dont look at the source, you will cry). PARADIME Implements, from scratch, -Custom Lexer/tokeniser -Stateful Recursive Decent Parser -Shunting yard algorithm for expression evaluation -implements std::map for Variable and builtinfunction pointer lookup -implements std::vector for token storage. Parser Evidently, I have attempted to deviate from Jonathons chosen parsing approach to test the validity of other algorithms, and initial results indicate that my parsing model is applicable. Both of our interpreters use the recursive decent model for traversing nested structures. Paradime has various parsing states transparent to parsing of the tokens themselves. The two main states are EXEC and IGNORE, where EXEC, executes the code up to the corresponding end of the code block (ENDIF, WEND etc), whereas IGNORE 'ignores' the contained code. I did not quite understand how Jon traversed nested structures, so I cannot comment further on his methods here. Handling of Expressions is done entirely different on the two interpreters. Jonathon uses a LALR Shift/Reduce Algorithm, where as I use dijkastras shunting yard algorithm. Thus far, both approaches seem entirely applicable. Variant Storage: Done the same on both interpreters. Array handling code is practically copied, It was better than anything I could ever make. Lookup Speed: One other thing I noticed is that Macros and Builtin functions have no optimal lookup table (in the public autoIT source). Perhaps, to improve speed, these things could be stored in a red/black binary tree to increase efficiency? Conclusion: All in all, the parsing and interpreting backbone is a magnificent piece of work, and all my attempts to replicate it and deconstruct (from the publicsource) it have only increased my sense of awe. I express my most sincere thanks to the autoit developers for such, and I hope that development of AutoIT never stops. One day, when I get out of highschool I would like to develop autoIT, who knows. Paradime Sourcecode: As previously mentioned, the vast majority of the sourcecode is created from scratch. However, the There was no point re-inventing the wheel when implementing some macros and some builtins, and the code for array handling in variants, and one or two syntatical expressions. These elements of the sourcecode are clearly labelled at the top and have the GNU license attached (Code from before Autoit went to closedsource). Credit is clearly given. Please dont look at it. It is poorly written, undercommented, and due to my bad choice to use the token structure as the operand structure, a good deal of parsing logic is littered in hundreds of lines of switch statements. (eww) http://code.google.com/p/paradime-interpreter/source/browse/#hg%2FParadime%2Fcore Please, dont judge me. SciTE integration: Thanks to LaCastiglione: command.38.*.au3="C:Paradime.exe" "$(FilePath)" command.name.38.*.au3=Paradime command.save.before.38.*.au3=1 command.shortcut.38.*.au3=Ctrl+F7Drop Paradime.exe into your C: drive. Future of Paradime: I will implement NOT, AND, OR, FOR-NEXT, SWITCH-CASE-ENDSWITCH, and user defined functions. Then I will deviate from autoit, exploring new, custom language constructs, but thats another academic project entirely. -hyperzap
    3 points
  2. The internals have progressed quite a bit since that public source code as well - some parts from scratch. There's lots of weird optimizations. Quite a lot of Copy-on-write activity which really sped things up a lot as well. The main slow down the last time I checked was the eval code which still creates a lot of copies of data as it works the values out using stacks - it's one of the scarier areas to contemplate rewriting though...
    1 point
  3. MattX, I would not limit it to just that error - better to use If @error Then ContinueLoop to catch them all. M23
    1 point
  4. MattX, Check for @error or use IsArray immediately after the _FileListToArray line to check you got some files returned. M23
    1 point
  5. Valuater

    Autoit Wrappers

    ;Get Wav Sound Volume ; Author gafrost #include <GUIConstants.au3> MsgBox(0,"", _SoundGetWaveVolume()) Func _SoundGetWaveVolume() Local $WaveVol = -1, $p, $ret Const $MMSYSERR_NOERROR = 0 $p = DllStructCreate ("dword") If @error Then SetError(2) Return -2 EndIf $ret = DllCall("winmm.dll", "long", "waveOutGetVolume", "long", -1, "long", DllStructGetPtr ($p)) If ($ret[0] == $MMSYSERR_NOERROR) Then $WaveVol = Round(Dec(StringRight(Hex(DllStructGetData ($p, 1), 8), 4)) / 0xFFFF * 100) Else SetError(1) EndIf $Struct=0 Return $WaveVol EndFunc;==>_SoundGetWaveVolume run("sndvol32.exe") WinWait("") ControlSend("Volume Control", "", "msctls_trackbar322", "{PGUP}") sleep(1000) ControlSend("Volume Control", "", "msctls_trackbar322", "{PGUP}") sleep(1000) ControlSend("Volume Control", "", "msctls_trackbar322", "{PGUP}") sleep(1000) ControlSend("Volume Control", "", "msctls_trackbar322", "{PGDN}") sleep(1000) ControlSend("Volume Control", "", "msctls_trackbar322", "{PGDN}") sleep(1000) ControlSend("Volume Control", "", "msctls_trackbar322", "{PGDN}") Global Const $TBM_GETPOS = $TWM_USER Func _GUICtrlSliderGetPos($h_slider) Local $ret $ret = DllCall("user32.dll", "int", "SendMessage", "hwnd", $h_slider, "int", $TBM_GETPOS, "int", 0, "int", 0) Return $ret[0] EndFunc;==>_GUICtrlSliderGetPos $ret = DllCall("user32.dll", "int", "SendMessage", "hwnd", $h_slider, "int", $TBM_GETPOS, "int", 0, "int", 0) 8)
    1 point
×
×
  • Create New...