Example #1
0
ExprNode* ReadExpr (FILE* F, ObjData* O)
/* Read an expression from the given file */
{
    ExprNode* Expr;

    /* Read the node tag and handle NULL nodes */
    unsigned char Op = Read8 (F);
    if (Op == EXPR_NULL) {
        return 0;
    }

    /* Create a new node */
    Expr = NewExprNode (O, Op);

    /* Check the tag and handle the different expression types */
    if (EXPR_IS_LEAF (Op)) {
        switch (Op) {

            case EXPR_LITERAL:
                Expr->V.IVal = Read32Signed (F);
                break;

            case EXPR_SYMBOL:
                /* Read the import number */
                Expr->V.ImpNum = ReadVar (F);
                break;

            case EXPR_SECTION:
                /* Read the section number */
                Expr->V.SecNum = ReadVar (F);
                break;

            default:
                Error ("Invalid expression op: %02X", Op);

        }

    } else {

        /* Not a leaf node */
        Expr->Left = ReadExpr (F, O);
        Expr->Right = ReadExpr (F, O);

    }

    /* Return the tree */
    return Expr;
}
Example #2
0
static void SkipExpr (FILE* F)
/* Skip an expression from the given file */
{
    /* Read the node tag and handle NULL nodes */
    unsigned char Op = Read8 (F);
    if (Op == EXPR_NULL) {
     	return;
    }

    /* Check the tag and handle the different expression types */
    if (EXPR_IS_LEAF (Op)) {
	switch (Op) {

	    case EXPR_LITERAL:
	   	(void) Read32Signed (F);
	   	break;

	    case EXPR_SYMBOL:
	   	/* Read the import number */
	   	(void) ReadVar (F);
	   	break;

	    case EXPR_SECTION:
            case EXPR_BANK:
	   	/* Read the segment number */
	       	(void) ReadVar (F);
    	   	break;

	    default:
	   	Error ("Invalid expression op: %02X", Op);

	}

    } else {

    	/* Not a leaf node */
       	SkipExpr (F);
	SkipExpr (F);
    }
}
Example #3
0
int IsConstExpr (ExprNode* Root)
/* Return true if the given expression is a constant expression, that is, one
 * with no references to external symbols.
 */
{
    int         Const;
    Export*     E;
    Section*    S;
    MemoryArea* M;

    if (EXPR_IS_LEAF (Root->Op)) {
        switch (Root->Op) {

            case EXPR_LITERAL:
                return 1;

            case EXPR_SYMBOL:
                /* Get the referenced export */
                E = GetExprExport (Root);
                /* If this export has a mark set, we've already encountered it.
                 * This means that the export is used to define it's own value,
                 * which in turn means, that we have a circular reference.
                 */
                if (ExportHasMark (E)) {
                    CircularRefError (E);
                    Const = 0;
                } else {
                    MarkExport (E);
                    Const = IsConstExport (E);
                    UnmarkExport (E);
                }
                return Const;

            case EXPR_SECTION:
                /* A section expression is const if the segment it is in is
                 * not relocatable and already placed.
                 */
                S = GetExprSection (Root);
                M = S->Seg->MemArea;
                return M != 0 && (M->Flags & MF_PLACED) != 0 && !M->Relocatable;

            case EXPR_SEGMENT:
                /* A segment is const if it is not relocatable and placed */
                M = Root->V.Seg->MemArea;
                return M != 0 && (M->Flags & MF_PLACED) != 0 && !M->Relocatable;

            case EXPR_MEMAREA:
                /* A memory area is const if it is not relocatable and placed */
                return !Root->V.Mem->Relocatable &&
                       (Root->V.Mem->Flags & MF_PLACED);

            default:
                /* Anything else is not const */
                return 0;

        }

    } else if (EXPR_IS_UNARY (Root->Op)) {

        SegExprDesc D;

        /* Special handling for the BANK pseudo function */
        switch (Root->Op) {

            case EXPR_BANK:
                /* Get segment references for the expression */
                GetSegExprVal (Root->Left, &D);

                /* The expression is const if the expression contains exactly
                 * one segment that is assigned to a memory area which has a
                 * bank attribute that is constant.
                 */
                return (D.TooComplex              == 0  &&
                        D.Seg                     != 0  &&
                        D.Seg->MemArea            != 0  &&
                        D.Seg->MemArea->BankExpr  != 0  &&
                        IsConstExpr (D.Seg->MemArea->BankExpr));

            default:
                /* All others handled normal */
                return IsConstExpr (Root->Left);

        }

    } else {

        /* We must handle shortcut boolean expressions here */
        switch (Root->Op) {

            case EXPR_BOOLAND:
                if (IsConstExpr (Root->Left)) {
                    /* lhs is const, if it is zero, don't eval right */
                    if (GetExprVal (Root->Left) == 0) {
                        return 1;
                    } else {
                        return IsConstExpr (Root->Right);
                    }
                } else {
                    /* lhs not const --> tree not const */
                    return 0;
                }
                break;

            case EXPR_BOOLOR:
                if (IsConstExpr (Root->Left)) {
                    /* lhs is const, if it is not zero, don't eval right */
                    if (GetExprVal (Root->Left) != 0) {
                        return 1;
                    } else {
                        return IsConstExpr (Root->Right);
                    }
                } else {
                    /* lhs not const --> tree not const */
                    return 0;
                }
                break;

            default:
                /* All others are handled normal */
                return IsConstExpr (Root->Left) && IsConstExpr (Root->Right);
        }
    }
}