+ExprNode* FinalizeExpr (ExprNode* Expr, const Collection* LineInfos)
+/* Finalize an expression tree before it is written to the file. This will
+ * replace EXPR_BANKRAW nodes by EXPR_BANK nodes, and replace constant
+ * expressions by their result. The LineInfos are used when diagnosing errors.
+ * Beware: The expression tree may get replaced in future versions, so don't
+ * use Expr after calling this function.
+ */
+{
+ ExprDesc ED;
+
+ /* Check the type code */
+ switch (EXPR_NODETYPE (Expr->Op)) {
+
+ case EXPR_LEAFNODE:
+ /* Nothing to do for leaf nodes */
+ break;
+
+ case EXPR_BINARYNODE:
+ Expr->Left = FinalizeExpr (Expr->Left, LineInfos);
+ Expr->Right = FinalizeExpr (Expr->Right, LineInfos);
+ /* FALLTHROUGH */
+
+ case EXPR_UNARYNODE:
+ Expr->Left = FinalizeExpr (Expr->Left, LineInfos);
+
+ /* Special handling for BANKRAW */
+ if (Expr->Op == EXPR_BANKRAW) {
+
+ /* Study the expression */
+ ED_Init (&ED);
+ StudyExpr (Expr->Left, &ED);
+
+ /* The expression must be ok and must have exactly one segment
+ * reference.
+ */
+ if (ED.Flags & ED_TOO_COMPLEX) {
+ LIError (LineInfos,
+ "Cannot evaluate expression");
+ } else if (ED.SecCount == 0) {
+ LIError (LineInfos,
+ ".BANK expects a segment reference");
+ } else if (ED.SecCount > 1 || ED.SecRef[0].Count > 1) {
+ LIError (LineInfos,
+ "Too many segment references in argument to .BANK");
+ } else {
+ FreeExpr (Expr->Left);
+ Expr->Op = EXPR_BANK;
+ Expr->Left = 0;
+ Expr->V.SecNum = ED.SecRef[0].Ref;
+ }
+
+ /* Cleanup */
+ ED_Done (&ED);
+
+ }
+ break;
+ }
+
+ /* Return the (partial) tree */
+ return Expr;
+}
+
+
+