void PushTokList (TokList* List, const char* Desc) /* Push a token list to be used as input for InputFromStack. This includes * several initializations needed in the token list structure, so don't use * PushInput directly. */ { /* If the list is empty, just delete it and bail out */ if (List->Count == 0) { FreeTokList (List); return; } /* Reset the last pointer to the first element */ List->Last = List->Root; /* Insert the list specifying our input function */ PushInput (ReplayTokList, List, Desc); }
static void StartExpDefine (MacExp* E) /* Start expanding a DEFINE style macro */ { /* A define style macro must be called with as many actual parameters * as there are formal ones. Get the parameter count. */ unsigned Count = E->M->ParamCount; /* Skip the current token */ NextTok (); /* Read the actual parameters */ while (Count--) { TokNode* Last; /* The macro may optionally be enclosed in curly braces */ token_t Term = GetTokListTerm (TOK_COMMA); /* Check if there is really a parameter */ if (TokIsSep (CurTok.Tok) || CurTok.Tok == Term) { ErrorSkip ("Macro parameter #%u is empty", E->ParamCount+1); FreeMacExp (E); return; } /* Read tokens for one parameter */ Last = 0; do { TokNode* T; /* Get the next token in a node */ T = NewTokNode (); /* Insert it into the list */ if (Last == 0) { E->Params [E->ParamCount] = T; } else { Last->Next = T; } Last = T; /* And skip it... */ NextTok (); } while (CurTok.Tok != Term && !TokIsSep (CurTok.Tok)); /* One parameter more */ ++E->ParamCount; /* If the macro argument was enclosed in curly braces, end-of-line * is an error. Skip the closing curly brace. */ if (Term == TOK_RCURLY) { if (TokIsSep (CurTok.Tok)) { Error ("End of line encountered within macro argument"); break; } NextTok (); } /* Check for a comma */ if (Count > 0) { if (CurTok.Tok == TOK_COMMA) { NextTok (); } else { Error ("`,' expected"); } } } /* Macro expansion will overwrite the current token. This is a problem * for define style macros since these are called from the scanner level. * To avoid it, remember the current token and re-insert it, once macro * expansion is done. */ E->Final = NewTokNode (); /* Insert a new token input function */ PushInput (MacExpand, E, ".DEFINE"); }
static void StartExpClassic (MacExp* E) /* Start expanding a classic macro */ { token_t Term; /* Skip the macro name */ NextTok (); /* Read the actual parameters */ while (!TokIsSep (CurTok.Tok)) { TokNode* Last; /* Check for maximum parameter count */ if (E->ParamCount >= E->M->ParamCount) { ErrorSkip ("Too many macro parameters"); break; } /* The macro may optionally be enclosed in curly braces */ Term = GetTokListTerm (TOK_COMMA); /* Read tokens for one parameter, accept empty params */ Last = 0; while (CurTok.Tok != Term && CurTok.Tok != TOK_SEP) { TokNode* T; /* Check for end of file */ if (CurTok.Tok == TOK_EOF) { Error ("Unexpected end of file"); FreeMacExp (E); return; } /* Get the next token in a node */ T = NewTokNode (); /* Insert it into the list */ if (Last == 0) { E->Params [E->ParamCount] = T; } else { Last->Next = T; } Last = T; /* And skip it... */ NextTok (); } /* One parameter more */ ++E->ParamCount; /* If the macro argument was enclosed in curly braces, end-of-line * is an error. Skip the closing curly brace. */ if (Term == TOK_RCURLY) { if (CurTok.Tok == TOK_SEP) { Error ("End of line encountered within macro argument"); break; } NextTok (); } /* Check for a comma */ if (CurTok.Tok == TOK_COMMA) { NextTok (); } else { break; } } /* We must be at end of line now, otherwise something is wrong */ ExpectSep (); /* Insert a new token input function */ PushInput (MacExpand, E, ".MACRO"); }