Subversion Repositories pentevo

Rev

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

  1. /* asmif.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Befehle zur bedingten Assemblierung                                       */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "bpemu.h"
  16. #include "chunks.h"
  17. #include "strutil.h"
  18. #include "errmsg.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22.  
  23. #include "asmif.h"
  24.  
  25.  
  26. PIfSave FirstIfSave;
  27. Boolean IfAsm;       /* FALSE: in einer neg. IF-Sequenz-->kein Code */
  28.  
  29. static Boolean ActiveIF;
  30.  
  31. /*!------------------------------------------------------------------------
  32.  * \fn     ifsave_create(tIfState if_state, Boolean case_found)
  33.  * \brief  create new IF stack element
  34.  * \param  if_state initial state of related construct
  35.  * \param  case_found in block enabled by IF/CASE?
  36.  * \return * to new element
  37.  * ------------------------------------------------------------------------ */
  38.  
  39. static PIfSave ifsave_create(tIfState if_state, Boolean case_found)
  40. {
  41.   PIfSave p_save;
  42.  
  43.   p_save = (PIfSave) malloc(sizeof(TIfSave));
  44.   if (p_save)
  45.   {
  46.     p_save->Next = NULL;
  47.     p_save->NestLevel = SaveIFs() + 1;
  48.     p_save->SaveIfAsm = IfAsm;
  49.     as_tempres_ini(&p_save->SaveExpr);
  50.     p_save->CaseFound = case_found;
  51.     p_save->State = if_state;
  52.     p_save->StartLine = CurrLine;
  53.   }
  54.   return p_save;
  55. }
  56.  
  57. /*!------------------------------------------------------------------------
  58.  * \fn     ifsave_free(PIfSave p_save)
  59.  * \brief  destroy IF stack element
  60.  * \param  p_save element to destroy
  61.  * ------------------------------------------------------------------------ */
  62.  
  63. static void ifsave_free(PIfSave p_save)
  64. {
  65.   as_tempres_free(&p_save->SaveExpr);
  66.   free(p_save);
  67. }
  68.  
  69. static LongInt GetIfVal(const tStrComp *pCond)
  70. {
  71.   Boolean IfOK;
  72.   tSymbolFlags Flags;
  73.   LongInt Tmp;
  74.  
  75.   Tmp = EvalStrIntExpressionWithFlags(pCond, Int32, &IfOK, &Flags);
  76.   if (mFirstPassUnknown(Flags) || !IfOK)
  77.   {
  78.     Tmp = 1;
  79.     if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  80.   }
  81.  
  82.   return Tmp;
  83. }
  84.  
  85.  
  86. static void AddBoolFlag(Boolean Flag)
  87. {
  88.   strmaxcpy(ListLine, Flag ? "=>TRUE" : "=>FALSE", STRINGSIZE);
  89. }
  90.  
  91.  
  92. static void PushIF(LongInt IfExpr)
  93. {
  94.   PIfSave NewSave = ifsave_create(IfState_IFIF, IfExpr != 0);
  95.  
  96.   NewSave->Next = FirstIfSave;
  97.   FirstIfSave = NewSave;
  98.   IfAsm = IfAsm && NewSave->CaseFound;
  99. }
  100.  
  101.  
  102. static void CodeIF(void)
  103. {
  104.   LongInt IfExpr;
  105.  
  106.   ActiveIF = IfAsm;
  107.  
  108.   if (!IfAsm)
  109.     IfExpr = 1;
  110.   else if (!ChkArgCnt(1, 1))
  111.     IfExpr = 1;
  112.   else
  113.     IfExpr = GetIfVal(&ArgStr[1]);
  114.   if (IfAsm)
  115.     AddBoolFlag(IfExpr != 0);
  116.   PushIF(IfExpr);
  117. }
  118.  
  119.  
  120. static void CodeIFDEF(Word Negate)
  121. {
  122.   LongInt IfExpr;
  123.   Boolean Defined;
  124.  
  125.   ActiveIF = IfAsm;
  126.  
  127.   if (!IfAsm) IfExpr = 1;
  128.   else if (!ChkArgCnt(1, 1))
  129.     IfExpr = 1;
  130.   else
  131.   {
  132.     Defined = IsSymbolDefined(&ArgStr[1]);
  133.     if (IfAsm)
  134.       strmaxcpy(ListLine, (Defined) ? "=>DEFINED" : "=>UNDEFINED", STRINGSIZE);
  135.     if (!Negate)
  136.       IfExpr = (Defined) ? 1 : 0;
  137.     else
  138.       IfExpr = (Defined) ? 0 : 1;
  139.   }
  140.   PushIF(IfExpr);
  141. }
  142.  
  143.  
  144. static void CodeIFUSED(Word Negate)
  145. {
  146.   LongInt IfExpr;
  147.   Boolean Used;
  148.  
  149.   ActiveIF = IfAsm;
  150.  
  151.   if (!IfAsm)
  152.     IfExpr = 1;
  153.   else if (!ChkArgCnt(1, 1))
  154.     IfExpr = 1;
  155.   else
  156.   {
  157.     Used = IsSymbolUsed(&ArgStr[1]);
  158.     if (IfAsm)
  159.       strmaxcpy(ListLine, (Used) ? "=>USED" : "=>UNUSED", STRINGSIZE);
  160.     if (!Negate)
  161.       IfExpr = (Used) ? 1 : 0;
  162.     else
  163.       IfExpr = (Used) ? 0 : 1;
  164.   }
  165.   PushIF(IfExpr);
  166. }
  167.  
  168.  
  169. void CodeIFEXIST(Word Negate)
  170. {
  171.   LongInt IfExpr;
  172.   Boolean Found;
  173.   String NPath;
  174.  
  175.   ActiveIF = IfAsm;
  176.  
  177.   if (!IfAsm)
  178.     IfExpr = 1;
  179.   else if (!ChkArgCnt(1, 1))
  180.     IfExpr = 1;
  181.   else
  182.   {
  183.     String FileName, Dummy;
  184.  
  185.     strmaxcpy(FileName, (ArgStr[1].str.p_str[0] == '"') ? ArgStr[1].str.p_str + 1 : ArgStr[1].str.p_str, STRINGSIZE);
  186.     if (FileName[strlen(FileName) - 1] == '"')
  187.       FileName[strlen(FileName) - 1] = '\0';
  188.     AddSuffix(FileName, IncSuffix);
  189.     strmaxcpy(NPath, IncludeList, STRINGSIZE);
  190.     strmaxprep(NPath, SDIRSEP, STRINGSIZE);
  191.     strmaxprep(NPath, ".", STRINGSIZE);
  192.     Found = !FSearch(Dummy, sizeof(Dummy), FileName, CurrFileName, NPath);
  193.     if (IfAsm)
  194.       strmaxcpy(ListLine, Found ? "=>FOUND" : "=>NOT FOUND", STRINGSIZE);
  195.     IfExpr = Negate ? !Found : Found;
  196.   }
  197.   PushIF(IfExpr);
  198. }
  199.  
  200.  
  201. static void CodeIFB(Word Negate)
  202. {
  203.   Boolean Blank = True;
  204.   LongInt IfExpr;
  205.   int z;
  206.  
  207.   ActiveIF = IfAsm;
  208.  
  209.   if (!IfAsm)
  210.     IfExpr = 1;
  211.   else
  212.   {
  213.     for (z = 1; z <= ArgCnt; z++)
  214.       if (strlen(ArgStr[z++].str.p_str) > 0)
  215.         Blank = False;
  216.     if (IfAsm)
  217.       strmaxcpy(ListLine, (Blank) ? "=>BLANK" : "=>NOT BLANK", STRINGSIZE);
  218.     IfExpr = Negate ? !Blank : Blank;
  219.   }
  220.   PushIF(IfExpr);
  221. }
  222.  
  223.  
  224. static void CodeELSEIF(void)
  225. {
  226.   LongInt IfExpr;
  227.  
  228.   if (!FirstIfSave || (FirstIfSave->State != IfState_IFIF)) WrError(ErrNum_MissingIf);
  229.   else if (ArgCnt == 0)
  230.   {
  231.     if (FirstIfSave->SaveIfAsm)
  232.       AddBoolFlag(IfAsm = (!FirstIfSave->CaseFound));
  233.     FirstIfSave->State = IfState_IFELSE;
  234.   }
  235.   else if (ArgCnt == 1)
  236.   {
  237.     if (!FirstIfSave->SaveIfAsm)
  238.       IfExpr = 1;
  239.     else if (FirstIfSave->CaseFound)
  240.       IfExpr = 0;
  241.     else
  242.       IfExpr = GetIfVal(&ArgStr[1]);
  243.     IfAsm = ((FirstIfSave->SaveIfAsm) && (IfExpr != 0) && (!FirstIfSave->CaseFound));
  244.     if (FirstIfSave->SaveIfAsm)
  245.       AddBoolFlag(IfExpr != 0);
  246.     if (IfExpr != 0)
  247.       FirstIfSave->CaseFound = True;
  248.   }
  249.   else
  250.     (void)ChkArgCnt(0, 1);
  251.  
  252.   ActiveIF = (!FirstIfSave) || (FirstIfSave->SaveIfAsm);
  253. }
  254.  
  255.  
  256. static void CodeENDIF(void)
  257. {
  258.   if (!ChkArgCnt(0, 0));
  259.   else if (!FirstIfSave || ((FirstIfSave->State != IfState_IFIF) && (FirstIfSave->State != IfState_IFELSE))) WrError(ErrNum_MissingIf);
  260.   else
  261.   {
  262.     PIfSave NewSave;
  263.  
  264.     IfAsm = FirstIfSave->SaveIfAsm;
  265.     NewSave = FirstIfSave;
  266.     FirstIfSave = NewSave->Next;
  267.     as_snprintf(ListLine, STRINGSIZE, "[%u]", (unsigned)NewSave->StartLine);
  268.     ifsave_free(NewSave);
  269.   }
  270.  
  271.   ActiveIF = IfAsm;
  272. }
  273.  
  274.  
  275. static void EvalIfExpression(const tStrComp *pCond, TempResult *erg)
  276. {
  277.   EvalStrExpression(pCond, erg);
  278.   if ((erg->Typ == TempNone) || mFirstPassUnknown(erg->Flags))
  279.   {
  280.     as_tempres_set_int(erg, 1);
  281.     if (mFirstPassUnknown(erg->Flags))
  282.       WrError(ErrNum_FirstPassCalc);
  283.   }
  284. }
  285.  
  286.  
  287. static void CodeSWITCH(void)
  288. {
  289.   PIfSave NewSave = ifsave_create(IfState_CASESWITCH, False);
  290.  
  291.   ActiveIF = IfAsm;
  292.  
  293.   if (ArgCnt != 1)
  294.   {
  295.     as_tempres_set_int(&NewSave->SaveExpr, 1);
  296.     if (IfAsm)
  297.       (void)ChkArgCnt(1, 1);
  298.   }
  299.   else
  300.   {
  301.     EvalIfExpression(&ArgStr[1], &NewSave->SaveExpr);
  302.     SetListLineVal(&NewSave->SaveExpr);
  303.   }
  304.   NewSave->Next = FirstIfSave;
  305.   FirstIfSave = NewSave;
  306. }
  307.  
  308.  
  309. static void CodeCASE(void)
  310. {
  311.   Boolean eq;
  312.   int z;
  313.  
  314.   if (!FirstIfSave) WrError(ErrNum_MissingIf);
  315.   else if (ChkArgCnt(1, ArgCntMax))
  316.   {
  317.     if ((FirstIfSave->State != IfState_CASESWITCH) && (FirstIfSave->State != IfState_CASECASE)) WrError(ErrNum_InvIfConst);
  318.     else
  319.     {
  320.       if (!FirstIfSave->SaveIfAsm)
  321.         eq = True;
  322.       else if (FirstIfSave->CaseFound)
  323.         eq = False;
  324.       else
  325.       {
  326.         TempResult t;
  327.  
  328.         as_tempres_ini(&t);
  329.         eq = False;
  330.         z = 1;
  331.         do
  332.         {
  333.           EvalIfExpression(&ArgStr[z], &t);
  334.           eq = (FirstIfSave->SaveExpr.Typ == t.Typ);
  335.           if (eq)
  336.            switch (t.Typ)
  337.            {
  338.              case TempInt:
  339.                eq = (t.Contents.Int == FirstIfSave->SaveExpr.Contents.Int);
  340.                break;
  341.              case TempFloat:
  342.                eq = (t.Contents.Float == FirstIfSave->SaveExpr.Contents.Float);
  343.                break;
  344.              case TempString:
  345.                eq = (as_nonz_dynstr_cmp(&t.Contents.str, &FirstIfSave->SaveExpr.Contents.str) == 0);
  346.                break;
  347.              default:
  348.                eq = False;
  349.                break;
  350.            }
  351.           z++;
  352.         }
  353.         while (!eq && (z <= ArgCnt));
  354.         as_tempres_free(&t);
  355.       }
  356.       IfAsm = (FirstIfSave->SaveIfAsm && eq & !FirstIfSave->CaseFound);
  357.       if (FirstIfSave->SaveIfAsm)
  358.         AddBoolFlag(eq && !FirstIfSave->CaseFound);
  359.       if (eq)
  360.         FirstIfSave->CaseFound = True;
  361.       FirstIfSave->State = IfState_CASECASE;
  362.     }
  363.   }
  364.  
  365.   ActiveIF = !FirstIfSave || FirstIfSave->SaveIfAsm;
  366. }
  367.  
  368.  
  369. static void CodeELSECASE(void)
  370. {
  371.   if (ChkArgCnt(0, 0))
  372.   {
  373.     if ((FirstIfSave->State != IfState_CASESWITCH) && (FirstIfSave->State != IfState_CASECASE)) WrError(ErrNum_InvIfConst);
  374.     else
  375.       IfAsm = (FirstIfSave->SaveIfAsm && (!FirstIfSave->CaseFound));
  376.     if (FirstIfSave->SaveIfAsm)
  377.       AddBoolFlag(!FirstIfSave->CaseFound);
  378.     FirstIfSave->CaseFound = True;
  379.     FirstIfSave->State = IfState_CASEELSE;
  380.   }
  381.  
  382.   ActiveIF = (!FirstIfSave) || (FirstIfSave->SaveIfAsm);
  383. }
  384.  
  385.  
  386. static void CodeENDCASE(void)
  387. {
  388.   if (!ChkArgCnt(0, 0));
  389.   else if (!FirstIfSave) WrError(ErrNum_MissingIf);
  390.   else
  391.   {
  392.     if ((FirstIfSave->State != IfState_CASESWITCH)
  393.     && (FirstIfSave->State != IfState_CASECASE)
  394.     && (FirstIfSave->State != IfState_CASEELSE)) WrError(ErrNum_InvIfConst);
  395.     else
  396.     {
  397.       PIfSave NewSave;
  398.  
  399.       IfAsm = FirstIfSave->SaveIfAsm;
  400.       if (!FirstIfSave->CaseFound) WrError(ErrNum_NoCaseHit);
  401.       NewSave = FirstIfSave;
  402.       FirstIfSave = NewSave->Next;
  403.       as_snprintf(ListLine, STRINGSIZE, "[%u]", (unsigned)NewSave->StartLine);
  404.       ifsave_free(NewSave);
  405.     }
  406.   }
  407.  
  408.   ActiveIF = IfAsm;
  409. }
  410.  
  411.  
  412. Boolean CodeIFs(void)
  413. {
  414.   Boolean Result = True;
  415.  
  416.   ActiveIF = False;
  417.  
  418.   switch (as_toupper(*OpPart.str.p_str))
  419.   {
  420.     case 'I':
  421.       if (Memo("IF")) CodeIF();
  422.       else if (Memo("IFDEF")) CodeIFDEF(False);
  423.       else if (Memo("IFNDEF")) CodeIFDEF(True);
  424.       else if (Memo("IFUSED")) CodeIFUSED(False);
  425.       else if (Memo("IFNUSED")) CodeIFUSED(True);
  426.       else if (Memo("IFEXIST")) CodeIFEXIST(False);
  427.       else if (Memo("IFNEXIST")) CodeIFEXIST(True);
  428.       else if (Memo("IFB")) CodeIFB(False);
  429.       else if (Memo("IFNB")) CodeIFB(True);
  430.       else Result = False;
  431.       break;
  432.     case 'E':
  433.       if ((Memo("ELSE")) || (Memo("ELSEIF"))) CodeELSEIF();
  434.       else if (Memo("ENDIF")) CodeENDIF();
  435.       else if (Memo("ELSECASE")) CodeELSECASE();
  436.       else if (Memo("ENDCASE")) CodeENDCASE();
  437.       else Result = False;
  438.       break;
  439.     case 'S':
  440.       if (memo_switch_pseudo()) CodeSWITCH();
  441.       else if (Memo("SELECT") && SwitchIsOccupied) CodeSWITCH();
  442.       else Result = False;
  443.       break;
  444.     case 'C':
  445.       if (Memo("CASE")) CodeCASE();
  446.       else Result = False;
  447.       break;
  448.     case '.':
  449.       if (Memo(".SWITCH")) CodeSWITCH();
  450.       else Result = False;
  451.       break;
  452.     default:
  453.       Result = False;
  454.   }
  455.  
  456.   return Result;
  457. }
  458.  
  459. Integer SaveIFs(void)
  460. {
  461.   return (!FirstIfSave) ? 0 : FirstIfSave->NestLevel;
  462. }
  463.  
  464. void RestoreIFs(Integer Level)
  465. {
  466.   PIfSave OldSave;
  467.  
  468.   while (FirstIfSave && (FirstIfSave->NestLevel != Level))
  469.   {
  470.     OldSave = FirstIfSave;
  471.     FirstIfSave = OldSave->Next;
  472.     IfAsm = OldSave->SaveIfAsm;
  473.     ifsave_free(OldSave);
  474.   }
  475. }
  476.  
  477. Boolean IFListMask(void)
  478. {
  479.   switch (ListOn)
  480.   {
  481.     case 0:
  482.       return True;
  483.     case 1:
  484.       return False;
  485.     case 2:
  486.       return ((!ActiveIF) && (!IfAsm));
  487.     case 3:
  488.       return (ActiveIF || (!IfAsm));
  489.   }
  490.   return True;
  491. }
  492.  
  493. void AsmIFInit(void)
  494. {
  495.   IfAsm = True;
  496. }
  497.  
  498. void asmif_init(void)
  499. {
  500. }
  501.