Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* function.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* internal holder for int/float/string                                      */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include "bpemu.h"
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include <float.h>
  16. #include "nonzstring.h"
  17. #include "strutil.h"
  18. #include "asmdef.h"
  19. #include "errmsg.h"
  20. #include "asmerr.h"
  21. #include "chartrans.h"
  22. #include "asmpars.h"
  23. #include "cpu2phys.h"
  24. #include "function.h"
  25.  
  26. static as_float_t log_max, log2_max, log10_max;
  27.  
  28. static Boolean FuncSUBSTR(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  29. {
  30.   int cnt = pArgs[0].Contents.str.len - pArgs[1].Contents.Int;
  31.  
  32.   UNUSED(ArgCnt);
  33.   if ((pArgs[2].Contents.Int != 0) && (pArgs[2].Contents.Int < cnt))
  34.     cnt = pArgs[2].Contents.Int;
  35.   if (cnt < 0)
  36.     cnt = 0;
  37.   as_tempres_set_c_str(pResult, "");
  38.   as_nonz_dynstr_append_raw(&pResult->Contents.str, pArgs[0].Contents.str.p_str + pArgs[1].Contents.Int, cnt);
  39.  
  40.   return True;
  41. }
  42.  
  43. static Boolean FuncSTRSTR(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  44. {
  45.   UNUSED(ArgCnt);
  46.  
  47.   as_tempres_set_int(pResult, as_nonz_dynstr_find(&pArgs[0].Contents.str, &pArgs[1].Contents.str));
  48.  
  49.   return True;
  50. }
  51.  
  52. static Boolean FuncCHARFROMSTR(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  53. {
  54.   UNUSED(ArgCnt);
  55.  
  56.   as_tempres_set_int(pResult, ((pArgs[1].Contents.Int >= 0) && ((unsigned)pArgs[1].Contents.Int < pArgs[0].Contents.str.len)) ? pArgs[0].Contents.str.p_str[pArgs[1].Contents.Int] : -1);
  57.  
  58.   return True;
  59. }
  60.  
  61. static Boolean FuncCODEPAGE_VAL(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  62. {
  63.   PTransTable p_table;
  64.  
  65.   UNUSED(ArgCnt);
  66.  
  67.   if (ArgCnt >= 2)
  68.   {
  69.     String name;
  70.  
  71.     as_nonz_dynstr_to_c_str(name, &pArgs[1].Contents.str, sizeof(name));
  72.     p_table = FindCodepage(name, NULL);
  73.     if (!p_table)
  74.     {
  75.       WrXError(ErrNum_UnknownCodepage, name);
  76.       as_tempres_set_int(pResult, 0);
  77.       return True;
  78.     }
  79.   }
  80.   else
  81.     p_table = CurrTransTable;
  82.  
  83.   if (ChkRange(pArgs[0].Contents.Int, 0, 255))
  84.     as_tempres_set_int(pResult, as_chartrans_xlate(p_table->p_table, pArgs[0].Contents.Int));
  85.   else
  86.     as_tempres_set_int(pResult, 0);
  87.   return True;
  88. }
  89.  
  90. static Boolean FuncEXPRTYPE(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  91. {
  92.   UNUSED(ArgCnt);
  93.  
  94.   switch (pArgs[0].Typ)
  95.   {
  96.     case TempInt:
  97.       as_tempres_set_int(pResult, 0);
  98.       break;
  99.     case TempFloat:
  100.       as_tempres_set_int(pResult, 1);
  101.       break;
  102.     case TempString:
  103.       as_tempres_set_int(pResult, 2);
  104.       break;
  105.     default:
  106.       as_tempres_set_int(pResult, -1);
  107.   }
  108.  
  109.   return True;
  110. }
  111.  
  112. /* in Grossbuchstaben wandeln */
  113.  
  114. static Boolean FuncUPSTRING(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  115. {
  116.   char *pRun;
  117.  
  118.   UNUSED(ArgCnt);
  119.  
  120.   as_tempres_set_str(pResult, &pArgs[0].Contents.str);
  121.   for (pRun = pResult->Contents.str.p_str;
  122.        pRun < pResult->Contents.str.p_str + pResult->Contents.str.len;
  123.        pRun++)
  124.     *pRun = as_toupper(*pRun);
  125.  
  126.   return True;
  127. }
  128.  
  129. /* in Kleinbuchstaben wandeln */
  130.  
  131. static Boolean FuncLOWSTRING(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  132. {
  133.   char *pRun;
  134.  
  135.   UNUSED(ArgCnt);
  136.  
  137.   as_tempres_set_str(pResult, &pArgs[0].Contents.str);
  138.   for (pRun = pResult->Contents.str.p_str;
  139.        pRun < pResult->Contents.str.p_str + pResult->Contents.str.len;
  140.        pRun++)
  141.     *pRun = as_tolower(*pRun);
  142.  
  143.   return True;
  144. }
  145.  
  146. /* Laenge ermitteln */
  147.  
  148. static Boolean FuncSTRLEN(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  149. {
  150.   UNUSED(ArgCnt);
  151.  
  152.   as_tempres_set_int(pResult, pArgs[0].Contents.str.len);
  153.  
  154.   return True;
  155. }
  156.  
  157. /* Parser aufrufen */
  158.  
  159. static Boolean FuncVAL(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  160. {
  161.   String Tmp;
  162.  
  163.   UNUSED(ArgCnt);
  164.  
  165.   as_nonz_dynstr_to_c_str(Tmp, &pArgs[0].Contents.str, sizeof(Tmp));
  166.   EvalExpression(Tmp, pResult);
  167.  
  168.   return True;
  169. }
  170.  
  171. static Boolean FuncTOUPPER(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  172. {
  173.   UNUSED(ArgCnt);
  174.  
  175.   if ((pArgs[0].Contents.Int < 0) || (pArgs[0].Contents.Int > 255)) WrError(ErrNum_OverRange);
  176.   else
  177.     as_tempres_set_int(pResult, as_toupper(pArgs[0].Contents.Int));
  178.  
  179.   return True;
  180. }
  181.  
  182. static Boolean FuncTOLOWER(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  183. {
  184.   UNUSED(ArgCnt);
  185.  
  186.   if ((pArgs[0].Contents.Int < 0) || (pArgs[0].Contents.Int > 255)) WrError(ErrNum_OverRange);
  187.   else
  188.     as_tempres_set_int(pResult, as_tolower(pArgs[0].Contents.Int));
  189.  
  190.   return True;
  191. }
  192.  
  193. static Boolean FuncBITCNT(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  194. {
  195.   int z;
  196.   LargeInt in = pArgs[0].Contents.Int, out = 0;
  197.  
  198.   UNUSED(ArgCnt);
  199.  
  200.   out = 0;
  201.   for (z = 0; z < LARGEBITS; z++)
  202.   {
  203.     out += (in & 1);
  204.     in >>= 1;
  205.   }
  206.   as_tempres_set_int(pResult, out);
  207.  
  208.   return True;
  209. }
  210.  
  211. static Boolean FuncFIRSTBIT(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  212. {
  213.   LargeInt in = pArgs[0].Contents.Int;
  214.   int out;
  215.  
  216.   UNUSED(ArgCnt);
  217.  
  218.   out = 0;
  219.   do
  220.   {
  221.     if (!Odd(in))
  222.       out++;
  223.     in >>= 1;
  224.   }
  225.   while ((out < LARGEBITS) && !Odd(in));
  226.   as_tempres_set_int(pResult, (out >= LARGEBITS) ? -1 : out);
  227.  
  228.   return True;
  229. }
  230.  
  231. static Boolean FuncLASTBIT(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  232. {
  233.   int z, out;
  234.   LargeInt in = pArgs[0].Contents.Int;
  235.  
  236.   UNUSED(ArgCnt);
  237.  
  238.   out = -1;
  239.   for (z = 0; z < LARGEBITS; z++)
  240.   {
  241.     if (Odd(in))
  242.       out = z;
  243.     in >>= 1;
  244.   }
  245.   as_tempres_set_int(pResult, out);
  246.  
  247.   return True;
  248. }
  249.  
  250. static Boolean FuncBITPOS(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  251. {
  252.   LargeInt out;
  253.  
  254.   UNUSED(ArgCnt);
  255.  
  256.   pResult->Typ = TempInt;
  257.   if (!SingleBit(pArgs[0].Contents.Int, &out))
  258.   {
  259.     out = -1;
  260.     WrError(ErrNum_NotOneBit);
  261.   }
  262.   as_tempres_set_int(pResult, out);
  263.  
  264.   return True;
  265. }
  266.  
  267. static Boolean FuncABS(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  268. {
  269.   UNUSED(ArgCnt);
  270.  
  271.   switch (pArgs[0].Typ)
  272.   {
  273.     case TempInt:
  274.       as_tempres_set_int(pResult, (pArgs[0].Contents.Int  < 0) ? -pArgs[0].Contents.Int : pArgs[0].Contents.Int);
  275.       break;
  276.     case TempFloat:
  277.       as_tempres_set_float(pResult, as_fabs(pArgs[0].Contents.Float));
  278.       break;
  279.     default:
  280.       pResult->Typ = TempNone;
  281.   }
  282.  
  283.   return True;
  284. }
  285.  
  286. static Boolean FuncSGN(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  287. {
  288.   UNUSED(ArgCnt);
  289.  
  290.   switch (pArgs[0].Typ)
  291.   {
  292.     case TempInt:
  293.       as_tempres_set_int(pResult, (pArgs[0].Contents.Int < 0) ? -1 : ((pArgs[0].Contents.Int > 0) ? 1 : 0));
  294.       break;
  295.     case TempFloat:
  296.       as_tempres_set_int(pResult, (pArgs[0].Contents.Float < 0) ? -1 : ((pArgs[0].Contents.Float > 0) ? 1 : 0));
  297.       break;
  298.     default:
  299.       as_tempres_set_none(pResult);
  300.   }
  301.  
  302.   return True;
  303. }
  304.  
  305. static Boolean FuncINT(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  306. {
  307.   UNUSED(ArgCnt);
  308.  
  309.   if (as_fabs(pArgs[0].Contents.Float) > IntTypeDefs[LargeSIntType].Max)
  310.   {
  311.     as_tempres_set_none(pResult);
  312.     WrError(ErrNum_OverRange);
  313.   }
  314.   else
  315.     as_tempres_set_int(pResult, (LargeInt) floor(pArgs[0].Contents.Float));
  316.  
  317.   return True;
  318. }
  319.  
  320. static Boolean FuncSQRT(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  321. {
  322.   UNUSED(ArgCnt);
  323.  
  324.   if (pArgs[0].Contents.Float < 0)
  325.   {
  326.     as_tempres_set_none(pResult);
  327.     WrError(ErrNum_InvFuncArg);
  328.   }
  329.   else
  330.     as_tempres_set_float(pResult, as_sqrt(pArgs[0].Contents.Float));
  331.  
  332.   return True;
  333. }
  334.  
  335. /* trigonometrische Funktionen */
  336.  
  337. static Boolean FuncSIN(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  338. {
  339.   UNUSED(ArgCnt);
  340.  
  341.   as_tempres_set_float(pResult, as_sin(pArgs[0].Contents.Float));
  342.  
  343.   return True;
  344. }
  345.  
  346. static Boolean FuncCOS(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  347. {
  348.   UNUSED(ArgCnt);
  349.  
  350.   as_tempres_set_float(pResult, as_cos(pArgs[0].Contents.Float));
  351.  
  352.   return True;
  353. }
  354.  
  355. static Boolean FuncTAN(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  356. {
  357.   UNUSED(ArgCnt);
  358.  
  359.   if (as_cos(pArgs[0].Contents.Float) == 0.0)
  360.   {
  361.     as_tempres_set_none(pResult);
  362.     WrError(ErrNum_InvFuncArg);
  363.   }
  364.   else
  365.     as_tempres_set_float(pResult, as_tan(pArgs[0].Contents.Float));
  366.  
  367.   return True;
  368. }
  369.  
  370. static Boolean FuncCOT(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  371. {
  372.   as_float_t FVal = as_sin(pArgs[0].Contents.Float);
  373.   UNUSED(ArgCnt);
  374.  
  375.   if (FVal == 0.0)
  376.   {
  377.     as_tempres_set_none(pResult);
  378.     WrError(ErrNum_InvFuncArg);
  379.   }
  380.   else
  381.     as_tempres_set_float(pResult, as_cos(pArgs[0].Contents.Float) / FVal);
  382.  
  383.   return True;
  384. }
  385.  
  386. /* inverse trigonometrische Funktionen */
  387.  
  388. static Boolean FuncASIN(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  389. {
  390.   UNUSED(ArgCnt);
  391.  
  392.   if (as_fabs(pArgs[0].Contents.Float) > 1)
  393.   {
  394.     as_tempres_set_none(pResult);
  395.     WrError(ErrNum_InvFuncArg);
  396.   }
  397.   else
  398.     as_tempres_set_float(pResult, as_asin(pArgs[0].Contents.Float));
  399.  
  400.   return True;
  401. }
  402.  
  403. static Boolean FuncACOS(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  404. {
  405.   UNUSED(ArgCnt);
  406.  
  407.   if (as_fabs(pArgs[0].Contents.Float) > 1)
  408.   {
  409.     as_tempres_set_none(pResult);
  410.     WrError(ErrNum_InvFuncArg);
  411.   }
  412.   else
  413.     as_tempres_set_float(pResult, as_acos(pArgs[0].Contents.Float));
  414.  
  415.   return True;
  416. }
  417.  
  418. static Boolean FuncATAN(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  419. {
  420.   UNUSED(ArgCnt);
  421.  
  422.   as_tempres_set_float(pResult, as_atan(pArgs[0].Contents.Float));
  423.  
  424.   return True;
  425. }
  426.  
  427. static Boolean FuncACOT(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  428. {
  429.   UNUSED(ArgCnt);
  430.  
  431.   as_tempres_set_float(pResult, M_PI / 2 - as_atan(pArgs[0].Contents.Float));
  432.  
  433.   return True;
  434. }
  435.  
  436. static Boolean FuncEXP(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  437. {
  438.   UNUSED(ArgCnt);
  439.  
  440.   if (pArgs[0].Contents.Float > log_max)
  441.   {
  442.     as_tempres_set_none(pResult);
  443.     WrError(ErrNum_FloatOverflow);
  444.   }
  445.   else
  446.     as_tempres_set_float(pResult, as_exp(pArgs[0].Contents.Float));
  447.  
  448.   return True;
  449. }
  450.  
  451. static Boolean FuncALOG(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  452. {
  453.   UNUSED(ArgCnt);
  454.  
  455.   if (pArgs[0].Contents.Float > log10_max)
  456.   {
  457.     as_tempres_set_none(pResult);
  458.     WrError(ErrNum_FloatOverflow);
  459.   }
  460.   else
  461.     as_tempres_set_float(pResult, as_exp(pArgs[0].Contents.Float * log(10.0)));
  462.  
  463.   return True;
  464. }
  465.  
  466. static Boolean FuncALD(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  467. {
  468.   UNUSED(ArgCnt);
  469.  
  470.   if (pArgs[0].Contents.Float > log2_max)
  471.   {
  472.     as_tempres_set_none(pResult);
  473.     WrError(ErrNum_FloatOverflow);
  474.   }
  475.   else
  476.     as_tempres_set_float(pResult, as_exp(pArgs[0].Contents.Float * log(2.0)));
  477.  
  478.   return True;
  479. }
  480.  
  481. static Boolean FuncSINH(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  482. {
  483.   UNUSED(ArgCnt);
  484.  
  485.   if (pArgs[0].Contents.Float > log_max)
  486.   {
  487.     as_tempres_set_none(pResult);
  488.     WrError(ErrNum_FloatOverflow);
  489.   }
  490.   else
  491.     as_tempres_set_float(pResult, as_sinh(pArgs[0].Contents.Float));
  492.  
  493.   return True;
  494. }
  495.  
  496. static Boolean FuncCOSH(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  497. {
  498.   UNUSED(ArgCnt);
  499.  
  500.   if (pArgs[0].Contents.Float > log_max)
  501.   {
  502.     as_tempres_set_none(pResult);
  503.     WrError(ErrNum_FloatOverflow);
  504.   }
  505.   else
  506.     as_tempres_set_float(pResult, as_cosh(pArgs[0].Contents.Float));
  507.  
  508.   return True;
  509. }
  510.  
  511. static Boolean FuncTANH(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  512. {
  513.   UNUSED(ArgCnt);
  514.  
  515.   if (pArgs[0].Contents.Float > log_max)
  516.   {
  517.     as_tempres_set_none(pResult);
  518.     WrError(ErrNum_FloatOverflow);
  519.   }
  520.   else
  521.     as_tempres_set_float(pResult, as_tanh(pArgs[0].Contents.Float));
  522.  
  523.   return True;
  524. }
  525.  
  526. static Boolean FuncCOTH(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  527. {
  528.   as_float_t FVal;
  529.  
  530.   UNUSED(ArgCnt);
  531.  
  532.   if (pArgs[0].Contents.Float > log_max)
  533.   {
  534.     as_tempres_set_none(pResult);
  535.     WrError(ErrNum_FloatOverflow);
  536.   }
  537.   else if ((FVal = as_tanh(pArgs[0].Contents.Float)) == 0.0)
  538.   {
  539.     as_tempres_set_none(pResult);
  540.     WrError(ErrNum_InvFuncArg);
  541.   }
  542.   else
  543.     as_tempres_set_float(pResult, pResult->Contents.Float = 1.0 / FVal);
  544.  
  545.   return True;
  546. }
  547.  
  548. /* logarithmische & inverse hyperbolische Funktionen */
  549.  
  550. static Boolean FuncLN(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  551. {
  552.   UNUSED(ArgCnt);
  553.  
  554.   if (pArgs[0].Contents.Float <= 0)
  555.   {
  556.     as_tempres_set_none(pResult);
  557.     WrError(ErrNum_InvFuncArg);
  558.   }
  559.   else
  560.     as_tempres_set_float(pResult, as_log(pArgs[0].Contents.Float));
  561.  
  562.   return True;
  563. }
  564.  
  565. static Boolean FuncLOG(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  566. {
  567.   UNUSED(ArgCnt);
  568.  
  569.   if (pArgs[0].Contents.Float <= 0)
  570.   {
  571.     as_tempres_set_none(pResult);
  572.     WrError(ErrNum_InvFuncArg);
  573.   }
  574.   else
  575.     as_tempres_set_float(pResult, as_log10(pArgs[0].Contents.Float));
  576.  
  577.   return True;
  578. }
  579.  
  580. static Boolean FuncLD(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  581. {
  582.   UNUSED(ArgCnt);
  583.  
  584.   if (pArgs[0].Contents.Float <= 0)
  585.   {
  586.     as_tempres_set_none(pResult);
  587.     WrError(ErrNum_InvFuncArg);
  588.   }
  589.   else
  590.     as_tempres_set_float(pResult, as_log(pArgs[0].Contents.Float) / as_log(2.0));
  591.  
  592.   return True;
  593. }
  594.  
  595. static Boolean FuncASINH(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  596. {
  597.   UNUSED(ArgCnt);
  598.  
  599.   as_tempres_set_float(pResult, as_log(pArgs[0].Contents.Float + as_sqrt(pArgs[0].Contents.Float * pArgs[0].Contents.Float + 1)));
  600.  
  601.   return True;
  602. }
  603.  
  604. static Boolean FuncACOSH(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  605. {
  606.   UNUSED(ArgCnt);
  607.  
  608.   if (pArgs[0].Contents.Float < 1)
  609.   {
  610.     as_tempres_set_none(pResult);
  611.     WrError(ErrNum_FloatOverflow);
  612.   }
  613.   else
  614.     as_tempres_set_float(pResult, as_log(pArgs[0].Contents.Float + as_sqrt(pArgs[0].Contents.Float * pArgs[0].Contents.Float - 1)));
  615.  
  616.   return True;
  617. }
  618.  
  619. static Boolean FuncATANH(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  620. {
  621.   UNUSED(ArgCnt);
  622.  
  623.   if (as_fabs(pArgs[0].Contents.Float) >= 1)
  624.   {
  625.     as_tempres_set_none(pResult);
  626.     WrError(ErrNum_FloatOverflow);
  627.   }
  628.   else
  629.     as_tempres_set_float(pResult, 0.5 * as_log((1 + pArgs[0].Contents.Float) / (1 - pArgs[0].Contents.Float)));
  630.  
  631.   return True;
  632. }
  633.  
  634. static Boolean FuncACOTH(TempResult *pResult, const TempResult *pArgs, unsigned ArgCnt)
  635. {
  636.   UNUSED(ArgCnt);
  637.  
  638.   if (as_fabs(pArgs[0].Contents.Float) <= 1)
  639.   {
  640.     as_tempres_set_none(pResult);
  641.     WrError(ErrNum_FloatOverflow);
  642.   }
  643.   else
  644.     as_tempres_set_float(pResult, 0.5 * as_log((pArgs[0].Contents.Float + 1) / (pArgs[0].Contents.Float - 1)));
  645.  
  646.   return True;
  647. }
  648.  
  649. #define TempAll (TempInt | TempFloat | TempString)
  650.  
  651. static const tFunction Functions[] =
  652. {
  653.   { "SUBSTR"     , 3, 3, { TempString              , TempInt        , TempInt        }, FuncSUBSTR      },
  654.   { "STRSTR"     , 2, 2, { TempString              , TempString     , 0              }, FuncSTRSTR      },
  655.   { "CHARFROMSTR", 2, 2, { TempString              , TempInt        , 0              }, FuncCHARFROMSTR },
  656.   { "CODEPAGE_VAL",1, 2, { TempInt                 , TempString     , 0              }, FuncCODEPAGE_VAL},
  657.   { "EXPRTYPE"   , 1, 1, { TempAll                 , 0              , 0              }, FuncEXPRTYPE    },
  658.   { "UPSTRING"   , 1, 1, { TempString              , 0              , 0              }, FuncUPSTRING    },
  659.   { "LOWSTRING"  , 1, 1, { TempString              , 0              , 0              }, FuncLOWSTRING   },
  660.   { "STRLEN"     , 1, 1, { TempString              , 0              , 0              }, FuncSTRLEN      },
  661.   { "VAL"        , 1, 1, { TempString              , 0              , 0              }, FuncVAL         },
  662.   { "TOUPPER"    , 1, 1, { TempInt                 , 0              , 0              }, FuncTOUPPER     },
  663.   { "TOLOWER"    , 1, 1, { TempInt                 , 0              , 0              }, FuncTOLOWER     },
  664.   { "BITCNT"     , 1, 1, { TempInt                 , 0              , 0              }, FuncBITCNT      },
  665.   { "FIRSTBIT"   , 1, 1, { TempInt                 , 0              , 0              }, FuncFIRSTBIT    },
  666.   { "LASTBIT"    , 1, 1, { TempInt                 , 0              , 0              }, FuncLASTBIT     },
  667.   { "BITPOS"     , 1, 1, { TempInt                 , 0              , 0              }, FuncBITPOS      },
  668.   { "ABS"        , 1, 1, { TempInt | TempFloat     , 0              , 0              }, FuncABS         },
  669.   { "SGN"        , 1, 1, { TempInt | TempFloat     , 0              , 0              }, FuncSGN         },
  670.   { "INT"        , 1, 1, { TempFloat               , 0              , 0              }, FuncINT         },
  671.   { "SQRT"       , 1, 1, { TempFloat               , 0              , 0              }, FuncSQRT        },
  672.   { "SIN"        , 1, 1, { TempFloat               , 0              , 0              }, FuncSIN         },
  673.   { "COS"        , 1, 1, { TempFloat               , 0              , 0              }, FuncCOS         },
  674.   { "TAN"        , 1, 1, { TempFloat               , 0              , 0              }, FuncTAN         },
  675.   { "COT"        , 1, 1, { TempFloat               , 0              , 0              }, FuncCOT         },
  676.   { "ASIN"       , 1, 1, { TempFloat               , 0              , 0              }, FuncASIN        },
  677.   { "ACOS"       , 1, 1, { TempFloat               , 0              , 0              }, FuncACOS        },
  678.   { "ATAN"       , 1, 1, { TempFloat               , 0              , 0              }, FuncATAN        },
  679.   { "ACOT"       , 1, 1, { TempFloat               , 0              , 0              }, FuncACOT        },
  680.   { "EXP"        , 1, 1, { TempFloat               , 0              , 0              }, FuncEXP         },
  681.   { "ALOG"       , 1, 1, { TempFloat               , 0              , 0              }, FuncALOG        },
  682.   { "ALD"        , 1, 1, { TempFloat               , 0              , 0              }, FuncALD         },
  683.   { "SINH"       , 1, 1, { TempFloat               , 0              , 0              }, FuncSINH        },
  684.   { "COSH"       , 1, 1, { TempFloat               , 0              , 0              }, FuncCOSH        },
  685.   { "TANH"       , 1, 1, { TempFloat               , 0              , 0              }, FuncTANH        },
  686.   { "COTH"       , 1, 1, { TempFloat               , 0              , 0              }, FuncCOTH        },
  687.   { "LN"         , 1, 1, { TempFloat               , 0              , 0              }, FuncLN          },
  688.   { "LOG"        , 1, 1, { TempFloat               , 0              , 0              }, FuncLOG         },
  689.   { "LD"         , 1, 1, { TempFloat               , 0              , 0              }, FuncLD          },
  690.   { "ASINH"      , 1, 1, { TempFloat               , 0              , 0              }, FuncASINH       },
  691.   { "ACOSH"      , 1, 1, { TempFloat               , 0              , 0              }, FuncACOSH       },
  692.   { "ATANH"      , 1, 1, { TempFloat               , 0              , 0              }, FuncATANH       },
  693.   { "ACOTH"      , 1, 1, { TempFloat               , 0              , 0              }, FuncACOTH       },
  694.   { "PHYS2CPU"   , 1, 1, { TempInt                 , 0              , 0              }, fnc_phys_2_cpu  },
  695.   { "CPU2PHYS"   , 1, 1, { TempInt                 , 0              , 0              }, fnc_cpu_2_phys  },
  696.   { NULL         , 0, 0, { 0                            , 0              , 0              }, NULL            }
  697. };
  698.  
  699. /*!------------------------------------------------------------------------
  700.  * \fn     tFunction *function_find(const char *p_name)
  701.  * \brief  look up built-in function
  702.  * \param  p_name function name
  703.  * \return retrieved function or NULL if not found
  704.  * ------------------------------------------------------------------------ */
  705.  
  706. const tFunction *function_find(const char *p_name)
  707. {
  708.   const tFunction *p_run;
  709.  
  710.   for (p_run = Functions; p_run->pName; p_run++)
  711.     if (!strcmp(p_name, p_run->pName))
  712.       return p_run;
  713.   return NULL;
  714. }
  715.  
  716. /*!------------------------------------------------------------------------
  717.  * \fn     function_init(void)
  718.  * \brief  module setup
  719.  * ------------------------------------------------------------------------ */
  720.  
  721. void function_init(void)
  722. {
  723.   log_max = as_log(AS_FLOAT_MAX);
  724.   log2_max = log_max / log(2.0);
  725.   log10_max = as_log10(AS_FLOAT_MAX);
  726. }
  727.