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