in interpreters/minibasic/basic.c [1748:2021]
static double factor(void)
{
double answer = 0;
FAR char *str;
FAR char *end;
int len;
switch (g_token)
{
case OPAREN:
match(OPAREN);
answer = expr();
match(CPAREN);
break;
case VALUE:
answer = getvalue(g_string, &len);
match(VALUE);
break;
case MINUS:
match(MINUS);
answer = -factor();
break;
case FLTID:
answer = variable();
break;
case DIMFLTID:
answer = dimvariable();
break;
case E:
answer = exp(1.0);
match(E);
break;
case PI:
answer = acos(0.0) * 2.0;
match(PI);
break;
case SIN:
match(SIN);
match(OPAREN);
answer = expr();
match(CPAREN);
answer = sin(answer);
break;
case COS:
match(COS);
match(OPAREN);
answer = expr();
match(CPAREN);
answer = cos(answer);
break;
case TAN:
match(TAN);
match(OPAREN);
answer = expr();
match(CPAREN);
answer = tan(answer);
break;
case LN:
match(LN);
match(OPAREN);
answer = expr();
match(CPAREN);
if (answer > 0)
{
answer = log(answer);
}
else
{
seterror(ERR_NEGLOG);
}
break;
case POW:
match(POW);
match(OPAREN);
answer = expr();
match(COMMA);
answer = pow(answer, expr());
match(CPAREN);
break;
case SQRT:
match(SQRT);
match(OPAREN);
answer = expr();
match(CPAREN);
if (answer >= 0.0)
{
answer = sqrt(answer);
}
else
{
seterror(ERR_NEGSQRT);
}
break;
case ABS:
match(ABS);
match(OPAREN);
answer = expr();
match(CPAREN);
answer = fabs(answer);
break;
case LEN:
match(LEN);
match(OPAREN);
str = stringexpr();
match(CPAREN);
if (str)
{
answer = strlen(str);
free(str);
}
else
{
answer = 0;
}
break;
case ASCII:
match(ASCII);
match(OPAREN);
str = stringexpr();
match(CPAREN);
if (str)
{
answer = *str;
free(str);
}
else
{
answer = 0;
}
break;
case ASIN:
match(ASIN);
match(OPAREN);
answer = expr();
match(CPAREN);
if (answer >= -1 && answer <= 1)
{
answer = asin(answer);
}
else
{
seterror(ERR_BADSINCOS);
}
break;
case ACOS:
match(ACOS);
match(OPAREN);
answer = expr();
match(CPAREN);
if (answer >= -1 && answer <= 1)
{
answer = acos(answer);
}
else
{
seterror(ERR_BADSINCOS);
}
break;
case ATAN:
match(ATAN);
match(OPAREN);
answer = expr();
match(CPAREN);
answer = atan(answer);
break;
case INT:
match(INT);
match(OPAREN);
answer = expr();
match(CPAREN);
answer = floor(answer);
break;
case RND:
match(RND);
match(OPAREN);
answer = expr();
match(CPAREN);
answer = integer(answer);
if (answer > 1)
{
answer = floor(rand() / (RAND_MAX + 1.0) * answer);
}
else if (answer == 1)
{
answer = rand() / (RAND_MAX + 1.0);
}
else
{
if (answer < 0)
{
srand((unsigned)-answer);
}
answer = 0;
}
break;
case VAL:
match(VAL);
match(OPAREN);
str = stringexpr();
match(CPAREN);
if (str)
{
answer = strtod(str, 0);
free(str);
}
else
{
answer = 0;
}
break;
case VALLEN:
match(VALLEN);
match(OPAREN);
str = stringexpr();
match(CPAREN);
if (str)
{
strtod(str, &end);
answer = end - str;
free(str);
}
else
{
answer = 0.0;
}
break;
case INSTR:
answer = instr();
break;
default:
if (isstring(g_token))
{
seterror(ERR_TYPEMISMATCH);
}
else
{
seterror(ERR_SYNTAX);
}
break;
}
while (g_token == SHRIEK)
{
match(SHRIEK);
answer = factorial(answer);
}
return answer;
}