fast hybrid 'pocket calculator' sub

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
foxfoxgo
Posts: 2
Joined: 08 Aug 2020 02:01

fast hybrid 'pocket calculator' sub

#1 Post by foxfoxgo » 08 Aug 2020 02:53

Hello Dostips ;)

Since it's a first msg after all this time, at least I would like to say that every time I walk through Dostips that makes me very enthusiast, I always discover something new, it's endless!, thanks to the aliens here who speak esoteric&dirty batch fluently :P

So, I would ask for a little help: I would like to have a small subroutine for simple calculation using hybrid cmd/cscript, embedded in a self calling batch so that I could use the sub inside when needed, and without tmp script file.

I saw numerous examples here or on SO for ex., yet didn't reach to make what I want.

After all I came with an hybrid cmd/powershell, the problem being that powershell is too long to load and perform the calculation, I find, yet powerfull but for simple or fast scripts I guess it's too much.

A code being worth a thousand words (while not so sure for msdos batch..), here is an example:

Code: Select all

@echo off

::main
setlocal EnableDelayedExpansion
setlocal EnableExtensions

::operation to perform
set "op=1+1"
call :hybrid-calc !op! res
echo.!op!=!res!

::pws offers a rather complete math library while it's a bit too much for my needs
set "m=[Math]::" & rem just an alias to lighten the writing

set "op=!m!cos(!m!log(!m!pi+20))"
call :hybrid-calc "!op!" res
echo.cos(ln(pi+20))=!res!

exit/b

:hybrid-calc op res
set "op=%~1"
for /f %%A in ('powershell -NoLogo -NoProfile -ExecutionPolicy Bypass "Write-Host ( !op! )" ') do set "r=%%~A"
(endlocal & set "%2=!r!" & exit/b)
Thus, the trick is to replace the (not really) cmd/pws hybrid-calc sub with an equivalent 'callable' cmd/js that I hope will give results faster, especially when it is called in batch (I mean many time).

I guess it should use something like

Code: Select all

@cscript //E:JScript //nologo "%~f0" "!op!"
but didn't find the way to set it nor the jscript to use.

Thank you

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: fast hybrid 'pocket calculator' sub

#2 Post by penpen » 08 Aug 2020 03:26

Actually i have not much time (sorry for that), so i hope this sample hybrid js/bat code helps you:

Code: Select all

@if (true == false) @end /*
@echo off
setlocal enableExtensions disableDelayedExpansion
call :main
goto :eof

:main
cscript //E:jScript //NoLogo "%~dpnx0" /"source:named 1" /"target:named 2" "unnamed 1" "unnamed 2"
goto :eof

*/

WScript.Echo("Arguments: " + WScript.Arguments.length);
for(var i = 0, n = WScript.Arguments.length; i < n; ++i) {
	WScript.Echo("Argument[i]: " + WScript.Arguments(i));
}

WScript.Echo();
WScript.Echo("Unnamed Arguments: " + WScript.Arguments.Unnamed.length);
for(var i = 0, n = WScript.Arguments.Unnamed.length; i < n; ++i) {
	WScript.Echo("Argument[i]: " + WScript.Arguments.Unnamed.item(i));
}

WScript.Echo();
WScript.Echo("Named Arguments: ");
for(var e = new Enumerator(WScript.Arguments.Named); !e.atEnd(); e.moveNext()) {
	arg = e.item();
	WScript.Echo(arg + ': ' + WScript.Arguments.Named(arg));
}
If i remember right, then the "call :main" was needed because of a possible call scenario i can't remember, where "%~dpnx0" isn't expanded correctly (had something to do with spaces in filename i think).


penpen

foxfoxgo
Posts: 2
Joined: 08 Aug 2020 02:01

Re: fast hybrid 'pocket calculator' sub

#3 Post by foxfoxgo » 08 Aug 2020 03:56

ok, thank you to lead me down the right path with the canvas,

I found an example close to what I need here or here too, I may come to smthg

edit: or not :D

well I found a minimalist way but still have questions

Code: Select all

@if (@X)==(@Y) @goto :enclosed batch block @end /*

@echo off

setlocal enableExtensions enableDelayedExpansion

::expression
set "op=2/3"

::get result
call :jscalc "!op!" res

echo.!op!=!res!

exit/B

:jscalc expr res

set "expr=%~1"
for /f %%A in ('cscript //e:jscript //NoLogo "%~f0" "!expr!"') do set "r=%%~A"
(endlocal & set "%2=!r!" & exit/b)

	REM --- end of batch, start of js ---
*/

WScript.Echo(eval(WScript.Arguments(0)));

/* end */

Now for the js part, I'm trying to use some math functions like Math.round, Math.pow but the result is "-1.#ind"
...must have been a typo somewhere, now it's fine

Code: Select all

set "js=Math."
set "op=!js!pow(!js!PI,0.5)"
call :jscalc "!op!" res
Eventually testing vbs, I saw the ".wsf" workaround to embed both languages, but does it worth it? I guess there is no noticeable difference between the two execution times

Post Reply