Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <# : batch portion
- :# The above line marks the beginning of a powershell comment block; and the Batch component of the Script. Do not modify.
- @Echo off
- Setlocal ENABLEextensions ENABLEdelayedexpansion
- Set "PS.Utility=For %%n in (1 2)Do if %%n==2 (Echo/^^^!Args:~1^^^!| powershell.exe -noprofile "$Mode = $input ^| ?{$_}; iex (${%~f0} ^| out-string)")Else Set Args="
- :# Toggle Fullscreen by calling powershell component of script.
- If not defined fscreen %PS.Utility%
- Endlocal & Set "fscreen=true"
- :::::::::::::::::::::::::::::::::::::::::::::: REM TBA script readability review.
- REM Esolang: BatchStax by T3RRY ; loosely based off isdo. See syntax for valid operations.
- REM This esolang now supports runtime inputs.
- REM Input Arguments may reference preceeding arguments as an Arithemetic expression - See Syntax for more info.
- REM
- REM NOTE: .bs Programs Should be located in the same directory tree as this Interpreter.
- REM IMPORTANT NOTE: Command lines terminating in .bs will be treated as being a path for a .bs script
- REM - this 3 digit string would otherwise be a valid, if unlikely command sequence
- REM This script is an interpreter for BatchStax, and includes limited debugging tools and error checking.
- ::: Version 2.4.1
- REM Version Change 24/05/2023: Added VT Command: "5" - Subsequent output will be in blinking mode. Pre-existing command: "~" resets cursor graphics mode
- REM Added shorthand: "£" - equivelant f#a
- REM
- REM VERSION Change 04/01/2022: Corrected literal String parsing to facilitate literal output of `*` character [special meaning in for loops.]
- REM Expanded character output support to include utf characters in the range 1~239 of code page 65001
- REM UTF8 Character indexing method significantly faster than previous ASCII character indexing method.
- REM VERSION Change 03/01/2022: Support added for USER input/s to commands at runtime via Arguments. See Updated Syntax and included example.
- REM VERSION Change 02/01/2022: Support added for Integer input to commands via Arguments. Inputs may be referenced in loop repeat arguments,
- REM stack array assingments or by subsequent input arguments.
- REM IMPORTANT: In the event command arguments are used, All instances of the String $_index, where index is
- REM an Integer within the maximum number of arguments supplied will be replaced with the relevant Argument.
- REM $_1 $_2 $_4 $_6 $_7 and $_8 would otherwise be valid, if unlikely, command sequences.
- REM VERSION Change 01/01/2022: Nested loop parsing and command error output extensively improved.
- REM Supports any nested loop structure with appropriately balanced
- REM parentheses and ':' seperators, provided each loop terminates with ':Integer)'
- REM Added support for Literal string output
- REM Added escaping rule for literal output of parentheses
- REM Prohibits literal use of strings: '//O' and '//C'
- REM '~' Virtual Terminal command added
- REM - Resets foreground / background color if Virtual Terminal sequences supported.
- REM
- ::: Version 2.0 : Breaking change introduced since last version for command lines containing 'Q'
- REM VERSION Change 23/12/2021: Added requirement for source scripts to have .bs extension to facilitate
- REM golfing quines.
- REM - Added Golf quines. If any commandline or script consists of
- REM a single command, the literal command character will be output.
- REM VERSION Change 22/12/2021: Command 'Q' now terminates program if the Current stack value EQU rVal
- REM - Previous behavior was to output 1 or 0 if true or false
- REM VERSION Change 21/12/2021: Added LIMITED support for Nested loops - See updated Syntax.
- REM - Infinite loops Are NOT supported.
- REM Added option of calling interpreter with a filepath containing source code.
- REM instead of calling with Command line arguments. The interpreter will pause
- REM and wait for a keypress after each line has executed.
- REM ** Note:
- REM Each line is treated as a new script. stack values and rVal do not persist.
- REM VERSION Change 20/12/2021: Added simple looping / repetition - See updated Syntax.
- REM VERSION Change 19/12/2021: Now accepts Input argument to predefine stack value / stack array values and
- REM assign initial stack. - See updated Syntax
- REM - Removed Virtual terminal Color command 'E', replaced with
- REM 'B' [background] and added 'F' [foreground]
- REM VERSION Change 18/12/2021: New Virtual terminal features:
- REM - Cursor left right up down
- REM - Background color change
- REM Creative Commomns License 4.0
- REM https://creativecommons.org/licenses/by-nc-sa/4.0/
- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- REM code page 65001 mandatory for this program to function as intended.
- CHCP 65001 > nul
- REM Critical Variable definition; requires default Disabled expansion environment. character index range: 1 ~ 239
- If "!!"=="" (Exit /b 1)
- Set ^"UnicodeChars= ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѺ¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦▀ÓßÔÒõÕµþÞÛÙýݯ´±‗¾"
- ::====================================================================================================
- Rem :: input capture method is a modified version of Dave Benhams method:
- Rem :: https://www.dostips.com/forum/viewtopic.php?t=4288#p23980
- REM ** input of literal "<" and ">" characters require caret escaping. "&" and "|" characters require the input to be doublequoted.
- SETLOCAL DISableDelayedExpansion
- Set "CommandError="
- SETLOCAL EnableDelayedExpansion
- 1>"%~f0:Params.dat" <"%~f0:Params.dat" (
- SETLOCAL DisableExtensions
- Set prompt=#
- Echo on
- For %%a in (%%a) do rem . %*.
- Echo off
- ENDLOCAL
- Set /p "_="
- Set /p "_="
- Set "_=!_:~7,-2!"
- @Rem duplicate for debug output
- Set "CL=!_!"
- ) || (
- 1>&2 Echo(%~nx0 requires an NTFS drive system to function as intended.
- CMD /C Exit -1073741510
- ) || Goto:Eof
- If not defined UnicodeChars (
- Call:FlagError "Interpreter has been modified."
- Goto:EndRun
- )
- For /l %%n in (1 1 239)Do Set ^"Uni[%%n]=!UnicodeChars:~%%n,1!"
- REM detect help switches or empty commandline; output help.
- set "_" 2>&1 | %systemroot%\system32\findstr.exe /li "\/? -? help syntax defined" > nul && (
- Mode 1000
- Call :Syntax
- If not errorlevel 1 Pause
- Goto:Eof
- )
- REM detect golfing help switch golfing info.
- Set "Fstr=Rem"
- set "_" 2>&1 | %systemroot%\system32\findstr.exe /li "\/golf" > nul && (
- Mode 1000
- For /F "Tokens=2* Delims=," %%G in ('%systemroot%\system32\findstr.exe /li "%Fstr%," "%~f0"')Do Echo(%%G
- Pause
- Endlocal & Goto:Eof
- )
- REM enact escaping and substitutions for safe processing.
- Set "_=!_:&=^&!"
- Set "_=!_:|=^|!"
- Set "_=%_:!=XCLM%"
- Rem a defined value to the below devmode variable logs command errors and / or output. Defined using /D switch.
- Set "devmode="
- If not "!_:/D=!"=="!_!" (
- Set "_=!_: /D =!"
- Set "_=!_:/D =!"
- Set "_=!_: /D=!"
- Set "_=!_:/D=!"
- Set "devmode=true"
- )
- REM,===========================================================================================================
- REM, Golfing shorthands
- Rem,
- Rem, Alt 0161 '¡' - Equivalent to $_ Argument reference prefix
- Set "_=!_:¡=$_!" & Set "CL=!CL:¡=$_!"
- Rem,
- Rem, Alt 223 '▀' - Equivalent to ai ; output unicode character + increment rval
- Set "_=!_:▀=ia!" & Set "CL=!CL:▀=ia!"
- Rem,
- Rem, Alt 220 '▄' - Equivalent to ia ; increment rval + output unicode character
- Set "_=!_:▄=ai!" & Set "CL=!CL:▄=ai!"
- Rem,
- Rem, Alt 0170 'ª' - Equivalent to 44a ; outputs unicode value of rval left of previous output character
- Set "_=!_:ª=44a!" & Set "CL=!CL:ª=44a!"
- Rem,
- Rem, Alt 0131 'ƒ' - Equivalent to fa ; Change color to rval + output unicode character
- Set "_=!_:ƒ=fa!" & Set "CL=!CL:ƒ=fa!"
- Rem,
- Rem, alt 156 '£' - Equivalent to f#a ; Change color to rval + Assign value of current stack to rval + output unicode character
- Set "_=!_:£=f#a!" & Set "CL=!CL:£=f#a!"
- Rem,
- REM, Alt 0191 '¿' / ?U - Equivalent to: ?#239 - input request within supported range of unicode characters.
- Set "_=!_:¿=?#239!"
- Set "_=!_:?U=?#239!" %= Backwards compatability =%
- Rem,
- REM, alt 0135 '‡'
- REM, Enact shorthand Array syntax with IMPLICIT starting index 0:
- REM, Shorthand Syntax: {ArrayIntegerList;StartIndex} Becomes: ArrayIntergerList‡
- REM, PREREQUISITE: Arraylist to prefix command line
- REM, CONSTRAINTS: { and ‡ cannot be used as literal strings
- If not "!_:‡=!"=="!_!" If "!_:{=!"=="!_!" (
- Set "_={!_:‡=;0}!"
- Set "CL={!CL:‡=;0}!"
- If not "!CL:{/D =!"=="!CL!" (
- Set "CL=/D !CL:{/D ={!"
- )Else If not "!CL:{/D=!"=="!CL!" (
- Set "CL=/D !CL:{/D={!"
- ))
- Rem,
- REM, Alt 174 '«' and Alt 175 '»'
- REM, « equivalent to -# ; decrements array index ; assigns stored value at array index to the pointer
- REM, » equivalent to +# ; increments array index ; assigns stored value at array index to the pointer
- REM, CONSTRAINTS: « and » cannot be used as literal strings
- Set "_=!_:┐«=┐a«!" & Set "CL=!CL:«=-#!"
- Set "_=!_:┐»=┐a»!" & Set "CL=!CL:┐»=┐a»!"
- Set "_=!_:└«=└a«!" & Set "CL=!CL:└«=└a«!"
- Set "_=!_:└»=└a»!" & Set "CL=!CL:└»=└a»!"
- Set "_=!_:«=-#!" & Set "CL=!CL:«=-#!"
- Set "_=!_:»=+#!" & Set "CL=!CL:»=+#!"
- Rem,
- Rem, Alt 191 '┐' and alt 192 '└'
- REM, ┐ equivalent to d@ ; decrements value of the pointer and stores it at the current array index
- REM, └ equivalent to i@ ; increments value of the pointer and stores it at the current array index
- REM, CONSTRAINTS: ┐ and └ cannot be used as literal strings
- Set "_=!_:┐=d@!" & Set "CL=!CL:┐=d@!"
- Set "_=!_:└=i@!" & Set "CL=!CL:└=i@!"
- Rem,
- REM, IMPLICIT: ┐« └« ┐» └» each assume output of indexed unicode character between value changes.
- Rem, - Equivalents: ┐« = d@a-#
- Rem, └« = i@a-#
- Rem, ┐» = d@a+#
- Rem, └» = i@a+#
- Rem,
- Rem, Alt 139 ï
- REM, ï Equivalient to ii ; increments the value held by the pointer twice
- REM, CONSTRAINTS: ï cannot be used in literal string
- Set "_=!_:ï=ii!" & Set "CL=!CL:ï=ii!"
- REM,
- REM, EXAMPLE shorthand program: 95 64‡(i└»i└«:13)
- REM, prints: aBcDeFgHiJkLmNoPqRsTuVwXyZ
- REM,
- REM,===========================================================================================================
- REM .bs file parsing preperation / execution.
- If "!PATHEXT!"=="!PATHEXT:.bs=!" Set "PATHEXT=!PATHEXT!;.bs"
- If "!PATH!"=="!PATH:%~dp0=!" Set "PATH=!PATH!;%~dp0"
- If /I "!_:~-3!"==".bs" Where *!_! 2>&1 | %SystemRoot%\System32\findstr.exe /li "pattern" > nul && (
- Call:FlagError "File could not be Found."
- Goto:EndRun
- )
- Set "BatchStaxSource="
- Set "_" 2>&1 | %SystemRoot%\System32\findstr.exe /EIL ".BS" > nul && For /f "delims=" %%G in ('Where *!_! 2^> nul')Do (
- Set "BatchStaxSource=%%~G"
- )
- If defined BatchStaxSource (
- For /f "usebackQ tokens=1 Delims=\" %%G in ("!BatchStaxSource!")Do (
- If "!!"=="" ENDLOCAL
- Setlocal DISABLEdelayedExpansion
- If not "%%~G"=="" Call "%~f0" %%G
- If Errorlevel 1 (
- Echo Error in Sourcefile "!BatchStaxSource!"
- Pause
- Exit /b
- )
- Endlocal
- )
- Endlocal
- Exit /b
- )
- cls (Title )
- Rem Define backspace to permit output of leading whitespace without newline.
- For /F %%# in ('"Prompt;$H;&For %%_ in (1) Do Rem"') Do Set "\b=%%#"
- :# Windows Version control for VT sequences. Assigns flag true if system is windows 10 build GTR 10586
- :# https://en.wikipedia.org/wiki/ANSI_escape_code#DOS,_OS/2,_and_Windows
- :# Version 1511 build number = 10.0.10586
- Set "Win10="
- For /f "tokens=3 delims=." %%v in ('Ver')Do if %%v GTR 10586 Set "Win10=True"
- :# If Win10 true ; Test if virtual terminal codes enabled ; enable if false
- :# removes win10 flag definition if version does not support Virtual Terminal sequences
- :# Reg values: https://devblogs.microsoft.com/commandline/understanding-windows-console-host-settings/
- If defined Win10 (
- Reg Query HKCU\Console | %SystemRoot%\System32\findstr.exe /LIC:"VirtualTerminalLevel REG_DWORD 0x1" > nul || (
- Reg Add HKCU\Console /f /v VirtualTerminalLevel /t REG_DWORD /d 1
- ) > Nul && (
- Echo(CMD restart required to enable Virtual terminal sequences.
- Pause
- EXIT
- ) || Set "Win10="
- )
- If not defined Win10 (
- Echo( Some features of this interpreter are not avialable on your system.
- Echo( Output may not match expected Output where Virtual Terminal commands are used.
- Timeout /T 1 /NoBreak > nul
- Pause
- Cls
- )
- If defined win10 For /f %%e in ('Echo Prompt $E^|cmd')Do Set "\E=%%e"
- REM Strip doublequotes from the string prior to Substring parsing.
- Set ^"_=!_:"=!"
- Rem Optional input Argument Parsing. Defines an array of arguments, Substitutes all instances of arg index referenced by $_Index in commandline
- Set "Arg[i]="
- If not "!_:?=!"=="!_!" (
- Set "Arg[i]=0"
- )
- If Defined Arg[i] Set "[A!Arg[i]!]=%_:?=" & Set /A "Arg[i]+=1" & Set "[A!Arg[i]!]=%"
- REM removes trailing Args from command line after parsing if present.
- If Defined Arg[i] Set "_=%_:?="&Rem::%
- If Defined Arg[i] For /l %%n in (1 1 !Arg[i]!)Do If defined [A%%n] (
- If "![A%%n]:#=!"=="![A%%n]!" (%= Argument is prepopulated =%
- For /f "UsebackQ delims=" %%v in (`CMD /C ^"Set /A "![A%%n]!"^"`)Do (
- Set /a "1/%%v","1/(1/((%%v>>32)-1))" 2> nul || (
- Call:FlagError "Invalid input for Argument %%n: '?![A%%n]!'='%%v'. Positive Integer Required."
- Goto:EndRun
- )
- Set "_=!_:$_%%n=%%v!"
- Set "[A%%n]=%%v"
- )
- ) Else (%= Argument is input request =%
- Set "input="
- Set "MaxIn=![A%%n]:#=!"
- If defined MaxIn Set "MaxIn=!MaxIn: =!"
- If defined MaxIn Echo(!MaxIn!| %SystemRoot%\System32\findstr.exe /R "[^1234567890]" > nul && (
- Call:FlagError "Invalid Argument value for input request %%n: "!MaxIn!". Positive integer required" > Con
- Goto:EndRun
- )Else Set "MaxIn=2147483647"
- For /l %%z in (0 1 99)Do if not defined input (
- Set /P "input=Enter Input %%n (Integer LEQ !MaxIn!): " > Con
- Set /a "input=!input!+0","1/input","1/(1/((input>>32)-1))","1/(MaxIn/Input)" 2> nul || (
- Echo(Invalid input. > Con
- Set "input="
- )
- )
- Set "[A%%n]=!input!"
- Cls
- If not defined input set "input=1"
- (Echo(Input %%n: !input!) >>"%~f0:Dev.log"
- For /f "Delims=" %%G in ("!input!")Do Set "_=!_:$_%%n=%%G!"
- )
- )
- Set "Spacing="
- For /l %%i in (1 1 1000)Do Set "Spacing=!Spacing! "
- Rem catch use of /D switch without command list or other args
- If not defined _ Goto:Syntax
- >"%~f0:Dev.log" (
- Echo(============================================================================================================
- Echo( Command Line : !CL!
- )
- If defined devmode >>"%~f0:Dev.log" 2> nul (
- For /f "Tokens=1,2* Delims==" %%G in ('Set [A')Do If NOT "%%G"=="[A0]" Echo(%%G : %%H
- )
- Set ^"_=!_:"=!"
- Set "_=!_:`(=//O!"
- Set "_=!_:`)=//C!"
- Set "_=!_:`:=//S!"
- Set "_=!_: {={!"
- Set "_=!_: (=(!"
- Set "_=!_: )=)!"
- Set "_=!_:} =}!"
- Set "Array?="
- Rem test {ArrayList;Index} usage; assign Stack array and Index if valid syntax and trailing command list.
- Rem flag Syntax Errors. Outer if condition prevents parsing error for unqouted commandlines beginning with "("
- If Not "!_:;=!"=="!_!" If Not "!_:}=!"=="!_!" If Not "!_:~0,1!"=="{" If not "!_:~0,1!"=="`" (
- Call:FlagError "Missing Opening curly brace '{' in Command Line: '!_!'"
- Goto:EndRun
- )
- If NOT "!_:~0,1!"=="(" (
- If "!_:~0,1!"=="{" (
- If "!_:}=!"=="!_!" (
- Call:FlagError "Missing Closing curly brace '}' in Command Line"
- Goto:EndRun
- )
- Set "Array?=%CL:}=}"&Rem ::%
- If not "!_:;=!"=="!_!" (
- If not "!_:}=!"=="!_!" (
- For /f "tokens=1,2,3 delims={;}" %%G in ("!_!") Do (
- Set "Stack=0"
- For %%i in (%%G)Do (
- Set /A "stack+=1,stack[!stack!]=%%i"
- )
- If not %%H GTR !Stack! (
- If not %%H LSS 0 (
- Set /A "Stack=%%H" 2> nul
- )Else (
- Call:FlagError "Stack outside array boundary OR missing array / index in {arraylist;index}"
- Goto:EndRun
- )
- ) Else (
- Call:FlagError "Stack outside array boundary OR missing array / index in {arraylist;index}"
- Goto:EndRun
- )
- If "%%I"=="" (
- Call:FlagError "Command list Required."
- Goto:EndRun
- )
- Set "_=%%I"
- )
- Set /A v=Stack[!stack!]
- )Else (
- Call:FlagError "Closing '}' missing in arg string"
- Goto:EndRun
- )
- )Else (
- Call:FlagError "{ArrayList;index} sepererator ';' missing in arg string"
- Goto:EndRun
- )))
- Set /A "Loop=0"
- REM Parse loops in arg
- Set /A "O_P=C_P=S_C=B_T=E_A=0"
- Set "null=%_:`=" & Set /A "B_T+=1" & Set "null=%"
- Set "null=%_:(=" & Set /A "O_P+=1" & Set "null=%"
- Set "null=%_:)=" & Set /A "C_P+=1" & Set "null=%"
- Set "null=%_::=" & Set /A "S_C+=1" & Set "null=%"
- Set "null=%_::)=" & Set /A "L_R+=1" & Set "null=%"
- If !L_R! GTR 0 (
- Call:FlagError "Missing Command Token: Loop repeat Value absent in (Command:RepeatCount) Usage."
- Goto:EndRun
- )
- If !O_P! GTR !C_P! (
- Call:FlagError "Missing Closing parentheses in Command Line. Opening:!O_P! Closing:!C_P!"
- Goto:EndRun
- )
- If !C_P! GTR !O_P! (
- Call:FlagError "Missing Opening parentheses in Command Line. Opening:!O_P! Closing:!C_P!"
- Goto:EndRun
- )
- If not "!O_P!!C_P!"=="00" (
- 2> nul Set /A "Seperators=((O_P + C_P) / S_C)"
- If !Seperators!0 NEQ 20 (
- Call:FlagError "Error - Invalid loop syntax, unbalanced ':' Seperator in Command Line. Loops:!O_P! Seperators:!S_C!. If a literal string" /N
- Call:FlagError "... precedes the ':' Seperator, delimit literal string and seperator using a comma or whitespace. IE: (`this`,:3)" /N
- Goto:EndRun
- )
- )Else (%= Command Contains no loops. Skip Loop parsing. =%
- If !B_T! EQU 0 If !S_C! GTR 0 (
- Call:FlagError "Invalid ':' Usage. Use with parentheses to demark loop: '(Commands:Integer)'"
- Call:FlagError "Invalid ':' Usage. Use backticks to indicate string literal: `String:String`"
- Goto:EndRun
- )
- Goto:SkipBuildReps
- )
- :BuildReps
- Set "Last_=!_!"
- Set "Lead=" & Set "Trail=" & Set "Replace="
- If not "!_:(=!"=="!_!" Set "Lead=!_:*(=!"
- For /L %%i in (0 1 10)Do If defined Lead Set "Lead=!Lead:*(=!"
- If defined Lead Set Lead | %SystemRoot%\System32\findstr.exe /lic:")" > nul || (
- Call:FlagError "Malformed Loop Syntax - Missing ')' in Command Line"
- Goto:EndRun
- )
- If defined Lead Set Lead | %SystemRoot%\System32\findstr.exe /lic:":" > nul || (
- Call:FlagError "Malformed Loop Syntax - Missing ':' in Command Line"
- Goto:EndRun
- )
- If Defined Lead Set "Trail=%Lead:)="&Rem::%
- If Defined Lead Set "Lead=%Lead:)="&Rem::%
- If defined Lead For /f "tokens=1,2 Delims=:" %%G in ("!Lead!")Do (
- Set "Lead=%%G"
- Set "Trail=%%H"
- )
- Set "Replace="
- If defined Trail Echo(!Trail!|%SystemRoot%\System32\findstr.exe /XR "[123456789][0123456789]*" > nul && (
- For /l %%i in (1 1 !Trail!)Do (
- Set "Replace=!Replace!!Lead!"
- If not "!Replace:~3750,1!"=="" (
- Call:FlagError "Parsed Command line exceeds supported length. 3750 character limit applies"
- Echo( Parse State: "!_!" >>"%~f0:Dev.log"
- Echo( Attempted Parse Action: "(!Lead!:!Trail!)=!Replace!" >>"%~f0:Dev.log"
- Goto:EndRun
- )
- )
- ) || (
- Call:FlagError "Invalid Command token For Loop RepeatCount ':!Trail!' - Positive Integer Required."
- Goto:EndRun
- )
- If Defined Replace Set "_=!_:(%Lead%:%Trail%)=%Replace%!"
- If /I not "!Last_!"=="!_!" (
- Set /A Loop += 1
- If defined devmode (
- Echo(Loop parse [!Loop!] : !REG3XP0!>"(!Lead!:!Trail!)" >>"%~f0:Dev.Log"
- Echo(Parse state : "!_!" >>"%~f0:Dev.Log"
- )
- Goto:BuildReps
- )
- :SkipBuildReps
- REM updated parsing method to permit use of string literals by using '`' to flag start and end of a literal string
- Set /A "1 / (B_T %% 2)" 2> nul && (
- Call:FlagError "Unpaired Literal delimiters '`' in Command Line. Escape Literal '(' and ')': '`(' or '`)'"
- Goto:EndRun
- )
- Set "Parse="
- Set "Isliteral="
- Set "DQstate=0"
- For /l %%i in (0 1 8000)Do If not "!_:~%%i,1!"=="" (
- Set "Char=!_:~%%i,1!"
- If /I "!_:~%%i,1!"=="`" (
- Set "IsLiteral=true"
- 2> nul Set /a 1/DQstate && (
- Set ^"Parse=!Parse!""
- Set /a "DQstate=0"
- ) || (
- Set ^"Parse=!Parse! ""
- Set /a "DQstate=1"
- )
- )Else (
- If "!DQstate!"=="0" (%= Token is Command =%
- Set "Char=!Char:$=# a !"
- Set "Char=!Char:_=i a !"
- Set "Parse=!Parse! !Char!"
- )Else (%= Token forms part of a Literal String =%
- If not "!Char!"=="*" (
- Set "Parse=!Parse!!Char!"
- )Else Set "Parse=!Parse!//A"
- )
- )
- )
- Set "_=!Parse!"
- REM Golfing feature: Any program comprised of a single valid command is a quine - Excludes $ and _ .
- If /I not "!_: =!"=="!_!" (
- If /I "!_:~2,1!"=="" (
- <nul Set/p "=.%\b%!_: =!"
- Goto:EndRun
- )
- )
- Set "args=!_!"
- If not defined Stack set Stack=0
- If not defined v Set v=0
- REM define Arithmetic command Macros. Approximations used due to Integer Limitation.
- REM r = Square root ; i = increment ; d = decrement ; s = square ; z = zero ;
- REM h = half ; t = double ; . = Mulitply by 10 ; p = Mulitply by Pi
- set r="v=( M=(v), x=M/(11*1024)+40, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
- Set i=v+=1&Set d=v-=1&Set s=v*=v&Set z=v=0&Set h=v/=2&Set t=v*=2&Set .=v*=10
- Set p="v=(v*3142)/1000"
- >>"%~f0:Dev.log" (
- Echo(Parsed CL : !Array?!!args!
- Echo(Parsed Loops : !Loop!
- )
- Set "tops=0"
- 2>nul (%!! command;Else Output =%
- If not Defined CommandError For %%i in (!args!)Do If not "%%~i"=="" (
- Set "outv= Output: ``"
- Set "CMDTKN=%%~i"
- Set "CMDTKN=!CMDTKN://A=*!"
- If not defined stack Set "stack=0"
- For %%v in (!Stack!)Do If "!stack[%%v]!"=="" Set /A stack[!stack!]=v+0
- Set /A tops+=1
- If /i "%%~i"=="A" (
- If defined Uni[!v!] (
- For /f delims^= %%v in ("!v!")Do (
- <nul Set /p ^"=.%\b%!Uni[%%v]!"
- Set ^"outv= Output: '!Uni[%%v]!'"
- )
- )
- )Else If /i "%%~i"=="N" ( Echo(%= Newline =%
- )Else If /i "%%~i"=="W" ( For %%v in (!v!)Do <nul set /p "=.%\b%!Spacing:~-%%v!"
- )Else If /i "%%~i"=="5" ( If defined win10 <nul set /p"=%\E%[5m" %= Set Cursor Blinking; No Equivelant non VT command =%
- )Else If /i "%%~i"=="2" ( If defined win10 <nul set /p"=%\E%[B" %!!%
- )Else If /i "%%~i"=="4" ( If NOT defined Win10 <nul set /p"=%\b%" %= Cursor Left - Destructive =%
- If defined win10 <nul set /p"=%\E%[D" %= VT Cursor Left - Non Destructive =%
- )Else If /i "%%~i"=="6" ( If NOT defined Win10 <nul Set /p"=.%\b% " %= Cursor Right - Destructive =%
- If defined win10 <nul set /p"=%\E%[C" %= VT Cursor Right - Non Destructive =%
- )Else If /i "%%~i"=="8" ( If defined win10 <nul set /p"=%\E%[A" %!!%
- )Else If /i "%%~i"=="1" ( If defined win10 <nul set /p"=%\E%8" %= VT Restore cursor position from memory =%
- )Else If /i "%%~i"=="7" ( If defined win10 <nul set /p"=%\E%7" %= VT Save Cursor position in memory =%
- )Else If /i "%%~i"=="C" ( If defined win10 <nul set /p"=%\E%[1;1H" %= VT Move Cursor Home =%
- )Else If /i "%%~i"=="B" ( If defined win10 <nul set /p "=%\E%[48;5;!v!m" %= VT Set background color to current pointer value =%
- )Else If /i "%%~i"=="F" ( If defined win10 <nul set /p "=%\E%[38;5;!v!m" %= VT Set foreground color to current pointer value =%
- )Else If /i "%%~i"=="~" ( If NOT defined win10 Color 07 %= Color Reset - Whole of screen =%
- If defined win10 <nul set /p "=%\E%[0m" %= Color Reset - restores default color for any subsequent output =%
- )Else If /i "%%~i"=="J" ( If NOT defined win10 CLS %= Whole screen Clear =%
- If defined win10 <nul set /p "=%\E%[0J" %= Clear screen from cursor location =%
- )Else If /i "%%~i"=="+" ( Set /A "stack+=1" %= PUSH =%
- )Else If /i "%%~i"=="-" ( %= POP - Prevents Negative stack indexes. =%
- If NOT !stack!==0 (
- Set /A stack-=1
- )Else (
- Set "outv= Error : 'OOB'"
- )
- )Else If /i "%%~i"=="@" ( Set /a "stack[!stack!]=v" %= Store pointers [rVal] value in the current stack =%
- )Else If /i "%%~i"=="#" ( Set /a "v=stack[!stack!]" %= Assign value stored in the current stack to the pointer =%
- )Else If /i "%%~i"=="]" ( Set /a "v+=stack[!stack!]+0" %= Increment the pointer with the value stored in the current stack =%
- )Else If /i "%%~i"=="[" ( Set /a "v-=stack[!stack!]+0" %= Decrement the pointer with the value stored in the current stack =%
- )Else If /i "%%~i"=="Q" ( %= Quit processing if the value stored in the current stack equals the Pointers current value =%
- For %%v in (!Stack!)Do If !v!==!Stack[%%v]! Goto:EndRun
- )Else If not "!CMDTKN::=!"=="!CMDTKN!" ( %!!%
- Set "CMDTKN=!CMDTKN://S=:!"
- Set "CMDTKN=!CMDTKN://O=(!"
- Set "CMDTKN=!CMDTKN://C=)!"
- <nul Set /p"=.%\b%!CMDTKN!"
- If defined DevMode (
- Set "outv= Output: '!CMDTKN!'"
- )
- )Else (
- Set/A!%%~i! 2>nul|| ( %= Attempt to perform Arithmetic command using command macros. =%
- If /I "%%~i"=="o" ( %= If fail; check if command equ output =%
- <nul Set /p"=!v!"
- )Else If "!CMDTKN:~0,1!"=="" ( %= Output current pointer value if command token empty =%
- <nul Set /p"=!v!"
- )Else ( %= Output Literal strings containg Exclamation marks =%
- Set "CMDTKN=!CMDTKN://S=:!"
- Set "CMDTKN=!CMDTKN://O=(!"
- Set "CMDTKN=!CMDTKN://C=)!"
- CMD /C Exit 33
- CALL Set "CMDTKN=!CMDTKN:XCLM=%%=EXITCODEASCII%%!"
- <nul Set /p"=.%\b%!CMDTKN!"
- If defined DevMode (
- Set "outv= Output: '!CMDTKN!'"
- )
- )
- )
- )
- If defined devmode ( %= Enact additional Command Logging =%
- Set "Stackarray="& If not Defined outv Set "outv=| Output: ``"
- For %%v in (!stack!)Do ( If "!stack[%%v]!"=="" Set /A "stack[!stack!]=v+0"
- For /f "delims=" %%G in ('Set Stack[')Do For /f "Tokens=2,3 delims=[]=" %%H in ("%%G")Do Set "stackarray=!stackarray!,%%I"
- If /I "%%~i"=="O" (
- Set "outv= Output: '!v!'"
- )Else If /I "%%~i"=="N" (
- Set "outv= Output: '\n'"
- )
- >>"%~f0:Dev.log" Echo({Cmd: %%~i ; !tops! } ^| Val:!v! ^| Stack %%v: !Stack[%%v]! ^|!Outv! ^| Stacks: !stackarray:~1!
- ))))
- :EndRun
- If not Defined CommandError (%= Pause if program completed succesfully =%
- Title Press any key to continue
- If not defined ExampleMode Pause > nul
- )
- (Title )
- Echo(
- Endlocal & Endlocal & Set "DevMode=%DevMode%" & Set "rVal=%v%"
- If defined DevMode (
- For /f "Delims=" %%G in ('more ^< "%~f0:Dev.log"')Do Echo(%%G
- )
- Exit /b 0
- :Syntax
- for /F %%a in ('Echo(prompt $E^| cmd')Do Set \E=%%a
- SETLOCAL DISABLEdelayedexpansion
- Echo =============================================================================================================
- Echo BatchStax by T3RRY
- Echo( %~n0 Syntax
- Echo( %~n0 [/D] [{ArrayList;Index}^|ArrayList;Index‡] [(commands:RepeatCount)][commands] [?IntArg/s] [?#MaxInt]
- Echo( Commands: $ A B C D F H I J N O P Q R S T U Z @ # [ ] + - 1 2 4 6 7 8 ~ . `literal string`
- Echo(
- Echo * [type] denotes an optional command, loop switch or arguments - note: If {ArrayList;int} is used, it must preceed the command list.
- Echo * ArrayList denotes a comma seperated list of initial stack values, followed by a ';' seperated Index[integer]
- Echo to declare the Stack location in which to commence. See examples below.
- Echo * (Commands:RepeatCount) ; where RepeatCount is an Integer: Repeat command group enclosed within parentheses
- Echo Integer times.
- Echo ** NOTE: Nested loops are now supported.
- Echo( Stack position and rVal are not implicity modified when a loop is enacted; Commands must
- Echo be used to Ensure stack location and rVal have the values necessary to achieve expected output.
- Echo - note example 2, and how the final 2 commands are used to prepare for the next loop iteration.
- Echo(
- Echo /D : switch ; Enables log output
- Echo `Literal String` : text between backticks denotes literal text to output.
- Echo - Valid single character Commands overide flagging of literal state.
- Echo - Literal use of '(', ':' and ')' require escaping using '`'
- Echo( Examples: ``(` or ``(and`)`
- Echo( - Failure to escape Parentheses for literal output may result in Unbalanced '`', ':', '(' or ')' Errors
- Echo( ?IntArg/s : One or more Integer or Integer Arithmetic expressions used as input for the preceeding command set, delimited by a ? prefix.
- Echo( Args, if used, must terminate the command line (/D switch excepted).
- Echo( The Integer argument or the result of the Arithmetic expression must be positive a positive Integer.
- Echo( Args can be referenced in the command line using $_index. $_1 To reference the first arg, $_2 the second and so on.
- Echo( Argument order is left to right. ?IntArgs may refer to previous input arguments Using [Aindex] - See below example.
- Echo( [?#MaxInt] : Request user input, constrained to a positive integer below Integer value provided: IE ?#50 accepts any integer from 1 to 50.
- Echo( See example 7.
- Echo(
- Echo( [?u] or [¿] : Similar to ?#MaxInt, however Maximum value is capped at 239, limiting input to the range of unicode/ascii character indices.
- REM Additional example: takes 5 inputs, Prints a diamond with an asterisk at its heart. First four inputs - '¿' define the unicode/ascii
- REM character to be used for each side, final input determines the length of each side - ?#Max.
- REM ¡1,¡2,¡3,¡4‡6(2:¡5)(8a:¡5)»(2a:¡5)»(2ª:¡5)7»(8ª:¡5)(6:¡5)4`*`1~¿¿¿¿?#25
- Echo(
- Echo Arithmetic commands:
- Echo 'I' + 1 'D' - 1
- Echo 'T' * 2 'H' / 2
- Echo 'P' * Pi '.' * 10
- Echo 'S' Square 'R' sqRoot
- Echo 'Z' rVal = 0
- Echo * '[' and ']' operations are described in Stack based commands below.
- Echo(
- Echo Virtual Terminal commands:
- Echo 'J' Clear the screen from the current cursor position
- Echo ** If Virtual terminal unsupported, Clears the entire screen
- Echo 'C' Move the Cursor to screen home.
- Echo 'B' Backgound color = 48;5;rVal
- Echo 'F' Foregound color = 38;5;rVal
- Echo '~' Reset Background and Foregound color to default.
- Echo '7' Save cursor position
- Echo '1' Restore cursor from saved position
- Echo '5' Set cursor blinking
- Echo '8' Cursor Up
- Echo Cursor Left '4' '6' Cursor Right
- Echo '2' Cursor Down
- Echo(
- Echo Output commands:
- Echo 'O' Output rVal as integer
- Echo 'A' Output ASCII or Unicode character for decimal value of rVal if within range: 1-239
- Echo - See: https://www.asciitable.com/
- Echo '$' Abbreviation of '#A'
- Echo 'N' Output Newline
- Echo 'W' Output rVal Spaces at the current cursor position.
- Echo(
- Echo Stack based commands:
- Echo A note regarding Stacks:
- Echo - 'Stacks' in this script are a group of associated variables
- Echo that may be used as memory to store or retrieve values. Changing stack index using '+'
- Echo or '-' changes the variable being used as the storage / retrieval 'location'.
- Echo - Stacks are assigned the current rVal on creation, or the array values when {ArrayList:Index}
- Echo is used to predefine stacks.
- Echo 'Q' Test if rVal is EQU current stack Value. Terminates if true
- Echo '+' Push ; increment stack counter
- Echo '-' Pop ; decrement stack counter
- Echo '@' Save current rVal to current stack index.
- Echo '#' Assign current stack value to rVal [retrieve]
- Echo ']' Add value stored in current stack to rVal
- Echo * if last operation was '@' or '+' creating a new stack, this is equivalent to doubling rVal
- Echo '[' Subtract value stored in current stack from rVal
- Echo * if last operation was '@' or '+' creating a new stack, this is equivalent to setting rVal to 0
- Echo(
- Echo Example 1 - Print: "Hello World!"
- Echo= %~f0 `Hello World!`
- Echo(
- Echo Example 2 - Print: "Hello World!" Three times with trailing newline
- Echo= %~f0 (`Hello World!`n:3)
- Echo(
- Echo Example 3 - Print "Hello World!" diagonally 0,0 to 11,11
- Echo= %~f0 ip@p+pd+]]-[a+]--]d2a+]dd2a2a-]][2a++[[[ï2a]]i2a]ddd2a--]2a[[2a+[i2arpï2a
- Echo(
- Echo Example 4 - Print "COCA COLA!"
- Echo= %~f0 {33,65,67,79,32,76;2} $+$-$-$+++$--$+$++$----$-$
- Echo(
- Echo Example 5 - Print: "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
- Echo= %~f0 62,32‡ï▀+]a([-▀+]a:25)
- Echo(
- Echo Nested loops are supported, to an expanded command length of 3750 characters. Examples:
- Echo Example 6 - nested loop - Print a stepped pyramid, alternating colors.
- Echo= %~f0 124,45‡(6:21)(2»f«a4'42ƒ4:7)n8(8a8»ƒa«f:7)»a«(»ƒa«f2a2:7)~
- Echo(
- Echo( Example 7 - (same as example 6, except uses Argument input to vary Loop repetitions and change output size):
- Echo= %~n0 124,45‡(6:¡2)(2»f«a4'42ƒ4:¡1)n8(8a8»ƒa«f:¡1)»a«(»ƒa«f2a2:¡1)~?#30?[A1]*3
- Echo(
- Echo Example 8 - nested loop - Draw a box, emit newline, repeat twice
- Echo= %~f0 61,124‡((a:5)»(24a:4)«4a(ª:5)»(84a:3)(n:5)«:2)
- Echo(
- Echo Example 9 - nested loop - Print all ASCII characters in blue from 32-123 as a column 5 characters wide
- Echo change color to pink; move cursor to screen home and print in another
- Echo column in reverse order. Reset forground color to white at end of commandline.
- Echo= %~f0 32‡f((▄:5)n:19)C(6:6)f((da:5)n(6:6):19)~
- Echo(
- Echo Example 10 - nested loop - Draw a blue Ascii art Comet:
- Echo= %~f0 32,33,42‡-((»f«ai@:2)2:48)++4$86a22a4ª8a6a~
- Echo(
- Echo Example 11 - command "5" set cursor graphical mode to blinking. command "~" restores cursor graphical defaults
- Echo= %~f0 33 176‡((«5ƒ~2»ƒ8:5)nn:5)~
- Echo(
- Echo Example 12 - Command logging: [deliberately malformed command - unbalanced parentheses]
- Echo= %~f0 /D ((▀:4)o:3)((ad:3)o):2)
- Echo(
- Echo =============================================================================================================
- ENDLOCAL
- Timeout /t 1 /NoBreak > nul
- Pause
- Cls
- For /l %%i in (0 1 5)Do if "!!"=="" Endlocal
- Setlocal DisableDelayedExpansion
- Set "ExampleCount=0"
- Choice /N /C:YN /M "View example outputs Y/N?"
- If %Errorlevel% EQU 1 (
- Set "exampleMode=1"
- For /f "tokens=2 Delims==" %%G in ('%SystemRoot%\System32\Findstr.exe /blic:" Echo=" "%~f0"')Do (
- Set /A "ExampleCount+=1"
- Setlocal DisableDelayedExpansion
- Set "Example=%%G"
- REM CMD /V:ON /C "Title Example: !ExampleCount! = !Example:*%%~f0=!"
- Rem Secondary call is used to expand literal %~f0 to this files filepath
- 2> nul Set /A "1/(ExampleCount-12)" || (
- Cls
- Echo(The next example Shows an example of error output When invalid syntax is used.
- Pause
- )
- Call call %%G
- Setlocal EnableDelayedExpansion
- Echo(%\E%7%\E%[1;1H%\E%[1TExample: !ExampleCount! = !Example:*%%~f0=%~nx0!%\E%8
- Endlocal
- Choice /C:nq /M "[N]ext [Q]uit"
- If errorlevel 2 (Endlocal & Endlocal & Exit /b 1)
- (Call )
- Endlocal
- )
- )
- Endlocal
- Exit /b 0
- ====================================================================================================================
- :FlagError <ErrorMessage>
- Set "ErrorMessage=%~1"
- If defined Devmode (
- Set "ErrorMessage= ** Error: !ErrorMessage:)=^)!"
- ) Else Set "ErrorMessage= ** Error: !ErrorMessage!"
- If not "%~2"=="" Set "ErrorMessage=!ErrorMessage:Error: =!"
- If defined Devmode (
- (
- If "%~2"=="" Echo(============================================================================================================
- (Echo( !ErrorMessage:^^=!)
- If /I Not "%~2"=="/N" Echo(============================================================================================================
- ) >> "%~f0:Dev.log"
- ) Else (
- If "%~2"=="" Echo(============================================================================================================
- If "%~2"=="" Echo( Command Line: !CL!
- If "%~2"=="" Echo(============================================================================================================
- (Echo( !ErrorMessage:^^=!)
- If /I Not "%~2"=="/N" Echo(============================================================================================================
- ENDLOCAL
- )
- )
- Set "CommandError=true"
- Exit /B
- :# The below line Marks the end of a Powershell comment Block; And the End of the Batch Script. Do not Modify.
- : end batch / begin powershell #>
- <#
- Test if input Argument -eq ToggleFs
- If true uses sendKeys to force fullscreen.
- #>
- $InitW = $Host.UI.RawUI.WindowSize.Width
- $InitH = $Host.UI.RawUI.WindowSize.Height
- $Mode -eq 'ToggleFS' >$null
- If ($Mode -eq "ToggleFS") {
- Add-Type -AssemblyName System.Windows.Forms
- [System.Windows.Forms.SendKeys]::SendWait("{F11}")
- $CurrentW = $Host.UI.RawUI.WindowSize.Width
- $CurrentH = $Host.UI.RawUI.WindowSize.Height
- If ($InitW -ge $CurrentW) {
- If ($InitH -ge $CurrentH) {
- [System.Windows.Forms.SendKeys]::SendWait("{F11}")
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement