diff --git a/include/math.h b/include/math.h index 8ad34db..79edcea 100644 --- a/include/math.h +++ b/include/math.h @@ -33,10 +33,15 @@ bool isfinite(float f); #pragma intrinsic(sin) #pragma intrinsic(cos) #pragma intrinsic(tan) +#pragma intrinsic(atan) +#pragma intrinsic(atan2) #pragma intrinsic(log) #pragma intrinsic(exp) +#pragma intrinsic(pow) +#pragma intrinsic(sqrt) + #pragma compile("math.c") diff --git a/oscar64/Constexpr.cpp b/oscar64/Constexpr.cpp index d2d4020..c29e01b 100644 --- a/oscar64/Constexpr.cpp +++ b/oscar64/Constexpr.cpp @@ -1197,6 +1197,26 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons mResult = Value(exp->mLocation, TheFloatTypeDeclaration); mResult.PutFloat(::exp(mParams[0].GetFloat())); } + else if (!strcmp(iname->mString, "sqrt")) + { + mResult = Value(exp->mLocation, TheFloatTypeDeclaration); + mResult.PutFloat(::sqrt(mParams[0].GetFloat())); + } + else if (!strcmp(iname->mString, "atan")) + { + mResult = Value(exp->mLocation, TheFloatTypeDeclaration); + mResult.PutFloat(::atan(mParams[0].GetFloat())); + } + else if (!strcmp(iname->mString, "atan2")) + { + mResult = Value(exp->mLocation, TheFloatTypeDeclaration); + mResult.PutFloat(::atan2(mParams[0].GetFloat(), mParams[1].GetFloat())); + } + else if (!strcmp(iname->mString, "pow")) + { + mResult = Value(exp->mLocation, TheFloatTypeDeclaration); + mResult.PutFloat(::pow(mParams[0].GetFloat(), mParams[1].GetFloat())); + } else mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname); } diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 76c2bec..eda2337 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -1237,19 +1237,19 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio else if (mType == EX_INDEX && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE_REF && (mLeft->mDecValue->mFlags & DTF_GLOBAL) && mLeft->mDecType->mType == DT_TYPE_ARRAY && mLeft->mDecType->mStride == 0 && mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER) - { - int offset = mLeft->mDecValue->mOffset + int(mDecType->mSize * mRight->mDecValue->mInteger); + { + int offset = mLeft->mDecValue->mOffset + int(mDecType->mSize * mRight->mDecValue->mInteger); - Expression* ex = new Expression(mLocation, EX_VARIABLE); - Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF); - dec->mFlags = mLeft->mDecValue->mFlags; - dec->mBase = mLeft->mDecValue->mBase; - dec->mOffset = offset; - dec->mSize = mDecType->mSize; - ex->mDecValue = dec; - ex->mDecType = mDecType; - return ex; - } + Expression* ex = new Expression(mLocation, EX_VARIABLE); + Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF); + dec->mFlags = mLeft->mDecValue->mFlags; + dec->mBase = mLeft->mDecValue->mBase; + dec->mOffset = offset; + dec->mSize = mDecType->mSize; + ex->mDecValue = dec; + ex->mDecType = mDecType; + return ex; + } else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight && mRight->mType == EX_CONSTANT) { Declaration* decf = mLeft->mDecValue, * decp = mRight->mDecValue; @@ -1258,6 +1258,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio if (decp->mType == DT_CONST_FLOAT || decp->mType == DT_CONST_INTEGER) { double d = decp->mType == DT_CONST_FLOAT ? decp->mNumber : decp->mInteger; + double e = 0.0; bool check = false; @@ -1277,6 +1278,10 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio d = log(d); else if (!strcmp(iname->mString, "exp")) d = exp(d); + else if (!strcmp(iname->mString, "sqrt")) + d = sqrt(d); + else if (!strcmp(iname->mString, "atan")) + d = atan(d); else return this; @@ -1289,6 +1294,36 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio return ex; } } + else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight && + mRight->mType == EX_LIST && mRight->mLeft->mType == EX_CONSTANT && mRight->mRight->mType == EX_CONSTANT) + { + Declaration* decf = mLeft->mDecValue, * decp1 = mRight->mLeft->mDecValue, * decp2 = mRight->mRight->mDecValue; + const Ident* iname = decf->mQualIdent; + + if ((decp1->mType == DT_CONST_FLOAT || decp1->mType == DT_CONST_INTEGER) && + (decp2->mType == DT_CONST_FLOAT || decp2->mType == DT_CONST_INTEGER)) + { + double d1 = decp1->mType == DT_CONST_FLOAT ? decp1->mNumber : decp1->mInteger; + double d2 = decp2->mType == DT_CONST_FLOAT ? decp2->mNumber : decp2->mInteger; + + bool check = false; + + if (!strcmp(iname->mString, "pow")) + d1 = pow(d1, d2); + else if (!strcmp(iname->mString, "atan2")) + d1 = atan2(d1, d2); + else + return this; + + Expression* ex = new Expression(mLocation, EX_CONSTANT); + Declaration* dec = new Declaration(mLocation, DT_CONST_FLOAT); + dec->mBase = TheFloatTypeDeclaration; + dec->mNumber = d1; + ex->mDecValue = dec; + ex->mDecType = dec->mBase; + return ex; + } + } else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_CONSTEXPR) && dataSection) { ConstexprInterpreter cinter(mLocation, errors, dataSection); diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 92c1bc6..2179f72 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -685,7 +685,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara } else { - mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent); + mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent()); if (cexp) mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here"); diff --git a/oscar64/GlobalOptimizer.cpp b/oscar64/GlobalOptimizer.cpp index 4764eff..3d386d6 100644 --- a/oscar64/GlobalOptimizer.cpp +++ b/oscar64/GlobalOptimizer.cpp @@ -462,7 +462,7 @@ void GlobalOptimizer::AnalyzeProcedure(Expression* exp, Declaration* procDec) Analyze(exp, procDec, false); } else - mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->mQualIdent); + mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->FullIdent()); procDec->mOptFlags &= ~OPTF_ANALYZING; } diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 4ee1c6f..f9ea31f 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -3715,6 +3715,18 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* else if (!strcmp(iname->mString, "exp")) { } + else if (!strcmp(iname->mString, "sqrt")) + { + } + else if (!strcmp(iname->mString, "atan")) + { + } + else if (!strcmp(iname->mString, "pow")) + { + } + else if (!strcmp(iname->mString, "atan2")) + { + } else if (!strcmp(iname->mString, "breakpoint")) { InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BREAKPOINT); @@ -6219,7 +6231,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod } } else - mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString); + mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent()); if (strcmp(proc->mIdent->mString, "main")) {