1 /* codepseudo.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Haeufiger benutzte Pseudo-Befehle                                         */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 /*****************************************************************************
12  * Includes
13  *****************************************************************************/
14 
15 #include "stdinc.h"
16 #include <string.h>
17 #include <ctype.h>
18 #include <math.h>
19 
20 #include "nls.h"
21 #include "bpemu.h"
22 #include "endian.h"
23 #include "strutil.h"
24 #include "chunks.h"
25 #include "asmdef.h"
26 #include "asmsub.h"
27 #include "asmpars.h"
28 #include "asmallg.h"
29 #include "asmitree.h"
30 #include "errmsg.h"
31 
32 #include "codepseudo.h"
33 #include "motpseudo.h"
34 
35 /*****************************************************************************
36  * Global Functions
37  *****************************************************************************/
38 
39 /*****************************************************************************
40  * Function:    IsIndirect
41  * Purpose:     check whether argument is syntactically 'indirect', i.e.
42  *              enclosed in 'extra' parentheses.
43  * Result:      TRUE if indirect
44  *****************************************************************************/
45 
IsIndirectGen(const char * Asc,const char * pBeginEnd)46 Boolean IsIndirectGen(const char *Asc, const char *pBeginEnd)
47 {
48   int z,Level,l;
49 
50   if (((l = strlen(Asc)) <= 2)
51    || (Asc[0] != pBeginEnd[0])
52    || (Asc[l - 1] != pBeginEnd[1]))
53     return False;
54 
55   Level = 0;
56   for (z = 1; z <= l - 2; z++)
57   {
58     if (Asc[z] == pBeginEnd[0]) Level++;
59     if (Asc[z] == pBeginEnd[1]) Level--;
60     if (Level < 0) return False;
61   }
62 
63   return True;
64 }
65 
IsIndirect(const char * Asc)66 Boolean IsIndirect(const char *Asc)
67 {
68   return IsIndirectGen(Asc, "()");
69 }
70 
71 /*****************************************************************************
72  * Function:    CodeEquate
73  * Purpose:     EQU for different segment
74  * Result:      -
75  *****************************************************************************/
76 
CodeEquate(ShortInt DestSeg,LargeInt Min,LargeInt Max)77 void CodeEquate(ShortInt DestSeg, LargeInt Min, LargeInt Max)
78 {
79   Boolean OK;
80   tSymbolFlags Flags;
81   TempResult t;
82   LargeInt Erg;
83 
84   if (ChkArgCnt(1, 1))
85   {
86     Erg = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
87     if (OK && !mFirstPassUnknown(Flags))
88     {
89       if (Min > Erg) WrError(ErrNum_UnderRange);
90       else if (Erg > Max) WrError(ErrNum_OverRange);
91       else
92       {
93         PushLocHandle(-1);
94         EnterIntSymbol(&LabPart, Erg, DestSeg, False);
95         PopLocHandle();
96         if (MakeUseList)
97           if (AddChunk(SegChunks + DestSeg, Erg, 1, False)) WrError(ErrNum_Overlap);
98         t.Typ = TempInt; t.Contents.Int = Erg; SetListLineVal(&t);
99       }
100     }
101   }
102 }
103 
104 /*!------------------------------------------------------------------------
105  * \fn     QualifyQuote_SingleQuoteConstant(const char *pStart, const char *pQuotePos)
106  * \brief  check whether ' in source is lead-in to character string or int constant
107  * \param  pStart complete string
108  * \param  pQuotePos single quote position
109  * \return True if this is NO lead-in of int constant
110  * ------------------------------------------------------------------------ */
111 
QualifyQuote_SingleQuoteConstant(const char * pStart,const char * pQuotePos)112 Boolean QualifyQuote_SingleQuoteConstant(const char *pStart, const char *pQuotePos)
113 {
114   const char *pRun;
115   Boolean OK;
116   int Base;
117 
118   /* previous character must be H X B O */
119 
120   if (pQuotePos == pStart)
121     return True;
122   switch (as_toupper(*(pQuotePos - 1)))
123   {
124     case 'B':
125       Base = 2; break;
126     case 'O':
127       Base = 8; break;
128     case 'X':
129     case 'H':
130       Base = 16; break;
131     default:
132       return True;
133   }
134 
135   /* Scan for following valid (binary/octal/hex) character(s) */
136 
137   for (pRun = pQuotePos + 1; *pRun; pRun++)
138   {
139     switch (Base)
140     {
141       case 16: OK = as_isxdigit(*pRun); break;
142       case 8: OK = as_isdigit(*pRun) && (*pRun < '8'); break;
143       case 2: OK = as_isdigit(*pRun) && (*pRun < '2'); break;
144       default: OK = False;
145     }
146     if (!OK)
147       break;
148   }
149 
150   /* none? -> bad */
151 
152   if (pRun <= pQuotePos + 1)
153     return True;
154 
155   /* If we've hit another ' after them, it is the "harmless" x'...' form,
156      and no special treatment is needed */
157 
158   if ('\'' == *pRun)
159     return True;
160 
161   /* Other token or string continues -> cannot be such a constant, otherwise we
162      have a match and the ' does NOT lead in a character string: */
163 
164   return isalnum(*pRun);
165 }
166 
167