ref: fe824e00687e96180c15c659511404ca6b93f079
parent: 66512ed8d2676f4937b2c64c9fea125aeb76d1d4
parent: 8fcdcb173184115c39bc175045aa94c942959c4d
author: Eldred Habert <[email protected]>
date: Sat Mar 21 19:20:01 EDT 2020
Merge pull request #490 from ISSOtm/const Implement `ISCONST`, reporting compile-time constness
--- a/include/asm/rpn.h
+++ b/include/asm/rpn.h
@@ -54,6 +54,7 @@
const struct Expression *src2);
void rpn_HIGH(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_UNNOT(struct Expression *expr, const struct Expression *src);
void rpn_BankSymbol(struct Expression *expr, char const *tzSym);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -543,6 +543,7 @@
%left T_OP_FLOOR
%token T_OP_HIGH T_OP_LOW
+%token T_OP_ISCONST
%left T_OP_STRCMP
%left T_OP_STRIN
@@ -1301,6 +1302,7 @@
| T_OP_NOT relocexpr %prec NEG { rpn_UNNOT(&$$, &$2); }
| T_OP_HIGH '(' relocexpr ')' { rpn_HIGH(&$$, &$3); }
| T_OP_LOW '(' relocexpr ')' { rpn_LOW(&$$, &$3); }
+ | T_OP_ISCONST '(' relocexpr ')'{ rpn_ISCONST(&$$, &$3); }
| T_OP_BANK '(' scoped_id ')' {
/* '@' is also a T_ID, it is handled here. */
rpn_BankSymbol(&$$, $3);
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -460,6 +460,7 @@
{"high", T_OP_HIGH},
{"low", T_OP_LOW},
+ {"isconst", T_OP_ISCONST},
{"strcmp", T_OP_STRCMP},
{"strin", T_OP_STRIN},
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -553,7 +553,7 @@
.Pp
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
-.Sy IF
+.Ic IF
constructs.
.Pp
.Bd -literal -offset indent
@@ -1317,6 +1317,9 @@
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 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
.Sh MISCELLANEOUS
.Ss Changing options while assembling
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -506,6 +506,14 @@
}
}
+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)
{
*expr = *src;
--- /dev/null
+++ b/test/asm/isconst.asm
@@ -1,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
--- /dev/null
+++ b/test/asm/isconst.err
@@ -1,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)!
--- /dev/null
+++ b/test/asm/isconst.out
@@ -1,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