Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @Echo off
- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- REM Esolang: BatchStax by T3RRY ; loosely based off isdo. See syntax for valid operations.
- REM This script is an interpreter for BatchStax, and includes limited debugging tools and error checking.
- :::
- ::: Version 1.4
- REM VERSION Change 21/12/2021: Added LIMITED support for Nested loops - See updated Syntax.
- REM Added
- 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/
- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- Set "CL=%*"
- Set "_=%*"
- set "_" 2>&1 | %systemroot%\system32\findstr.exe /li "\/? -? help syntax defined" > nul && (
- Mode 1000
- Call :Syntax
- Goto:Eof
- )
- If exist "%~1" (
- For /f "usebackq Delims=" %%G in ("%~1")Do (
- Setlocal
- Call "%~f0" %%G
- If Errorlevel 1 (
- Echo Error in Sourcefile "%~1"
- Pause
- Exit /b
- )
- Endlocal
- )
- Exit /b
- )
- Mode 1000 & Cls (Title )
- Rem add a value to the below devmode variable definition to track operations during runtime, or use switch /D
- Set "devmode="
- Rem Define backspace to permit output of 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.
- Pause
- Cls
- )
- If defined win10 For /f %%e in ('Echo Prompt $E^|cmd')Do Set "\E=%%e"
- Setlocal EnableDelayedExpansion
- Set "Spacing="
- For /l %%i in (1 1 1000)Do Set "Spacing=!Spacing! "
- Set ^"_=!_:"=!"
- Set "_" | %SystemRoot%\System32\Findstr.exe /lic:"\/D" > nul && (
- Set "_=!_: /D =!"
- Set "_=!_:/D =!"
- Set "_=!_: /D=!"
- Set "_=!_:/D=!"
- Set devmode=true
- )
- Rem catch use of /D switch without command list
- If not defined _ Goto:Syntax
- Set "Array?="
- Rem test {Array;Index} usage; assign Stack array and Index if valid syntax and trailing command list.
- Rem flag Syntax Errors.
- If "!_:~0,1!"=="{" (
- Set Array?=%CL:}=}&::%
- 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 (
- Echo Stack outside array boundary OR missing array / index in {arraylist;index} & Endlocal & Pause & Exit /b
- )
- ) Else (
- Echo(Stack outside array boundary OR missing array / index in {arraylist;index} & Endlocal & Pause & Exit /b
- )
- If "%%I"=="" (
- Echo(Command list Required & Endlocal & Pause & Exit /b
- )
- Set "_=%%I"
- )
- Set /A v=Stack[!stack!]
- )Else (
- Echo( Closing '}' missing in arg string.
- Endlocal & Pause & Exit /B 1
- )
- )Else (
- Echo( {array;index} sepererator ';' missing in arg string.
- Endlocal & Pause & Exit /B 1
- )
- )
- set "_=!_: =!"
- Set "ErrCounter=0"
- :BuildReps
- Set /A ErrCounter += 1
- Set "Search=" & Set "Replace="
- If not "!_:(=!"=="!_!" If not "!_:)=!"=="!_!" (
- For /f "tokens=1,2,3 delims=(:)" %%G in ("!_!")Do Set /A "1/%%H" 2> nul && (
- Set "Search=(%%G:%%H)"
- For /L %%i in (1 1 %%H)Do (
- Set "Replace=!Replace!%%G"
- If not "!Replace:~3750,1!"=="" (
- Echo Warning^^! Command line exceeds supported length.
- Endlocal & Pause & Exit /B 1
- )
- )
- ) || Set /A "1/%%I" 2> nul && (
- Set "Search=(%%H:%%I)"
- For /L %%i in (1 1 %%I)Do (
- Set "Replace=!Replace!%%H"
- If not "!Replace:~3750,1!"=="" (
- Echo Warning^^! Command line exceeds supported length.
- Endlocal & Pause & Exit /B 1
- )
- )
- )
- )
- If Defined Search If Defined Replace Set "_=!_:%Search%=%Replace%!"
- If not "!_:(=!"=="!_!" If not "!_:)=!"=="!_!" (
- If !ErrCounter! GTR 512 (
- Echo(Error - Malformed use of (Commands:RepeatCount^) syntax in arg string:
- Echo( "!_!"
- Endlocal & Pause & Exit /B 1
- )
- Goto :BuildReps
- )
- Set "_=!_: =!"
- Set "_=!_:$=#A!"
- For %%G in (A B D F H I J N O P Q R S T W Z "+" "-" "@" "#" "[" "]" 1 2 4 6 7 8 ".")Do Set "_=!_:%%~G= %%~G!"
- Set "args=!_!"
- If not defined Stack set Stack=0
- Set "C=Set/A"#"||Set v=0&"
- If not defined v Set v=0
- 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(Command Line: !CL!
- Echo(Parsed CL : !Array?!!args: =!
- )
- Set "tops=0"
- 2>nul (
- For %%i in (!args!)Do (
- For %%v in (!Stack!)Do If "!stack[%%v]!"=="" Set /A stack[!stack!]=v+0
- Set /A tops+=1
- If /i "%%~i"=="A" (
- Set /A "1/(v/32)","1/(126/v)" 2> nul && (
- Cmd /C Exit !v!
- <nul Set /p ^"=.%\b%!=ExitCodeASCII!"
- )
- )Else If /i "%%~i"=="N" (
- Echo(
- )Else If /i "%%~i"=="W" (
- For %%v in (!v!)Do <nul set /p "=.%\b%!Spacing:~-%%v!"
- )Else If /i "%%~i"=="2" (
- If defined win10 <nul set /p=%\E%[B
- )Else If /i "%%~i"=="4" (
- If defined win10 <nul set /p=%\E%[D
- )Else If /i "%%~i"=="6" (
- If defined win10 <nul set /p=%\E%[C
- )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
- )Else If /i "%%~i"=="7" (
- If defined win10 <nul set /p=%\E%7
- )Else If /i "%%~i"=="B" (
- If defined win10 <nul set /p "=%\E%[48;5;!v!m"
- )Else If /i "%%~i"=="F" (
- If defined win10 <nul set /p "=%\E%[38;5;!v!m"
- )Else If /i "%%~i"=="J" (
- If NOT defined win10 CLS
- If defined win10 <nul set /p "=%\E%[2J"
- )Else If /i "%%~i"=="+" (
- Set /A stack+=1
- )Else If /i "%%~i"=="-" (
- Set /A stack-=1
- )Else If /i "%%~i"=="@" (
- Set /a stack[!stack!]=v
- )Else If /i "%%~i"=="#" (
- Set /a v=stack[!stack!]
- )Else If /i "%%~i"=="]" (
- Set /a v+=stack[!stack!]+0
- )Else If /i "%%~i"=="[" (
- Set /a v-=stack[!stack!]+0
- )Else If /i "%%~i"=="Q" (
- For %%v in (!Stack!)Do If !v!==!Stack[%%v]! (Echo 1)Else Echo 0
- )Else (
- Set/A!%%~i! 2>nul||(<nul Set /p"=!v!")
- )
- If defined devmode (
- Set "Stackarray="&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"=="A" (
- Cmd /c Exit !v!
- Set "outv=^| Output: '!=ExitcodeASCII!'"
- )Else 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!
- )
- )
- )
- )
- Title Press any key to continue
- Pause > nul
- (Title )
- Echo(
- 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
- Echo =============================================================================================================
- Echo BatchStax by T3RRY
- Echo Switch Optional Input Commands:
- Echo( %~n0 [/D] [{Arraylist;Index}] $ A B D F H I J N O P Q R S T Z @ # [ ] + - 1 2 4 6 7 8
- Echo(
- Echo %~n0 [/D] [{Arraylist;Index}] [(commands:RepeatCount)][commands]
- Echo(
- Echo * [argument] denotes an optional argument - note: If used {Array;int} must preceede 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:
- Echo Nesting loops are now possible, however:
- Echo * Commands in nested loops Should not begin with 2 4 6 8 + -
- Echo * Loops are identified when the 1st and 2nd or 2nd and 3rd token of the command string delimited
- Echo by '(' ':' and ')' match the pattern: .*:Integer
- Echo If at any step during the parsing of the command argument there occurs a loop not matching this
- Echo pattern, particularly where the secon or third token is not an integer, the nested will be flagged
- Echo will be flagged as invalid.
- Echo
- 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(
- 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 'B' Backgound color = 48;5;rVal
- Echo 'F' Foregound color = 38;5;rVal
- Echo '7' Save cursor position
- Echo '1' Restore cursor from saved position
- Echo '8' Cursor Up
- Echo '4' Cursor Left '6' Cursor Right
- Echo '2' Cursor Down
- Echo(
- Echo Output commands:
- Echo 'Q' Test if rVal is EQU current stack Value. Outputs 0 if false 1 if true
- Echo 'O' Output rVal as integer
- Echo 'A' Output ASCII character for decimal value of rVal if within range: 32-126
- 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 '+' 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= %~n0 ip@p+pd+]]-[a+]--]da+]ddaa-]][a++[[[iia]]ia]ddda--]a[[a+[iarpiia
- Echo(
- Echo Example 2 - Print: "Hello World!" Three times with trailing newline
- Echo= %~n0 "(ip@p+pd+]]-[a+]--]da+]ddaa-]][a++[[[iia]]ia]ddda--]a[[a+[iarpiian-z:3)"
- Echo(
- Echo Example 3 - Print "Hello World!" diagonally 0,0 to 11,11
- Echo= %~n0 ip@p+pd+]]-[a+]--]d2a+]dd2a2a-]][2a++[[[ii2a]]i2a]ddd2a--]2a[[2a+[i2arpii2a
- Echo(
- Echo Example 4 - Print "COCA COLA!"
- Echo= %~n0 {33,65,67,79,32,76;2} $+$-$-$+++$--$+$++$----$-$
- Echo(
- Echo Example 5 - Print: "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
- Echo= %~n0 {62,32;0} iiia+]a([-ia+]a:25)
- Echo(
- Echo Nested loops are unofficially supported [Not thoroughly tested]. Examples:
- Echo Example 6 - nested loops - Print "GFEGFEHIJKHIJKHIJK"
- Echo= %~n0 {72;0} ((da:3)#:2)((ai:4)#:3)
- Echo(
- Echo Example 7 - nested loop - Draw a box, emit newline, repeat:
- Echo= %~n0 {61,124;0} ((a:5)+#(24a:4)-#4a(44a:5)+#(84a:3)(n:5)-#:2)
- Echo(
- Echo Example 8 - 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 top of screen and print in another
- Echo column in reverse order. Reset forground color to white at end of commandline.
- Echo= %~n0 {32,255;0} f((ai:5)n:19)(n88:19)666666f((da:5)n666666:19)+#f
- Echo(
- Echo =============================================================================================================
- Timeout /t 1 /NoBreak > nul
- Pause
- Cls
- Choice /N /C:YN /M "View example outputs Y/N?"
- If %Errorlevel% EQU 1 (
- For /f "tokens=2 Delims==" %%G in ('%SystemRoot%\System32\Findstr.exe /blic:" Echo=" "%~f0"')Do (
- Setlocal
- Call call %%G
- Endlocal
- )
- )
- Exit/b
- REM Advanced Usage Example: An extension of example 8. Repeats the output 3 times, however, between output: saves
- REM cursor position, return to screen home, clear the screen. After all iterations complete: restore cursor position
- REM %~n0 {32,255;0} (Jf((ai:5)n:19)(n88:19)666666f((da:5)n666666:19)+#f7-(n88:19)#:3)1
- REM An example regarding Virtual terminal commands for cursor positioning:
- REM [almost] functionally equivalent:
- REM %~n0 {92,1;0}(a+#nwi@-#:15)
- REM %~n0 {92;0}(a2:15)
- REM Version 1: Uses inbuilt Spacer string via 'W' command to output rVal spaces, alternating between stacks 0 and 1 -
- REM stack 0 contains the decimal value of ASCII character '\' which is retrieved at the end of each loop,
- REM while stack 1 contains a count for spacings to use, which is retrieved, incremented and saved each loop.
- REM Limitation: command line is longer, limiting the number of repetitions that can be built into the output.
- REM Version 2: Uses only a single stack containing decimal value of ASCII character '\'
- REM alternates between outputing '\' character and moving cursor down.
- REM Limitations: Requires Windows 10 ver 10586 or newer. Cannot move cursor beyond bounds of terminal. Output will
- REM continue horizontally along the last line of the terminal if boundary is encountered.
- REM Both command lines Output diagonal line:
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
- REM \
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement