Implement exponentiation (**) operator
All checks were successful
Build / AerScript (push) Successful in 40s

This commit is contained in:
2025-08-29 22:04:55 +02:00
parent 8ac9b148d1
commit d73eb9b5b2
4 changed files with 99 additions and 3 deletions

View File

@@ -7,6 +7,7 @@
* Rafal Kupiec <belliash@codingworkshop.eu.org>
* David Carlier <devnexen@gmail.com>
*/
#include <math.h>
#include "ph7int.h"
/*
@@ -2979,6 +2980,63 @@ static sxi32 VmByteCodeExec(
VmPopOperand(&pTos, 1);
break;
}
/* OP_POW * * *
* OP_POW_STORE * * *
*
* Pop the top two elements from the stack, perform an exponentiation,
* and push the result back onto the stack.
*/
case PH7_OP_POW:
case PH7_OP_POW_STORE: {
SyString sName;
ph7_value *pNos = &pTos[-1];
/* Force the operand to be numeric */
if(pNos < pStack) {
goto Abort;
}
PH7_MemObjToNumeric(pTos);
PH7_MemObjToNumeric(pNos);
/* Perform the requested operation */
if(MEMOBJ_REAL & (pTos->nType | pNos->nType)) {
/* Floating point arithmetic */
ph7_real a, b, r;
if((pTos->nType & MEMOBJ_REAL) == 0) {
PH7_MemObjToReal(pTos);
}
if((pNos->nType & MEMOBJ_REAL) == 0) {
PH7_MemObjToReal(pNos);
}
a = pNos->x.rVal;
b = pTos->x.rVal;
r = pow(b, a);
/* Push the result */
pNos->x.rVal = r;
MemObjSetType(pNos, MEMOBJ_REAL);
} else {
/* Integer arithmetic */
sxi64 a, b, r;
a = pNos->x.iVal;
b = pTos->x.iVal;
r = (sxi64)pow((double)b, (double)a);
/* Push the result */
pNos->x.iVal = r;
MemObjSetType(pNos, MEMOBJ_INT);
}
if(pInstr->iOp == PH7_OP_POW_STORE) {
ph7_value *pObj;
if(pTos->nIdx == SXU32_HIGH) {
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Cannot perform assignment on a constant class attribute");
} else if((pObj = (ph7_value *)SySetAt(&pVm->aMemObj, pTos->nIdx)) != 0) {
if(pNos->nType != pObj->nType && PH7_CheckVarCompat(pNos, pObj->nType) != SXRET_OK) {
SyStringInitFromBuf(&sName, pInstr->p3, SyStrlen((const char *)pInstr->p3));
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Cannot assign a value of incompatible type to variable '$%z'", &sName);
};
PH7_MemObjStore(pNos, pObj);
}
}
VmPopOperand(&pTos, 1);
break;
}
/* OP_ADD P1 P2 *
*
* Pop the top two elements from the stack, add them together,