Sorry for spoon-feeding like this, but here I go.
Supported operators:
+, -, *, /, ^ and %.
This can handle things such as:
(5 ^ 3 % (17 + 4)) - 3 - 5 + 7 * (3 % 2)
Even this:
( 5 ^ 3 % ( 17 + 4) ) - 3 -5 +7 *( 3 %2 )
function strMath( %str )
{
if ( !strLen( %str ) )
{
return 0;
}
%off = 0;
while ( true )
{
%pos = striPos( %str, "(", %off );
if ( %pos < 0 )
{
break;
}
%end = strPosBackwards( %str, ")", %pos );
if ( %end < 0 )
{
continue;
}
%mat = trim( getSubStr( %str, %pos + 1, %end - ( %pos + 1 ) ) );
%str = setSubStr( %str, %pos, %end + 1, strMath( %mat ) );
%off = %end + 1;
}
%str = strReplace( %str, " ", "" );
%mat = "+-*/^%";
%off = 0;
%val = 0;
while ( true )
{
%pos = strPosAny( %str, %mat, %off );
if ( %pos < 0 )
{
break;
}
%prev = strPosAnyBackwards( %str, %mat, %pos );
%next = strPosAny( %str, %mat, %pos + 1 );
%type = getSubStr( %str, %pos, 1 );
if ( %prev < 0 && %next < 0 )
{
%pre = getSubStr( %str, 0, %pos );
%sub = getSubStr( %str, %pos + 1, strLen( %str ) );
%prev = 0;
%next = strLen( %str ) - 1;
}
else if ( %prev < 0 && %next >= 0 )
{
%pre = getSubStr( %str, 0, %pos );
%sub = getSubStr( %str, %pos + 1, %next - ( %pos + 1 ) );
%prev = 0;
%next = %next;
}
else if ( %prev >= 0 && %next < 0 )
{
%pre = getSubStr( %str, %prev, %pos - %prev );
%sub = getSubStr( %str, %pos + 1, strLen( %str ) );
%prev = %prev + 1;
%next = strLen( %str ) - 1;
}
else if ( %prev >= 0 && %next >= 0 )
{
%pre = getSubStr( %str, %prev, %pos - %prev );
%sub = getSubStr( %str, %pos + 1, %next - ( %pos + 1 ) );
%prev = %prev + 1;
%next = %next;
}
else
{
return 0;
}
if ( !strLen( %pre ) || !strLen( %sub ) )
{
%str = setSubStr( %str, %prev, %next, 0 );
continue;
}
switch$ ( %type )
{
case "+": %val = %pre + %sub;
case "-": %val = %pre - %sub;
case "*": %val = %pre * %sub;
case "/": %val = %pre / %sub;
case "^": %val = mPow( %pre, %sub );
case "%": %val = %pre % %sub;
default:
%str = setSubStr( %str, %prev, %next, 0 );
continue;
}
if ( %val $= "1.#INF" || %val $= "-1.#IND" )
{
%val = 0;
}
%str = setSubStr( %str, %prev, %next, %val );
}
return %val;
}
function setSubStr( %str, %start, %len, %val )
{
return getSubStr( %str, 0, %start ) @ %val @ getSubStr( %str, %start + %len, strLen( %str ) );
}
function strPosAny( %str, %list, %offset )
{
if ( !strLen( %str ) || !strLen( %list ) )
{
return -1;
}
if ( !strLen( %offset ) )
{
%offset = 0;
}
%cnt = strLen( %str );
for ( %i = 0 ; %i < %cnt ; %i++ )
{
if ( strPos( %list, getSubStr( %str, %i, 1 ) ) >= 0 )
{
return %i;
}
}
return -1;
}
function strPosBackwards( %str, %char, %offset )
{
if ( !strLen( %str ) || !strLen( %char ) )
{
return -1;
}
if ( !strLen( %offset ) )
{
%offset = 0;
}
for ( %i = strLen( %str ) - 1 - %offset ; %i >= 0 ; %i-- )
{
%chr = getSubStr( %str, %i, 1 );
if ( %chr $= %char )
{
return %i;
}
}
return -1;
}
function strPosAnyBackwards( %str, %list, %offset )
{
if ( !strLen( %str ) || !strLen( %list ) )
{
return -1;
}
if ( !strLen( %offset ) )
{
%offset = 0;
}
for ( %i = strLen( %str ) - 1 - %offset ; %i >= 0 ; %i-- )
{
%chr = getSubStr( %str, %i, 1 );
if ( strPos( %list, %chr ) >= 0 )
{
return %i;
}
}
return -1;
}