1 /*****************************************************************************/
5 /* Token list for the ca65 macroassembler */
9 /* (C) 1998-2012, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
52 /*****************************************************************************/
54 /*****************************************************************************/
58 /* Number of currently pushed token lists */
59 static unsigned PushCounter = 0;
63 /*****************************************************************************/
65 /*****************************************************************************/
69 TokNode* NewTokNode (void)
70 /* Create and return a token node with the current token value */
74 TokNode* N = xmalloc (sizeof (TokNode));
76 /* Initialize the token contents */
79 CopyToken (&N->T, &CurTok);
87 void FreeTokNode (TokNode* N)
88 /* Free the given token node */
96 void TokSet (TokNode* N)
97 /* Set the scanner token from the given token node. */
100 CopyToken (&CurTok, &N->T);
101 SB_Terminate (&CurTok.SVal);
106 enum TC TokCmp (const TokNode* N)
107 /* Compare the token given as parameter against the current token */
109 if (N->T.Tok != CurTok.Tok) {
110 /* Different token */
114 /* If the token has string attribute, check it */
115 if (TokHasSVal (N->T.Tok)) {
116 if (SB_Compare (&CurTok.SVal, &N->T.SVal) != 0) {
119 } else if (TokHasIVal (N->T.Tok)) {
120 if (N->T.IVal != CurTok.IVal) {
125 /* Tokens are identical */
131 TokList* NewTokList (void)
132 /* Create a new, empty token list */
134 /* Allocate memory for the list structure */
135 TokList* T = xmalloc (sizeof (TokList));
137 /* Initialize the fields */
148 /* Return the new list */
154 void FreeTokList (TokList* List)
155 /* Delete the token list including all token nodes */
157 /* Free the token list */
158 TokNode* T = List->Root;
165 /* Free associated line info */
170 /* If we have associated data, free it */
175 /* Free the list structure itself */
181 enum token_t GetTokListTerm (enum token_t Term)
182 /* Determine if the following token list is enclosed in curly braces. This is
183 ** the case if the next token is the opening brace. If so, skip it and return
184 ** a closing brace, otherwise return Term.
187 if (CurTok.Tok == TOK_LCURLY) {
197 void AddCurTok (TokList* List)
198 /* Add the current token to the token list */
200 /* Create a token node with the current token value */
201 TokNode* T = NewTokNode ();
203 /* Insert the node into the list */
204 if (List->Root == 0) {
207 List->Last->Next = T;
217 static int ReplayTokList (void* List)
218 /* Function that gets the next token from a token list and sets it. This
219 ** function may be used together with the PushInput function from the istack
223 /* Cast the generic pointer to an actual list */
226 /* If there are no more tokens, decrement the repeat counter. If it goes
227 ** zero, delete the list and remove the function from the stack.
230 if (++L->RepCount >= L->RepMax) {
231 /* Done with this list */
237 /* Replay one more time */
242 /* Set the next token from the list */
245 /* Set the line info for the new token */
249 L->LI = StartLine (&CurTok.Pos, LI_TYPE_ASM, PushCounter);
251 /* If a check function is defined, call it, so it may look at the token
252 ** just set and changed it as apropriate.
258 /* Set the pointer to the next token */
259 L->Last = L->Last->Next;
261 /* We have a token */
267 void PushTokList (TokList* List, const char* Desc)
268 /* Push a token list to be used as input for InputFromStack. This includes
269 ** several initializations needed in the token list structure, so don't use
270 ** PushInput directly.
273 /* If the list is empty, just delete it and bail out */
274 if (List->Count == 0) {
279 /* Reset the last pointer to the first element */
280 List->Last = List->Root;
282 /* Insert the list specifying our input function */
284 PushInput (ReplayTokList, List, Desc);