Exemplo n.º 1
0
static void ReturnStatement (void)
/* Handle the 'return' statement */
{
    ExprDesc Expr;

    NextToken ();
    if (CurTok.Tok != TOK_SEMI) {

        /* Evaluate the return expression */
        hie0 (&Expr);

        /* If we return something in a void function, print an error and
        ** ignore the value. Otherwise convert the value to the type of the
        ** return.
        */
        if (F_HasVoidReturn (CurrentFunc)) {
            Error ("Returning a value in function with return type void");
        } else {
            /* Convert the return value to the type of the function result */
            TypeConversion (&Expr, F_GetReturnType (CurrentFunc));

            /* Load the value into the primary */
            LoadExpr (CF_NONE, &Expr);
        }

    } else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) {
        Error ("Function `%s' must return a value", F_GetFuncName (CurrentFunc));
    }

    /* Mark the function as having a return statement */
    F_ReturnFound (CurrentFunc);

    /* Cleanup the stack in case we're inside a block with locals */
    g_space (StackPtr - F_GetTopLevelSP (CurrentFunc));

    /* Output a jump to the function exit code */
    g_jump (F_GetRetLab (CurrentFunc));
}
Exemplo n.º 2
0
void NextToken (void)
/* Get next token from input stream */
{
    ident token;

    /* We have to skip white space here before shifting tokens, since the
    ** tokens and the current line info is invalid at startup and will get
    ** initialized by reading the first time from the file. Remember if
    ** we were at end of input and handle that later.
    */
    int GotEOF = (SkipWhite() == 0);

    /* Current token is the lookahead token */
    if (CurTok.LI) {
        ReleaseLineInfo (CurTok.LI);
    }
    CurTok = NextTok;

    /* When reading the first time from the file, the line info in NextTok,
    ** which was copied to CurTok is invalid. Since the information from
    ** the token is used for error messages, we must make it valid.
    */
    if (CurTok.LI == 0) {
        CurTok.LI = UseLineInfo (GetCurLineInfo ());
    }

    /* Remember the starting position of the next token */
    NextTok.LI = UseLineInfo (GetCurLineInfo ());

    /* Now handle end of input. */
    if (GotEOF) {
        /* End of file reached */
        NextTok.Tok = TOK_CEOF;
        return;
    }

    /* Determine the next token from the lookahead */
    if (IsDigit (CurC) || (CurC == '.' && IsDigit (NextC))) {
        /* A number */
        NumericConst ();
        return;
    }

    /* Check for wide character literals */
    if (CurC == 'L' && NextC == '\"') {
        StringConst ();
        return;
    }

    /* Check for keywords and identifiers */
    if (IsSym (token)) {

        /* Check for a keyword */
        if ((NextTok.Tok = FindKey (token)) != TOK_IDENT) {
            /* Reserved word found */
            return;
        }
        /* No reserved word, check for special symbols */
        if (token[0] == '_' && token[1] == '_') {
            /* Special symbols */
            if (strcmp (token+2, "FILE__") == 0) {
                NextTok.SVal = AddLiteral (GetCurrentFile());
                NextTok.Tok  = TOK_SCONST;
                return;
            } else if (strcmp (token+2, "LINE__") == 0) {
                NextTok.Tok  = TOK_ICONST;
                NextTok.IVal = GetCurrentLine();
                NextTok.Type = type_int;
                return;
            } else if (strcmp (token+2, "func__") == 0) {
                /* __func__ is only defined in functions */
                if (CurrentFunc) {
                    NextTok.SVal = AddLiteral (F_GetFuncName (CurrentFunc));
                    NextTok.Tok  = TOK_SCONST;
                    return;
                }
            }
        }

        /* No reserved word but identifier */
        strcpy (NextTok.Ident, token);
        NextTok.Tok = TOK_IDENT;
        return;
    }

    /* Monstrous switch statement ahead... */
    switch (CurC) {

        case '!':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_NE);
            } else {
                NextTok.Tok = TOK_BOOL_NOT;
            }
            break;

        case '\"':
            StringConst ();
            break;

        case '%':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_MOD_ASSIGN);
            } else {
                NextTok.Tok = TOK_MOD;
            }
            break;

        case '&':
            NextChar ();
            switch (CurC) {
                case '&':
                    SetTok (TOK_BOOL_AND);
                    break;
                case '=':
                    SetTok (TOK_AND_ASSIGN);
                    break;
                default:
                    NextTok.Tok = TOK_AND;
            }
            break;

        case '\'':
            CharConst ();
            break;

        case '(':
            SetTok (TOK_LPAREN);
            break;

        case ')':
            SetTok (TOK_RPAREN);
            break;

        case '*':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_MUL_ASSIGN);
            } else {
                NextTok.Tok = TOK_STAR;
            }
            break;

        case '+':
            NextChar ();
            switch (CurC) {
                case '+':
                    SetTok (TOK_INC);
                    break;
                case '=':
                    SetTok (TOK_PLUS_ASSIGN);
                    break;
                default:
                    NextTok.Tok = TOK_PLUS;
            }
            break;

        case ',':
            SetTok (TOK_COMMA);
            break;

        case '-':
            NextChar ();
            switch (CurC) {
                case '-':
                    SetTok (TOK_DEC);
                    break;
                case '=':
                    SetTok (TOK_MINUS_ASSIGN);
                    break;
                case '>':
                    SetTok (TOK_PTR_REF);
                    break;
                default:
                    NextTok.Tok = TOK_MINUS;
            }
            break;

        case '.':
            NextChar ();
            if (CurC == '.') {
                NextChar ();
                if (CurC == '.') {
                    SetTok (TOK_ELLIPSIS);
                } else {
                    UnknownChar (CurC);
                }
            } else {
                NextTok.Tok = TOK_DOT;
            }
            break;

        case '/':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_DIV_ASSIGN);
            } else {
                NextTok.Tok = TOK_DIV;
            }
            break;

        case ':':
            SetTok (TOK_COLON);
            break;

        case ';':
            SetTok (TOK_SEMI);
            break;

        case '<':
            NextChar ();
            switch (CurC) {
                case '=':
                    SetTok (TOK_LE);
                    break;
                case '<':
                    NextChar ();
                    if (CurC == '=') {
                        SetTok (TOK_SHL_ASSIGN);
                    } else {
                        NextTok.Tok = TOK_SHL;
                    }
                    break;
                default:
                    NextTok.Tok = TOK_LT;
            }
            break;

        case '=':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_EQ);
            } else {
                NextTok.Tok = TOK_ASSIGN;
            }
            break;

        case '>':
            NextChar ();
            switch (CurC) {
                case '=':
                    SetTok (TOK_GE);
                    break;
                case '>':
                    NextChar ();
                    if (CurC == '=') {
                        SetTok (TOK_SHR_ASSIGN);
                    } else {
                        NextTok.Tok = TOK_SHR;
                    }
                    break;
                default:
                    NextTok.Tok = TOK_GT;
            }
            break;

        case '?':
            SetTok (TOK_QUEST);
            break;

        case '[':
            SetTok (TOK_LBRACK);
            break;

        case ']':
            SetTok (TOK_RBRACK);
            break;

        case '^':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_XOR_ASSIGN);
            } else {
                NextTok.Tok = TOK_XOR;
            }
            break;

        case '{':
            SetTok (TOK_LCURLY);
            break;

        case '|':
            NextChar ();
            switch (CurC) {
                case '|':
                    SetTok (TOK_BOOL_OR);
                    break;
                case '=':
                    SetTok (TOK_OR_ASSIGN);
                    break;
                default:
                    NextTok.Tok = TOK_OR;
            }
            break;

        case '}':
            SetTok (TOK_RCURLY);
            break;

        case '~':
            SetTok (TOK_COMP);
            break;

        default:
            UnknownChar (CurC);

    }

}