576 |
Unit( |
Unit( |
577 |
(fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT |
(fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT |
578 |
), |
), |
579 |
functionName(function), args(args), fn(fn), result(NULL) |
functionName(function), args(args), fn(fn), |
580 |
|
result( (fn) ? fn->allocResult(dynamic_cast<VMFnArgs*>(&*args)) : NULL ) |
581 |
{ |
{ |
582 |
} |
} |
583 |
|
|
584 |
|
FunctionCall::~FunctionCall() { |
585 |
|
if (result) { |
586 |
|
delete result; |
587 |
|
result = NULL; |
588 |
|
} |
589 |
|
} |
590 |
|
|
591 |
void FunctionCall::dump(int level) { |
void FunctionCall::dump(int level) { |
592 |
printIndents(level); |
printIndents(level); |
593 |
printf("FunctionCall '%s' args={\n", functionName.c_str()); |
printf("FunctionCall '%s' args={\n", functionName.c_str()); |
619 |
|
|
620 |
VMFnResult* FunctionCall::execVMFn() { |
VMFnResult* FunctionCall::execVMFn() { |
621 |
if (!fn) return NULL; |
if (!fn) return NULL; |
622 |
|
|
623 |
|
// tell function where it shall dump its return value to |
624 |
|
VMFnResult* oldRes = fn->boundResult(); |
625 |
|
fn->bindResult(result); |
626 |
|
|
627 |
// assuming here that all argument checks (amount and types) have been made |
// assuming here that all argument checks (amount and types) have been made |
628 |
// at parse time, to avoid time intensive checks on each function call |
// at parse time, to avoid time intensive checks on each function call |
629 |
VMFnResult* res = fn->exec(dynamic_cast<VMFnArgs*>(&*args)); |
VMFnResult* res = fn->exec(dynamic_cast<VMFnArgs*>(&*args)); |
630 |
|
|
631 |
|
// restore previous result binding of some potential toplevel or concurrent |
632 |
|
// caller, i.e. if exactly same function is called more than one time, |
633 |
|
// concurrently in a term by other FunctionCall objects, e.g.: |
634 |
|
// ~c := ceil( ceil(~a) + ~b) |
635 |
|
fn->bindResult(oldRes); |
636 |
|
|
637 |
if (!res) return res; |
if (!res) return res; |
638 |
|
|
639 |
VMExpr* expr = res->resultValue(); |
VMExpr* expr = res->resultValue(); |
656 |
} |
} |
657 |
|
|
658 |
StmtFlags_t FunctionCall::exec() { |
StmtFlags_t FunctionCall::exec() { |
659 |
result = execVMFn(); |
VMFnResult* result = execVMFn(); |
660 |
if (!result) |
if (!result) |
661 |
return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); |
return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); |
662 |
return result->resultFlags(); |
return result->resultFlags(); |
663 |
} |
} |
664 |
|
|
665 |
vmint FunctionCall::evalInt() { |
vmint FunctionCall::evalInt() { |
666 |
result = execVMFn(); |
VMFnResult* result = execVMFn(); |
667 |
if (!result) return 0; |
if (!result) return 0; |
668 |
VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue()); |
VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue()); |
669 |
if (!intExpr) return 0; |
if (!intExpr) return 0; |
671 |
} |
} |
672 |
|
|
673 |
vmfloat FunctionCall::evalReal() { |
vmfloat FunctionCall::evalReal() { |
674 |
result = execVMFn(); |
VMFnResult* result = execVMFn(); |
675 |
if (!result) return 0; |
if (!result) return 0; |
676 |
VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue()); |
VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue()); |
677 |
if (!realExpr) return 0; |
if (!realExpr) return 0; |
686 |
// calls to be evaluated at all. This issue should be addressed cleanly by |
// calls to be evaluated at all. This issue should be addressed cleanly by |
687 |
// adjusting the API appropriately. |
// adjusting the API appropriately. |
688 |
FunctionCall* rwSelf = const_cast<FunctionCall*>(this); |
FunctionCall* rwSelf = const_cast<FunctionCall*>(this); |
689 |
rwSelf->result = rwSelf->execVMFn(); |
VMFnResult* result = rwSelf->execVMFn(); |
690 |
|
|
691 |
if (!result) return 0; |
if (!result) return 0; |
692 |
VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue()); |
VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue()); |
701 |
// calls to be evaluated at all. This issue should be addressed cleanly by |
// calls to be evaluated at all. This issue should be addressed cleanly by |
702 |
// adjusting the API appropriately. |
// adjusting the API appropriately. |
703 |
FunctionCall* rwSelf = const_cast<FunctionCall*>(this); |
FunctionCall* rwSelf = const_cast<FunctionCall*>(this); |
704 |
rwSelf->result = rwSelf->execVMFn(); |
VMFnResult* result = rwSelf->execVMFn(); |
705 |
|
|
706 |
if (!result) return 0; |
if (!result) return 0; |
707 |
VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue()); |
VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue()); |
709 |
} |
} |
710 |
|
|
711 |
String FunctionCall::evalStr() { |
String FunctionCall::evalStr() { |
712 |
result = execVMFn(); |
VMFnResult* result = execVMFn(); |
713 |
if (!result) return ""; |
if (!result) return ""; |
714 |
VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue()); |
VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue()); |
715 |
if (!strExpr) return ""; |
if (!strExpr) return ""; |
717 |
} |
} |
718 |
|
|
719 |
String FunctionCall::evalCastToStr() { |
String FunctionCall::evalCastToStr() { |
720 |
result = execVMFn(); |
VMFnResult* result = execVMFn(); |
721 |
if (!result) return ""; |
if (!result) return ""; |
722 |
const ExprType_t resultType = result->resultValue()->exprType(); |
const ExprType_t resultType = result->resultValue()->exprType(); |
723 |
if (resultType == STRING_EXPR) { |
if (resultType == STRING_EXPR) { |