Пример #1
0
static void FuncRight (void)
/* Handle the .RIGHT function */
{
    long        Count;
    TokList*    List;

    /* Skip it */
    NextTok ();

    /* Left paren expected */
    ConsumeLParen ();

    /* Count argument. Correct negative counts to zero. */
    Count = ConstExpression ();
    if (Count < 0) {
        Count = 0;
    }
    ConsumeComma ();

    /* Read the complete token list */
    List = CollectTokens (0, 9999);

    /* Delete tokens from the list until Count tokens are remaining */
    while (List->Count > (unsigned) Count) {
        /* Get the first node */
        TokNode* T = List->Root;

        /* Remove it from the list */
        List->Root = List->Root->Next;

        /* Free the node */
        FreeTokNode (T);

        /* Corrent the token counter */
        List->Count--;
    }

    /* Since we want to insert the list before the now current token, we have
     * to save the current token in some way and then skip it. To do this, we
     * will add the current token at the end of the token list (so the list
     * will never be empty), push the token list, and then skip the current
     * token. This will replace the current token by the first token from the
     * list (which will be the old current token in case the list was empty).
     */
    AddCurTok (List);

    /* Insert it into the scanner feed */
    PushTokList (List, ".RIGHT");

    /* Skip the current token */
    NextTok ();
}
Пример #2
0
static void FuncMid (void)
/* Handle the .MID function */
{
    long        Start;
    long        Count;
    TokList*    List;

    /* Skip it */
    NextTok ();

    /* Left paren expected */
    ConsumeLParen ();

    /* Start argument. Since the start argument can get negative with
     * expressions like ".tcount(arg)-2", we correct it to zero silently.
     */
    Start = ConstExpression ();
    if (Start < 0 || Start > 100) {
        Start = 0;
    }
    ConsumeComma ();

    /* Count argument. Similar as above, we will accept negative counts and
     * correct them to zero silently.
     */
    Count = ConstExpression ();
    if (Count < 0) {
        Count = 0;
    }
    ConsumeComma ();

    /* Read the token list */
    List = CollectTokens ((unsigned) Start, (unsigned) Count);

    /* Since we want to insert the list before the now current token, we have
     * to save the current token in some way and then skip it. To do this, we
     * will add the current token at the end of the token list (so the list
     * will never be empty), push the token list, and then skip the current
     * token. This will replace the current token by the first token from the
     * list (which will be the old current token in case the list was empty).
     */
    AddCurTok (List);

    /* Insert it into the scanner feed */
    PushTokList (List, ".MID");

    /* Skip the current token */
    NextTok ();
}
Пример #3
0
static TokList* CollectRepeatTokens (void)
/* Collect all tokens inside the .REPEAT body in a token list and return
 * this list. In case of errors, NULL is returned.
 */
{
    /* Create the token list */
    TokList* List = NewTokList ();

    /* Read the token list */
    unsigned Repeats = 0;
    while (Repeats != 0 || Tok != TOK_ENDREP) {

     	/* Check for end of input */
       	if (Tok == TOK_EOF) {
     	    Error ("Unexpected end of file");
	    FreeTokList (List);
     	    return 0;
     	}

	/* If we find a token that is equal to the repeat counter name,
	 * replace it by a REPCOUNTER token. This way we have to do strcmps
	 * only once for each identifier, and not for each expansion.
	 * Note: This will fail for nested repeats using the same repeat
	 * counter name, but
	 */



       	/* Collect all tokens in the list */
	AddCurTok (List);

     	/* Check for and count nested .REPEATs */
     	if (Tok == TOK_REPEAT) {
     	    ++Repeats;
     	} else if (Tok == TOK_ENDREP) {
     	    --Repeats;
     	}

       	/* Get the next token */
     	NextTok ();
    }

    /* Eat the closing .ENDREP */
    NextTok ();

    /* Return the list of collected tokens */
    return List;
}
Пример #4
0
static TokList* CollectTokens (unsigned Start, unsigned Count)
/* Read a list of tokens that is optionally enclosed in curly braces and
 * terminated by a right paren. For all tokens starting at the one with index
 * Start, and ending at (Start+Count-1), place them into a token list, and
 * return this token list.
 */
{

    /* Create the token list */
    TokList* List = NewTokList ();

    /* Determine if the list is enclosed in curly braces. */
    token_t Term = GetTokListTerm (TOK_RPAREN);

    /* Read the token list */
    unsigned Current = 0;
    while (CurTok.Tok != Term) {

        /* Check for end of line or end of input */
        if (TokIsSep (CurTok.Tok)) {
            Error ("Unexpected end of line");
            return List;
        }

        /* Collect tokens in the given range */
        if (Current >= Start && Current < Start+Count) {
            /* Add the current token to the list */
            AddCurTok (List);
        }

        /* Get the next token */
        ++Current;
        NextTok ();
    }

    /* Eat the terminator token */
    NextTok ();

    /* If the list was enclosed in curly braces, we do expect now a right paren */
    if (Term == TOK_RCURLY) {
        ConsumeRParen ();
    }

    /* Return the list of collected tokens */
    return List;
}
Пример #5
0
static TokList* CollectRepeatTokens (void)
/* Collect all tokens inside the .REPEAT body in a token list and return
 * this list. In case of errors, NULL is returned.
 */
{
    /* Create the token list */
    TokList* List = NewTokList ();

    /* Read the token list */
    unsigned Repeats = 0;
    while (Repeats != 0 || CurTok.Tok != TOK_ENDREP) {

        /* Check for end of input */
        if (CurTok.Tok == TOK_EOF) {
            Error ("Unexpected end of file");
            FreeTokList (List);
            return 0;
        }

        /* Collect all tokens in the list */
        AddCurTok (List);

        /* Check for and count nested .REPEATs */
        if (CurTok.Tok == TOK_REPEAT) {
            ++Repeats;
        } else if (CurTok.Tok == TOK_ENDREP) {
            --Repeats;
        }

        /* Get the next token */
        NextTok ();
    }

    /* Eat the closing .ENDREP */
    NextTok ();

    /* Return the list of collected tokens */
    return List;
}
Пример #6
0
static void FuncLeft (void)
/* Handle the .LEFT function */
{
    long        Count;
    TokList*    List;

    /* Skip it */
    NextTok ();

    /* Left paren expected */
    ConsumeLParen ();

    /* Count argument. Correct negative counts to zero. */
    Count = ConstExpression ();
    if (Count < 0) {
        Count = 0;
    }
    ConsumeComma ();

    /* Read the token list */
    List = CollectTokens (0, (unsigned) Count);

    /* Since we want to insert the list before the now current token, we have
     * to save the current token in some way and then skip it. To do this, we
     * will add the current token at the end of the token list (so the list
     * will never be empty), push the token list, and then skip the current
     * token. This will replace the current token by the first token from the
     * list (which will be the old current token in case the list was empty).
     */
    AddCurTok (List);

    /* Insert it into the scanner feed */
    PushTokList (List, ".LEFT");

    /* Skip the current token */
    NextTok ();
}