mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Handle subtractions between labels
This commit is contained in:
@@ -274,6 +274,28 @@ static int32_t shift(int32_t shiftee, int32_t amount)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct sSymbol const *symbolOf(struct Expression const *expr)
|
||||||
|
{
|
||||||
|
/* If an expression starts with a symbol ref... */
|
||||||
|
if (!expr->tRPN || expr->tRPN[0] != RPN_SYM || expr->nRPNPatchSize != 5)
|
||||||
|
return NULL;
|
||||||
|
return sym_FindSymbol((char *)expr->tRPN + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isDiffConstant(struct Expression const *src1,
|
||||||
|
struct Expression const *src2)
|
||||||
|
{
|
||||||
|
/* Check if both expressions only refer to a single symbol */
|
||||||
|
struct sSymbol const *symbol1 = symbolOf(src1);
|
||||||
|
struct sSymbol const *symbol2 = symbolOf(src2);
|
||||||
|
|
||||||
|
if (!symbol1 || !symbol2
|
||||||
|
|| symbol1->type != SYM_LABEL || symbol2->type != SYM_LABEL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return symbol1->pSection == symbol2->pSection;
|
||||||
|
}
|
||||||
|
|
||||||
void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
||||||
const struct Expression *src1, const struct Expression *src2)
|
const struct Expression *src1, const struct Expression *src2)
|
||||||
{
|
{
|
||||||
@@ -383,8 +405,12 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
|||||||
fatalerror("%d is no binary operator", op);
|
fatalerror("%d is no binary operator", op);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: under some conditions, the expression will still be known */
|
} else if (op == RPN_SUB && isDiffConstant(src1, src2)) {
|
||||||
|
struct sSymbol const *symbol1 = symbolOf(src1);
|
||||||
|
struct sSymbol const *symbol2 = symbolOf(src2);
|
||||||
|
|
||||||
|
expr->nVal = symbol1->nValue - symbol2->nValue;
|
||||||
|
expr->isKnown = true;
|
||||||
} else {
|
} else {
|
||||||
/* If it's not known, start computing the RPN expression */
|
/* If it's not known, start computing the RPN expression */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user