mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Merge pull request #490 from ISSOtm/const
Implement `ISCONST`, reporting compile-time constness
This commit is contained in:
@@ -54,6 +54,7 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
|||||||
const struct Expression *src2);
|
const struct Expression *src2);
|
||||||
void rpn_HIGH(struct Expression *expr, const struct Expression *src);
|
void rpn_HIGH(struct Expression *expr, const struct Expression *src);
|
||||||
void rpn_LOW(struct Expression *expr, const struct Expression *src);
|
void rpn_LOW(struct Expression *expr, const struct Expression *src);
|
||||||
|
void rpn_ISCONST(struct Expression *expr, const struct Expression *src);
|
||||||
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
|
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
|
||||||
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
|
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
|
||||||
void rpn_BankSymbol(struct Expression *expr, char const *tzSym);
|
void rpn_BankSymbol(struct Expression *expr, char const *tzSym);
|
||||||
|
|||||||
@@ -543,6 +543,7 @@ static void strsubUTF8(char *dest, const char *src, uint32_t pos, uint32_t len)
|
|||||||
%left T_OP_FLOOR
|
%left T_OP_FLOOR
|
||||||
|
|
||||||
%token T_OP_HIGH T_OP_LOW
|
%token T_OP_HIGH T_OP_LOW
|
||||||
|
%token T_OP_ISCONST
|
||||||
|
|
||||||
%left T_OP_STRCMP
|
%left T_OP_STRCMP
|
||||||
%left T_OP_STRIN
|
%left T_OP_STRIN
|
||||||
@@ -1301,6 +1302,7 @@ relocexpr_no_str : scoped_id { rpn_Symbol(&$$, $1); }
|
|||||||
| T_OP_NOT relocexpr %prec NEG { rpn_UNNOT(&$$, &$2); }
|
| T_OP_NOT relocexpr %prec NEG { rpn_UNNOT(&$$, &$2); }
|
||||||
| T_OP_HIGH '(' relocexpr ')' { rpn_HIGH(&$$, &$3); }
|
| T_OP_HIGH '(' relocexpr ')' { rpn_HIGH(&$$, &$3); }
|
||||||
| T_OP_LOW '(' relocexpr ')' { rpn_LOW(&$$, &$3); }
|
| T_OP_LOW '(' relocexpr ')' { rpn_LOW(&$$, &$3); }
|
||||||
|
| T_OP_ISCONST '(' relocexpr ')'{ rpn_ISCONST(&$$, &$3); }
|
||||||
| T_OP_BANK '(' scoped_id ')' {
|
| T_OP_BANK '(' scoped_id ')' {
|
||||||
/* '@' is also a T_ID, it is handled here. */
|
/* '@' is also a T_ID, it is handled here. */
|
||||||
rpn_BankSymbol(&$$, $3);
|
rpn_BankSymbol(&$$, $3);
|
||||||
|
|||||||
@@ -460,6 +460,7 @@ const struct sLexInitString lexer_strings[] = {
|
|||||||
|
|
||||||
{"high", T_OP_HIGH},
|
{"high", T_OP_HIGH},
|
||||||
{"low", T_OP_LOW},
|
{"low", T_OP_LOW},
|
||||||
|
{"isconst", T_OP_ISCONST},
|
||||||
|
|
||||||
{"strcmp", T_OP_STRCMP},
|
{"strcmp", T_OP_STRCMP},
|
||||||
{"strin", T_OP_STRIN},
|
{"strin", T_OP_STRIN},
|
||||||
|
|||||||
@@ -553,7 +553,7 @@ which references the same macro, which has the same problem.
|
|||||||
.Pp
|
.Pp
|
||||||
One of the best features of an assembler is the ability to write macros for it.
|
One of the best features of an assembler is the ability to write macros for it.
|
||||||
Macros also provide a method of passing arguments to them and they can then react to the input using
|
Macros also provide a method of passing arguments to them and they can then react to the input using
|
||||||
.Sy IF
|
.Ic IF
|
||||||
constructs.
|
constructs.
|
||||||
.Pp
|
.Pp
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
@@ -1317,6 +1317,9 @@ For labels, as the linker has to resolve this, it can't be used when the express
|
|||||||
has been defined.
|
has been defined.
|
||||||
.It Fn HIGH arg Ta Returns the top 8 bits of the operand if Ar arg No is a label or constant, or the top 8-bit register if it is a 16-bit register.
|
.It Fn HIGH arg Ta Returns the top 8 bits of the operand if Ar arg No is a label or constant, or the top 8-bit register if it is a 16-bit register.
|
||||||
.It Fn LOW arg Ta Returns the bottom 8 bits of the operand if Ar arg No is a label or constant, or the bottom 8-bit register if it is a 16-bit register Pq Cm AF No isn't a valid register for this function .
|
.It Fn LOW arg Ta Returns the bottom 8 bits of the operand if Ar arg No is a label or constant, or the bottom 8-bit register if it is a 16-bit register Pq Cm AF No isn't a valid register for this function .
|
||||||
|
.It Fn ISCONST arg Ta Returns 1 if Ar arg Ns No 's value is known by RGBASM (e.g. if it can be an argument to
|
||||||
|
.Ic IF ) ,
|
||||||
|
or 0 if only RGBLINK can compute its value.
|
||||||
.El
|
.El
|
||||||
.Sh MISCELLANEOUS
|
.Sh MISCELLANEOUS
|
||||||
.Ss Changing options while assembling
|
.Ss Changing options while assembling
|
||||||
|
|||||||
@@ -506,6 +506,14 @@ void rpn_LOW(struct Expression *expr, const struct Expression *src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rpn_ISCONST(struct Expression *expr, const struct Expression *src)
|
||||||
|
{
|
||||||
|
rpn_Init(expr);
|
||||||
|
expr->nVal = rpn_isKnown(src);
|
||||||
|
expr->isKnown = true;
|
||||||
|
expr->isSymbol = false;
|
||||||
|
}
|
||||||
|
|
||||||
void rpn_UNNEG(struct Expression *expr, const struct Expression *src)
|
void rpn_UNNEG(struct Expression *expr, const struct Expression *src)
|
||||||
{
|
{
|
||||||
*expr = *src;
|
*expr = *src;
|
||||||
|
|||||||
29
test/asm/isconst.asm
Normal file
29
test/asm/isconst.asm
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
TEST_NUM = 0
|
||||||
|
|
||||||
|
test_expr: MACRO
|
||||||
|
TEST_NUM = TEST_NUM + 1
|
||||||
|
|
||||||
|
IS_CONST = ISCONST(\1)
|
||||||
|
PRINTT "Test #{d:TEST_NUM}: ISCONST reports {IS_CONST}\n"
|
||||||
|
IF (\1) || 1 ; Only test if the expression can be evaluated
|
||||||
|
WARN "Test #{d:TEST_NUM}: Compile-time constant"
|
||||||
|
ENDC
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
test_expr 1
|
||||||
|
test_expr UnknownLabel
|
||||||
|
|
||||||
|
SECTION "fixed", WRAM0[$CAFE]
|
||||||
|
|
||||||
|
FixedLabel:
|
||||||
|
ds 42
|
||||||
|
test_expr FixedLabel
|
||||||
|
test_expr @ - FixedLabel
|
||||||
|
|
||||||
|
SECTION "floating", WRAMX
|
||||||
|
|
||||||
|
FloatingLabel:
|
||||||
|
ds 69
|
||||||
|
test_expr FloatingLabel
|
||||||
|
test_expr @ - FloatingLabel
|
||||||
13
test/asm/isconst.err
Normal file
13
test/asm/isconst.err
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
warning: isconst.asm(14) -> isconst.asm::test_expr(10): [-Wuser]
|
||||||
|
Test #1: Compile-time constant
|
||||||
|
ERROR: isconst.asm(15) -> isconst.asm::test_expr(9):
|
||||||
|
Expected constant expression: 'UnknownLabel' is not constant at assembly time
|
||||||
|
warning: isconst.asm(21) -> isconst.asm::test_expr(10): [-Wuser]
|
||||||
|
Test #3: Compile-time constant
|
||||||
|
warning: isconst.asm(22) -> isconst.asm::test_expr(10): [-Wuser]
|
||||||
|
Test #4: Compile-time constant
|
||||||
|
ERROR: isconst.asm(28) -> isconst.asm::test_expr(9):
|
||||||
|
Expected constant expression: 'FloatingLabel' is not constant at assembly time
|
||||||
|
warning: isconst.asm(29) -> isconst.asm::test_expr(10): [-Wuser]
|
||||||
|
Test #6: Compile-time constant
|
||||||
|
error: Assembly aborted (2 errors)!
|
||||||
6
test/asm/isconst.out
Normal file
6
test/asm/isconst.out
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Test #1: ISCONST reports $1
|
||||||
|
Test #2: ISCONST reports $0
|
||||||
|
Test #3: ISCONST reports $1
|
||||||
|
Test #4: ISCONST reports $1
|
||||||
|
Test #5: ISCONST reports $0
|
||||||
|
Test #6: ISCONST reports $1
|
||||||
Reference in New Issue
Block a user