I just made a few more functions
First :IsObject
Use it like this
Call :IsObject NotAnObject myoutput
Call :IsObject NotAnObject && echo NotAnObject is an object || echo NotAnObject is not object
In my world, an object is a variable name which has other defined variable with the same root name plus a "." and some other text
Here is what I mean
Code: Select all
set NotAnObject=test
set IsAnObject=test
set IsAnObject.suffixA=test
set IsAnObject.suffixB=test
set IsAnObject.suffixC=test
set IsAnotherObject.suffixA=test
set IsAnotherObject.suffixB=test
set IsAnotherObject.suffixC=test
Code: Select all
Call :IsObject NotAnObject myoutput
echo IsObject NotAnObject ? %myoutput%
Call :IsObject IsAnObject myoutput
echo IsObject IsAnObject ? %myoutput%
Call :IsObject IsAnotherObject myoutput
echo IsObject IsAnotherObject ? %myoutput%
Call :IsObject NotAnObject && echo NotAnObject is an object || echo NotAnObject is not object
Call :IsObject IsAnObject && echo IsAnObject is an object || echo IsAnObject is not object
Call :IsObject IsAnotherObject && echo IsAnotherObject is an object || echo IsAnotherObject is not object
Code: Select all
IsObject NotAnObject ? false
IsObject IsAnObject ? true
IsObject IsAnotherObject ? true
NotAnObject is not object
IsAnObject is an object
IsAnotherObject is an object
Code: Select all
::Usage Call :IsObject ObjectName optional Output
:IsObject
set /a "_IsObject=1"
for /f "tokens=1,2* delims==" %%a in ('set %~1 2^>nul') do (
if "[%%a]" NEQ "[%~1]" ( set /a "_IsObject=0" & GoTo :IsObject-for-exit )
)
:IsObject-for-exit
if "[%~2]" NEQ "[]" if "[%_IsObject%]" EQU "[0]" ( set "%~2=true" ) else ( set "%~2=false" )
set "_IsObject=" & exit /b %_IsObject%
Code: Select all
::Usage Call :IsObjectStrict ObjectName optional Output
:IsObjectStrict
set /a "_IsObjectStrict=1"
for /f "tokens=1,2* delims==" %%a in ('set %~1 2^>nul') do (
if "[%%a]" NEQ "[%~1]" (
setlocal enabledelayedexpansion
set _IsObjectStrict_buffer=%%a
set _IsObjectStrict_buffer=!_IsObjectStrict_buffer:%~1=!
set _IsObjectStrict_buffer=!_IsObjectStrict_buffer:~,1!
if "[!_IsObjectStrict_buffer!]" EQU "[.]" ( endlocal & set /a "_IsObjectStrict=0" & GoTo :IsObjectStrict-for-exit )
endlocal
)
)
:IsObjectStrict-for-exit
if "[%~2]" NEQ "[]" if "[%_IsObjectStrict%]" EQU "[0]" ( set "%~2=true" ) else ( set "%~2=false" )
set "_IsObjectStrict=" & exit /b %_IsObjectStrict%
In my world an array is fundamentally a variable which includes numbers between [brackets]
so myarray is an array if there exists myarray[42]
Also if myarray.ubound myarray.lbound or myarray.datatype=array are defined
You use it like this
Code: Select all
Call :IsArray IsAnArray1 myoutput
echo IsArray IsAnArray1 ? %myoutput%
Call :IsArray IsAnArray1 && echo IsAnArray1 is an array || echo IsAnArray1 is not array
Code: Select all
::Usage :IsArray ArrayName optional output
:IsArray
set /a "_IsArray=1"
if defined %~1.lbound ( set /a "_IsArray=0" & GoTo :IsArray-end )
if defined %~1.ubound ( set /a "_IsArray=0" & GoTo :IsArray-end )
if defined %~1.datatype call set "_IsArray_datatype=%%%~1.datatype%%"
if "[%_IsArray_datatype%]" EQU "[array]" ( set /a "_IsArray=0" & GoTo :IsArray-end )
for /f "tokens=1,2* delims==" %%a in ('set %~1 2^>nul') do (
if "[%%a]" NEQ "[%~1]" (
setlocal enabledelayedexpansion
set _IsArray_buffer=%%a
set _IsArray_buffer=!_IsArray_buffer:%~1=!
set _IsArray_buffer=!_IsArray_buffer:~,1!
if "[!_IsArray_buffer!]" EQU "[[]" ( endlocal & set /a "_IsArray=0" & GoTo :IsArray-end )
endlocal
)
)
:IsArray-end
if "[%~2]" NEQ "[]" if "[%_IsArray%]" EQU "[0]" ( set "%~2=true" ) else ( set "%~2=false" )
set "IsArray=" & set "_IsArray_datatype=" & exit /b %_IsArray%
Lastly, the function :Arithmetic, which is a simple function of the "set /a" command
You can use it byval, byref and byref array
Examples
Call :Calculate 2+2 myresult
set myarray[0]=2+2
Call :Calculate myarray[0] myresult
Call :Calculate myarray myresults
I have not yet made a version which can detection operations that start with an operator to chain multiple operations together
Here is the DEMO function
Code: Select all
echo.&echo Performing calculations byval&echo.
set myresult=
Call :Calculate 2+2 myresult
echo 2+2 is %myresult%
Call :Calculate 2+2+5465+1 myresult
echo 2+2+5465+1 is %myresult%
Call :Calculate 100-25-25+50 myresult
echo 100-25-25+50 is %myresult%
Call :Calculate 25/5 myresult
echo 25/5 is %myresult%
Call :Calculate 10*10 myresult
echo 10*10 is %myresult%
Call :Calculate 99%%%%20 myresult
echo 99%%20 is %myresult%
Call :Calculate 10+10/2 myresult
echo 10+10/2 is %myresult%
Call :Calculate (10+10)/2 myresult
echo (10+10)/2 is %myresult%
set myarray[0]=2+2
set myarray[1]=2+2+5465+1
set myarray[2]=100-25-25+50
set myarray[3]=25/5
set myarray[4]=10*10
set myarray[5]=99%%20
set myarray[6]=10+10/2
set myarray[7]=(10+10)/2
echo.&echo Performing calculations byref&echo.
set myresult=
Call :Calculate myarray[0] myresult
echo %myarray[0]% is %myresult%, errorlevel is %errorlevel%
Call :Calculate myarray[1] myresult
echo %myarray[1]% is %myresult%, errorlevel is %errorlevel%
Call :Calculate myarray[2] myresult
echo %myarray[2]% is %myresult%, errorlevel is %errorlevel%
Call :Calculate myarray[3] myresult
echo %myarray[3]% is %myresult%, errorlevel is %errorlevel%
Call :Calculate myarray[4] myresult
echo %myarray[4]% is %myresult%, errorlevel is %errorlevel%
Call :Calculate myarray[5] myresult
echo %myarray[5]% is %myresult%, errorlevel is %errorlevel%
Call :Calculate myarray[6] myresult
echo %myarray[6]% is %myresult%, errorlevel is %errorlevel%
Call :Calculate myarray[7] myresult
echo %myarray[7]% is %myresult%, errorlevel is %errorlevel%
set myarray.ubound=7
echo.&echo Performing calculations from array byref&echo.
Call :Calculate myarray myresults
call :echoarray myresults
Code: Select all
Performing calculations byval
2+2 is 4
2+2+5465+1 is 5470
100-25-25+50 is 100
25/5 is 5
10*10 is 100
99%20 is 19
10+10/2 is 15
(10+10)/2 is 10
Performing calculations byref
2+2 is 4, errorlevel is 4
2+2+5465+1 is 5470, errorlevel is 5470
100-25-25+50 is 100, errorlevel is 100
25/5 is 5, errorlevel is 5
10*10 is 100, errorlevel is 100
99%20 is 19, errorlevel is 19
10+10/2 is 15, errorlevel is 15
(10+10)/2 is 10, errorlevel is 10
Performing calculations from array byref
4
5470
100
5
100
19
15
10
Code: Select all
::Usage Call :Calculate operations result operations2 result2 operationsN resultN
:Arithmetic
:Calculate
set "_Arithmetic_operation=%~1"
set "_Arithmetic_output=%~2"
if defined %~1.ubound GoTo :Arithmetic-loop-setup
if defined %_Arithmetic_operation% call set "_Arithmetic_operation=%%%_Arithmetic_operation%%%"
set /a "_Arithmetic_result=%_Arithmetic_operation%"
set /a "%_Arithmetic_output%=%_Arithmetic_result%" & GoTo :Arithmetic-end
:Arithmetic-loop-setup
if defined %_Arithmetic_output%.ubound ( call set /a "_Arithmetic_output_ubound=%%%_Arithmetic_output%.ubound%%" ) else ( set /a "_Arithmetic_output_ubound=-1" )
if defined %_Arithmetic_operation%.lbound ( call set /a "_Arithmetic_operation_lbound=%%%_Arithmetic_operation%.lbound%%" ) else ( set /a "_Arithmetic_operation_lbound=0" )
call set /a "_Arithmetic_operation_ubound=%%%_Arithmetic_operation%.ubound%%"
set /a "_Arithmetic_operation_index=%_Arithmetic_operation_lbound%"
:Arithmetic-loop
set /a "_Arithmetic_output_ubound+=1"
call set /a "_Arithmetic_result=%%%_Arithmetic_operation%[%_Arithmetic_operation_index%]%%"
set /a "%_Arithmetic_output%[%_Arithmetic_output_ubound%]=%_Arithmetic_result%"
set /a "_Arithmetic_operation_index+=1"
if %_Arithmetic_operation_index% LEQ %_Arithmetic_operation_ubound% GoTo :Arithmetic-loop
set /a "%_Arithmetic_output%.ubound=%_Arithmetic_output_ubound%"
:Arithmetic-end
REM I think I'm missing some stuff here, at least clear local variables !
REM if %~3 %~4 clear and goto start to chain multiple operations like Call :Calculate 2+2 myresult 3+3 myresult2, this function isn't done ! also need to test all the operators, especially the bitwise , also make boolean logic with the bitwide operators!
exit /b %_Arithmetic_result%
Oh this function is aliased to two names :Arithmetic and :Calculate
I like to call it :Calculate, but :Arithmetic would be the bare set /a capabilities , while :Calculate might grow to become more clever overtime. Maybe a version of :Calculate could implement some of "bc"