Merge pull request #490 from ISSOtm/const

Implement `ISCONST`, reporting compile-time constness
This commit is contained in:
Eldred Habert
2020-03-21 23:20:01 +01:00
committed by GitHub
8 changed files with 64 additions and 1 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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},

View File

@@ -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

View File

@@ -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
View 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
View 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
View 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