Beispiel #1
0
void XmdsExprSetDefaultNid(Widget w,int nid)
{
  XmdsExprWidget ew = (XmdsExprWidget) w;
  if (nid != ew->expr.default_nid)
  {
    ew->expr.default_nid = nid;
    LoadExpr(ew,(struct descriptor *) ew->expr.xd);
    Resize((Widget) ew);
  }
}
Beispiel #2
0
void XmdsExprReset(Widget w)
{
  XmdsExprWidget ew = (XmdsExprWidget) w;
  if (ew->expr.nid)
    XmdsExprSetNid(w,ew->expr.nid,ew->expr.nid_offset);
  else
  {
    LoadExpr(ew,(struct descriptor *) ew->expr.xd);
    Resize((Widget) ew);
  }
}
Beispiel #3
0
unsigned Test (unsigned Label, int Invert)
/* Evaluate a boolean test expression and jump depending on the result of
** the test and on Invert. The function returns one of the TESTEXPR_xx codes
** defined above. If the jump is always true, a warning is output.
*/
{
    ExprDesc Expr;
    unsigned Result;

    /* Read a boolean expression */
    BoolExpr (hie0, &Expr);

    /* Check for a constant expression */
    if (ED_IsConstAbs (&Expr)) {

        /* Result is constant, so we know the outcome */
        Result = (Expr.IVal != 0);

        /* Constant rvalue */
        if (!Invert && Expr.IVal == 0) {
            g_jump (Label);
            Warning ("Unreachable code");
        } else if (Invert && Expr.IVal != 0) {
            g_jump (Label);
        }

    } else {

        /* Result is unknown */
        Result = TESTEXPR_UNKNOWN;

        /* If the expr hasn't set condition codes, set the force-test flag */
        if (!ED_IsTested (&Expr)) {
            ED_MarkForTest (&Expr);
        }

        /* Load the value into the primary register */
        LoadExpr (CF_FORCECHAR, &Expr);

        /* Generate the jump */
        if (Invert) {
            g_truejump (CF_NONE, Label);
        } else {
            g_falsejump (CF_NONE, Label);
        }
    }

    /* Return the result */
    return Result;
}
Beispiel #4
0
void XmdsExprSetXd(Widget w,struct descriptor *dsc)
{
  XmdsExprWidget ew = (XmdsExprWidget) w;
  if (ew->expr.xd)
    MdsFree1Dx(ew->expr.xd, 0);
  else
  {
    ew->expr.xd = (struct descriptor_xd *) XtMalloc(sizeof(struct descriptor_xd));
    *ew->expr.xd = empty_xd;
  }
  MdsCopyDxXd(dsc,ew->expr.xd);
  LoadExpr(ew,(struct descriptor *) ew->expr.xd);
  Resize((Widget) ew);
}
Beispiel #5
0
void XmdsExprSetNid(Widget w,int nid,int offset)
{
  XmdsExprWidget ew = (XmdsExprWidget) w;
  int new_nid;
  int status;
  if (ew->expr.xd)
    MdsFree1Dx(ew->expr.xd, 0);
  else
  {
    ew->expr.xd = (struct descriptor_xd *) XtMalloc(sizeof(struct descriptor_xd));
    *ew->expr.xd = empty_xd;
  }
  if (nid == -1)
    ew->expr.nid = XmdsGetDeviceNid();

  new_nid = ew->expr.nid + offset;
  status = TreeGetRecord(new_nid,ew->expr.xd);
  if (status & 1)
    LoadExpr(ew,(struct descriptor *) ew->expr.xd);
  else
    LoadExpr(ew,0);
  Resize((Widget) ew);
  ew->expr.nid_offset = offset;
}
Beispiel #6
0
static void ParseArg (ArgDesc* Arg, Type* Type)
/* Parse one argument but do not push it onto the stack. Make all fields in
 * Arg valid.
 */
{
    /* We have a prototype, so chars may be pushed as chars */
    Arg->Flags = CF_FORCECHAR;

    /* Remember the required argument type */
    Arg->ArgType = Type;

    /* Read the expression we're going to pass to the function */
    MarkedExprWithCheck (hie1, &Arg->Expr);

    /* Remember the actual argument type */
    Arg->Type = Arg->Expr.Type;

    /* Convert this expression to the expected type */
    TypeConversion (&Arg->Expr, Type);

    /* Remember the following code position */
    GetCodePos (&Arg->Load);

    /* If the value is a constant, set the flag, otherwise load it into the
     * primary register.
     */
    if (ED_IsConstAbsInt (&Arg->Expr) && ED_CodeRangeIsEmpty (&Arg->Expr)) {
        /* Remember that we have a constant value */
        Arg->Flags |= CF_CONST;
    } else {
        /* Load into the primary */
        LoadExpr (CF_NONE, &Arg->Expr);
    }

    /* Remember the following code position */
    GetCodePos (&Arg->Push);
    GetCodePos (&Arg->End);

    /* Use the type of the argument for the push */
    Arg->Flags |= TypeOf (Arg->Expr.Type);
}
Beispiel #7
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));
}
Beispiel #8
0
int Statement (int* PendingToken)
/* Statement parser. Returns 1 if the statement does a return/break, returns
** 0 otherwise. If the PendingToken pointer is not NULL, the function will
** not skip the terminating token of the statement (closing brace or
** semicolon), but store true if there is a pending token, and false if there
** is none. The token is always checked, so there is no need for the caller to
** check this token, it must be skipped, however. If the argument pointer is
** NULL, the function will skip the token.
*/
{
    ExprDesc Expr;
    int GotBreak;
    CodeMark Start, End;

    /* Assume no pending token */
    if (PendingToken) {
        *PendingToken = 0;
    }

    /* Check for a label. A label is always part of a statement, it does not
    ** replace one.
    */
    while (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) {
        /* Handle the label */
        DoLabel ();
        if (CheckLabelWithoutStatement ()) {
            return 0;
        }
    }

    switch (CurTok.Tok) {

        case TOK_LCURLY:
            NextToken ();
            GotBreak = CompoundStatement ();
            CheckTok (TOK_RCURLY, "`{' expected", PendingToken);
            return GotBreak;

        case TOK_IF:
            return IfStatement ();

        case TOK_WHILE:
            WhileStatement ();
            break;

        case TOK_DO:
            DoStatement ();
            break;

        case TOK_SWITCH:
            SwitchStatement ();
            break;

        case TOK_RETURN:
            ReturnStatement ();
            CheckSemi (PendingToken);
            return 1;

        case TOK_BREAK:
            BreakStatement ();
            CheckSemi (PendingToken);
            return 1;

        case TOK_CONTINUE:
            ContinueStatement ();
            CheckSemi (PendingToken);
            return 1;

        case TOK_FOR:
            ForStatement ();
            break;

        case TOK_GOTO:
            GotoStatement ();
            CheckSemi (PendingToken);
            return 1;

        case TOK_SEMI:
            /* Ignore it */
            CheckSemi (PendingToken);
            break;

        case TOK_PRAGMA:
            DoPragma ();
            break;

        case TOK_CASE:
            CaseLabel ();
            CheckLabelWithoutStatement ();
            break;

        case TOK_DEFAULT:
            DefaultLabel ();
            CheckLabelWithoutStatement ();
            break;

        default:
            /* Remember the current code position */
            GetCodePos (&Start);
            /* Actual statement */
            ExprWithCheck (hie0, &Expr);
            /* Load the result only if it is an lvalue and the type is
            ** marked as volatile. Otherwise the load is useless.
            */
            if (ED_IsLVal (&Expr) && IsQualVolatile (Expr.Type)) {
                LoadExpr (CF_NONE, &Expr);
            }
            /* If the statement didn't generate code, and is not of type
            ** void, emit a warning.
            */
            GetCodePos (&End);
            if (CodeRangeIsEmpty (&Start, &End) &&
                !IsTypeVoid (Expr.Type)         &&
                IS_Get (&WarnNoEffect)) {
                Warning ("Statement has no effect");
            }
            CheckSemi (PendingToken);
    }
    return 0;
}
Beispiel #9
0
static void DoConversion (ExprDesc* Expr, const Type* NewType)
/* Emit code to convert the given expression to a new type. */
{
    Type*    OldType;
    unsigned OldSize;
    unsigned NewSize;


    /* Remember the old type */
    OldType = Expr->Type;

    /* If we're converting to void, we're done. Note: This does also cover a
     * conversion void -> void.
     */
    if (IsTypeVoid (NewType)) {
        ED_MakeRVal (Expr);     /* Never an lvalue */
        goto ExitPoint;
    }

    /* Don't allow casts from void to something else. */
    if (IsTypeVoid (OldType)) {
        Error ("Cannot convert from `void' to something else");
        goto ExitPoint;
    }

    /* Get the sizes of the types. Since we've excluded void types, checking
     * for known sizes makes sense here.
     */
    OldSize = CheckedSizeOf (OldType);
    NewSize = CheckedSizeOf (NewType);

    /* lvalue? */
    if (ED_IsLVal (Expr)) {

        /* We have an lvalue. If the new size is smaller than the new one,
         * we don't need to do anything. The compiler will generate code
         * to load only the portion of the value that is actually needed.
         * This works only on a little endian architecture, but that's
         * what we support.
         * If both sizes are equal, do also leave the value alone.
         * If the new size is larger, we must convert the value.
         */
        if (NewSize > OldSize) {
            /* Load the value into the primary */
            LoadExpr (CF_NONE, Expr);

            /* Emit typecast code */
            g_typecast (TypeOf (NewType), TypeOf (OldType) | CF_FORCECHAR);

            /* Value is now in primary and an rvalue */
            ED_MakeRValExpr (Expr);
        }

    } else if (ED_IsLocAbs (Expr)) {

        /* A cast of a constant numeric value to another type. Be sure
         * to handle sign extension correctly.
         */

        /* Get the current and new size of the value */
        unsigned OldBits = OldSize * 8;
        unsigned NewBits = NewSize * 8;

        /* Check if the new datatype will have a smaller range. If it
         * has a larger range, things are ok, since the value is
         * internally already represented by a long.
         */
        if (NewBits <= OldBits) {

            /* Cut the value to the new size */
            Expr->IVal &= (0xFFFFFFFFUL >> (32 - NewBits));

            /* If the new type is signed, sign extend the value */
            if (IsSignSigned (NewType)) {
                if (Expr->IVal & (0x01UL << (NewBits-1))) {
                    /* Beware: Use the safe shift routine here. */
                    Expr->IVal |= shl_l (~0UL, NewBits);
                }
            }
        }

    } else {
Beispiel #10
0
 ObjectExpression_BranchIf(ObjectLoad &arc) : Super(arc), exprC(LoadExpr(arc)) {}