ref: b9fd85470eda79497ce44246c1385916a44900d6
parent: ec6d63bce3ead381e70a1aca0ad2501bee4d9fae
author: Rangi <35663410+Rangi42@users.noreply.github.com>
date: Mon Nov 22 12:08:29 EST 2021
Reword docs now that SET is deprecated (#946) - '=' constants are "variables" (not "mutable constants") - EQU constants are "numeric constants" (not "immutable constants") - EQUS constants are "string constants" (not "string equates") - DS declarations are "static allocations" (not "variables")
--- a/include/asm/symbol.h
+++ b/include/asm/symbol.h
@@ -23,7 +23,7 @@
enum SymbolType {
SYM_LABEL,
SYM_EQU,
- SYM_SET,
+ SYM_VAR,
SYM_MACRO,
SYM_EQUS,
SYM_REF // Forward reference to a label
@@ -75,12 +75,12 @@
return sect && sect->org != (uint32_t)-1;
}
- return sym->type == SYM_EQU || sym->type == SYM_SET;
+ return sym->type == SYM_EQU || sym->type == SYM_VAR;
}
static inline bool sym_IsNumeric(struct Symbol const *sym)
{
- return sym->type == SYM_LABEL || sym->type == SYM_EQU || sym->type == SYM_SET;
+ return sym->type == SYM_LABEL || sym->type == SYM_EQU || sym->type == SYM_VAR;
}
static inline bool sym_IsLabel(struct Symbol const *sym)
@@ -119,7 +119,7 @@
void sym_Export(char const *symName);
struct Symbol *sym_AddEqu(char const *symName, int32_t value);
struct Symbol *sym_RedefEqu(char const *symName, int32_t value);
-struct Symbol *sym_AddSet(char const *symName, int32_t value);
+struct Symbol *sym_AddVar(char const *symName, int32_t value);
uint32_t sym_GetPCValue(void);
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);
uint32_t sym_GetConstantValue(char const *symName);
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -241,11 +241,11 @@
/* If this is a FOR, update the symbol value */
if (contextStack->forName && fileInfo->iters[0] <= contextStack->nbReptIters) {
contextStack->forValue += contextStack->forStep;
- struct Symbol *sym = sym_AddSet(contextStack->forName,
+ struct Symbol *sym = sym_AddVar(contextStack->forName,
contextStack->forValue);
/* This error message will refer to the current iteration */
- if (sym->type != SYM_SET)
+ if (sym->type != SYM_VAR)
fatalerror("Failed to update FOR symbol value\n");
}
/* Advance to the next iteration */
@@ -478,9 +478,9 @@
dbgPrint("Running FOR(\"%s\", %" PRId32 ", %" PRId32 ", %" PRId32 ")\n",
symName, start, stop, step);
- struct Symbol *sym = sym_AddSet(symName, start);
+ struct Symbol *sym = sym_AddVar(symName, start);
- if (sym->type != SYM_SET)
+ if (sym->type != SYM_VAR)
return;
uint32_t count = 0;
--- a/src/asm/parser.y
+++ b/src/asm/parser.y
@@ -372,7 +372,7 @@
rpn_Number(&constExpr, constValue);
rpn_BinaryOp(op, &newExpr, &oldExpr, &constExpr);
newValue = rpn_GetConstVal(&newExpr);
- sym_AddSet(symName, newValue);
+ sym_AddVar(symName, newValue);
}
static void initDsArgList(struct DsArgList *args)
@@ -927,11 +927,11 @@
equ : T_LABEL T_POP_EQU const { sym_AddEqu($1, $3); }
;
-set : T_LABEL T_POP_EQUAL const { sym_AddSet($1, $3); }
+set : T_LABEL T_POP_EQUAL const { sym_AddVar($1, $3); }
| T_LABEL compoundeq const { compoundAssignment($1, $2, $3); }
| T_LABEL T_POP_SET const {
- warning(WARNING_OBSOLETE, "`SET` is deprecated; use `=`\n");
- sym_AddSet($1, $3);
+ warning(WARNING_OBSOLETE, "`SET` for variables is deprecated; use `=`\n");
+ sym_AddVar($1, $3);
}
;
@@ -940,19 +940,19 @@
rb : T_LABEL T_POP_RB rs_uconst {
sym_AddEqu($1, sym_GetConstantValue("_RS"));
- sym_AddSet("_RS", sym_GetConstantValue("_RS") + $3);
+ sym_AddVar("_RS", sym_GetConstantValue("_RS") + $3);
}
;
rw : T_LABEL T_POP_RW rs_uconst {
sym_AddEqu($1, sym_GetConstantValue("_RS"));
- sym_AddSet("_RS", sym_GetConstantValue("_RS") + 2 * $3);
+ sym_AddVar("_RS", sym_GetConstantValue("_RS") + 2 * $3);
}
;
rl : T_LABEL T_Z80_RL rs_uconst {
sym_AddEqu($1, sym_GetConstantValue("_RS"));
- sym_AddSet("_RS", sym_GetConstantValue("_RS") + 4 * $3);
+ sym_AddVar("_RS", sym_GetConstantValue("_RS") + 4 * $3);
}
;
@@ -1116,10 +1116,10 @@
}
;
-rsset : T_POP_RSSET uconst { sym_AddSet("_RS", $2); }
+rsset : T_POP_RSSET uconst { sym_AddVar("_RS", $2); }
;
-rsreset : T_POP_RSRESET { sym_AddSet("_RS", 0); }
+rsreset : T_POP_RSRESET { sym_AddVar("_RS", 0); }
;
rs_uconst : %empty { $$ = 1; }
@@ -1174,35 +1174,35 @@
redef_equ : redef_id T_POP_EQU const { sym_RedefEqu($1, $3); }
;
-def_set : def_id T_POP_EQUAL const { sym_AddSet($1, $3); }
- | redef_id T_POP_EQUAL const { sym_AddSet($1, $3); }
+def_set : def_id T_POP_EQUAL const { sym_AddVar($1, $3); }
+ | redef_id T_POP_EQUAL const { sym_AddVar($1, $3); }
| def_id compoundeq const { compoundAssignment($1, $2, $3); }
| redef_id compoundeq const { compoundAssignment($1, $2, $3); }
| def_id T_POP_SET const {
- warning(WARNING_OBSOLETE, "`SET` is deprecated; use `=`\n");
- sym_AddSet($1, $3);
+ warning(WARNING_OBSOLETE, "`SET` for variables is deprecated; use `=`\n");
+ sym_AddVar($1, $3);
}
| redef_id T_POP_SET const {
- warning(WARNING_OBSOLETE, "`SET` is deprecated; use `=`\n");
- sym_AddSet($1, $3);
+ warning(WARNING_OBSOLETE, "`SET` for variables is deprecated; use `=`\n");
+ sym_AddVar($1, $3);
}
;
def_rb : def_id T_POP_RB rs_uconst {
sym_AddEqu($1, sym_GetConstantValue("_RS"));
- sym_AddSet("_RS", sym_GetConstantValue("_RS") + $3);
+ sym_AddVar("_RS", sym_GetConstantValue("_RS") + $3);
}
;
def_rw : def_id T_POP_RW rs_uconst {
sym_AddEqu($1, sym_GetConstantValue("_RS"));
- sym_AddSet("_RS", sym_GetConstantValue("_RS") + 2 * $3);
+ sym_AddVar("_RS", sym_GetConstantValue("_RS") + 2 * $3);
}
;
def_rl : def_id T_Z80_RL rs_uconst {
sym_AddEqu($1, sym_GetConstantValue("_RS"));
- sym_AddSet("_RS", sym_GetConstantValue("_RS") + 4 * $3);
+ sym_AddVar("_RS", sym_GetConstantValue("_RS") + 4 * $3);
}
;
@@ -1312,13 +1312,13 @@
;
printi : T_POP_PRINTI const {
- warning(WARNING_OBSOLETE, "`PRINTI` is deprecated; use `PRINT` with `STRFMT`\n");
+ warning(WARNING_OBSOLETE, "`PRINTI` is deprecated; use `PRINT` with `STRFMT` \"%%d\"\n");
printf("%" PRId32, $2);
}
;
printf : T_POP_PRINTF const {
- warning(WARNING_OBSOLETE, "`PRINTF` is deprecated; use `PRINT` with `STRFMT`\n");
+ warning(WARNING_OBSOLETE, "`PRINTF` is deprecated; use `PRINT` with `STRFMT` \"%%f\"\n");
fix_Print($2);
}
;
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -77,8 +77,8 @@
This will paste the contents of
.Ql symbol
as if they were part of the source file.
-If it is a string equate, its characters are simply inserted as-is.
-If it is a numerical symbol, its value is converted to hexadecimal notation with a dollar sign
+If it is a string symbol, its characters are simply inserted as-is.
+If it is a numeric symbol, its value is converted to hexadecimal notation with a dollar sign
.Sq $
prepended.
.Pp
@@ -97,7 +97,7 @@
.Em interpolated
even in the contexts that disable automatic
.Em expansion
-of string equates:
+of string constants:
.Ql name
will be expanded in all of
.Ql DEF({name}) ,
@@ -170,8 +170,8 @@
.Bd -literal -offset indent
SECTION "Test", ROM0[2]
X: ;\ This works with labels **whose address is known**
-Y = 3 ;\ This also works with mutable constants
-SUM equ X + Y ;\ Likewise with immutable constants
+Y = 3 ;\ This also works with variables
+SUM equ X + Y ;\ And likewise with numeric constants
; Prints "%0010 + $3 == 5"
PRINTLN "{#05b:X} + {#x:Y} == {d:SUM}"
@@ -194,7 +194,7 @@
further below.
.Sh EXPRESSIONS
An expression can be composed of many things.
-Numerical expressions are always evaluated using signed 32-bit math.
+Numeric expressions are always evaluated using signed 32-bit math.
Zero is considered to be the only "false" number, all non-zero numbers (including negative) are "true".
.Pp
An expression is said to be "constant" if
@@ -468,7 +468,7 @@
.It Fn DEF symbol Ta Returns TRUE (1) if
.Ar symbol
has been defined, FALSE (0) otherwise.
-String equates are not expanded within the parentheses.
+String constants are not expanded within the parentheses.
.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 Ap s value is known by RGBASM (e.g. if it can be an argument to
@@ -756,12 +756,12 @@
.Ic FRAGMENT
modifiers, as described below.
.Ss Unionized Sections
-When you're tight on RAM, you may want to define overlapping blocks of variables, as explained in the
+When you're tight on RAM, you may want to define overlapping static memory allocations, as explained in the
.Sx Unions
section.
-However, the
+However, a
.Ic UNION
-keyword only works within a single file, which prevents e.g. defining temporary variables on a single memory area across several files.
+only works within a single file, so it can't be used e.g. to define temporary variables across several files, all of which use the same statically allocated memory.
Unionized sections solve this problem.
To declare an unionized section, add a
.Ic UNION
@@ -771,7 +771,7 @@
Unionized sections follow some different rules from normal sections:
.Bl -bullet -offset indent
.It
-The same unionized section (= having the same name) can be declared several times per
+The same unionized section (i.e. having the same name) can be declared several times per
.Nm
invocation, and across several invocations.
Different declarations are treated and merged identically whether within the same invocation, or different ones.
@@ -852,15 +852,15 @@
RGBDS supports several types of symbols:
.Bl -hang
.It Sy Label
-Numerical symbol designating a memory location.
+Numeric symbol designating a memory location.
May or may not have a value known at assembly time.
.It Sy Constant
-Numerical symbol whose value has to be known at assembly time.
+Numeric symbol whose value has to be known at assembly time.
.It Sy Macro
A block of
.Nm
code that can be invoked later.
-.It Sy String equate
+.It Sy String
A text string that can be expanded later, similarly to a macro.
.El
.Pp
@@ -987,12 +987,49 @@
: ; referenced by "ld hl"
dw $7FFF, $1061, $03E0, $58A5
.Ed
-.Ss Immutable constants
+.Ss Variables
+An equal sign
+.Ic =
+is used to define mutable numeric symbols.
+Unlike the other symbols described below, variables can be redefined.
+This is useful for internal symbols in macros, for counters, etc.
+.Bd -literal -offset indent
+DEF ARRAY_SIZE EQU 4
+DEF COUNT = 2
+DEF COUNT = 3
+DEF COUNT = ARRAY_SIZE + COUNT
+COUNT = COUNT*2
+;\ COUNT now has the value 14
+.Ed
+.Pp
+Note that colons
+.Ql \&:
+following the name are not allowed.
+.Pp
+Variables can be conveniently redefined by compound assignment operators like in C:
+.Bl -column -offset indent "*= /= %="
+.It Sy Operator Ta Sy Meaning
+.It Li += -= Ta Compound plus/minus
+.It Li *= /= %= Ta Compound multiply/divide/modulo
+.It Li <<= >>= Ta Compound shift left/right
+.It Li &= \&|= ^= Ta Compound and/or/xor
+.El
+.Pp
+Examples:
+.Bd -literal -offset indent
+DEF x = 10
+DEF x += 1 ; x == 11
+DEF y = x - 1 ; y == 10
+DEF y *= 2 ; y == 20
+DEF y >>= 1 ; y == 10
+DEF x ^= y ; x == 1
+.Ed
+.Ss Numeric constants
.Ic EQU
-is used to define numerical constant symbols.
+is used to define immutable numeric symbols.
Unlike
.Ic =
-below, constants defined this way cannot be redefined.
+above, constants defined this way cannot be redefined.
These constants can be used for unchanging values such as properties of the hardware.
.Bd -literal -offset indent
def SCREEN_WIDTH equ 160 ;\ In pixels
@@ -1007,7 +1044,8 @@
.Em really
need to, the
.Ic REDEF
-keyword will define or redefine a constant symbol.
+keyword will define or redefine a numeric constant symbol.
+(It can also be used for variables, although it's not necessary since they are mutable.)
This can be used, for example, to update a constant using a macro, without making it mutable in general.
.Bd -literal -offset indent
def NUM_ITEMS equ 0
@@ -1022,43 +1060,6 @@
assert NUM_ITEMS == 4
assert ITEM_04 == 16
.Ed
-.Ss Mutable constants
-.Ic =
-is used to define numerical symbols like
-.Ic EQU ,
-but these symbols can be redefined.
-This is useful for variables in macros, for counters, etc.
-.Bd -literal -offset indent
-DEF ARRAY_SIZE EQU 4
-DEF COUNT = 2
-DEF COUNT = 3
-REDEF COUNT = ARRAY_SIZE + COUNT
-COUNT = COUNT*2
-;\ COUNT now has the value 14
-.Ed
-.Pp
-Note that colons
-.Ql \&:
-following the name are not allowed.
-.Pp
-Mutable constants can be conveniently redefined by compound assignment operators like in C:
-.Bl -column -offset indent "*= /= %="
-.It Sy Operator Ta Sy Meaning
-.It Li += -= Ta Compound plus/minus
-.It Li *= /= %= Ta Compound multiply/divide/modulo
-.It Li <<= >>= Ta Compound shift left/right
-.It Li &= \&|= ^= Ta Compound and/or/xor
-.El
-.Pp
-Examples:
-.Bd -literal -offset indent
-DEF x = 10
-DEF x += 1 ; x == 11
-DEF y = x - 1 ; y == 10
-DEF y *= 2 ; y == 20
-DEF y >>= 1 ; y == 10
-DEF x ^= y ; x == 1
-.Ed
.Ss Offset constants
The RS group of commands is a handy way of defining structure offsets:
.Bd -literal -offset indent
@@ -1096,10 +1097,10 @@
Note that colons
.Ql \&:
following the name are not allowed.
-.Ss String equates
+.Ss String constants
.Ic EQUS
-is used to define string equate symbols.
-Wherever the assembler reads a string equate, it gets
+is used to define string constant symbols.
+Wherever the assembler reads a string constant, it gets
.Em expanded :
the symbol's name is replaced with its contents.
If you are familiar with C, you can think of it as similar to
@@ -1110,7 +1111,7 @@
.Ql PURGE name ,
and
.Ql MACRO name
-will not expand string equates in their names.
+will not expand string constants in their names.
.Bd -literal -offset indent
DEF COUNTREG EQUS "[hl+]"
ld a,COUNTREG
@@ -1125,7 +1126,7 @@
db "John"
.Ed
.Pp
-String equates can also be used to define small one-line macros:
+String constants can also be used to define small one-line macros:
.Bd -literal -offset indent
DEF pusha EQUS "push af\[rs]npush bc\[rs]npush de\[rs]npush hl\[rs]n"
.Ed
@@ -1134,14 +1135,12 @@
.Ql \&:
following the name are not allowed.
.Pp
-String equates can't be exported or imported.
+String constants can't be exported or imported.
.Pp
-String equates, like
-.Ic EQU
-constants, cannot be redefined.
+String constants, like numeric constants, cannot be redefined.
However, the
.Ic REDEF
-keyword will define or redefine a string symbol.
+keyword will define or redefine a string constant symbol.
For example:
.Bd -literal -offset indent
DEF s EQUS "Hello, "
@@ -1151,11 +1150,7 @@
.Ed
.Pp
.Sy Important note :
-An
-.Ic EQUS
-can be expanded to a string that contains another
-.Ic EQUS
-and it will be expanded as well.
+When a string constant is expanded, its expansion may contain another string constant, which will be expanded as well.
If this creates an infinite loop,
.Nm
will error out once a certain depth is
@@ -1164,9 +1159,7 @@
.Fl r
command-line option in
.Xr rgbasm 1 .
-Also, a macro can contain an
-.Ic EQUS
-which calls the same macro, which causes the same problem.
+The same problem can occur if the expansion of a macro invokes another macro, recursively.
.Pp
The examples above for
.Ql EQU ,
@@ -1178,9 +1171,7 @@
.Ql EQUS
all start with
.Ql DEF .
-(An
-.Ql =
-definition may start with
+(A variable definition may start with
.Ql REDEF
instead, since they are redefinable.)
You may use the older syntax without
@@ -1194,7 +1185,7 @@
Furthermore, without the
.Ql DEF
keyword,
-string equates may be expanded for the name.
+string constants may be expanded for the name.
This can lead to surprising results:
.Bd -literal -offset indent
X EQUS "Y"
@@ -1218,7 +1209,7 @@
The example above defines
.Ql MyMacro
as a new macro.
-String equates are not expanded within the name of the macro.
+String constants are not expanded within the name of the macro.
You may use the older syntax
.Ql MyMacro: MACRO
instead of
@@ -1226,7 +1217,7 @@
with a single colon
.Ql \&:
following the macro's name.
-With the older syntax, string equates may be expanded for the name.
+With the older syntax, string constants may be expanded for the name.
.Pp
Macros can't be exported or imported.
.Pp
@@ -1320,7 +1311,7 @@
I can't stress this enough,
.Sy you seriously need to know what you are doing .
DON'T purge a symbol that you use in expressions the linker needs to calculate.
-When not sure, it's probably not safe to purge anything other than string symbols, macros, and constants.
+When not sure, it's probably not safe to purge anything other than variables, numeric or string constants, or macros.
.Bd -literal -offset indent
DEF Kamikaze EQUS "I don't want to live anymore"
DEF AOLer EQUS "Me too"
@@ -1327,7 +1318,7 @@
PURGE Kamikaze, AOLer
.Ed
.Pp
-String equates are not expanded within the symbol names.
+String constants are not expanded within the symbol names.
.Ss Predeclared Symbols
The following symbols are defined by the assembler:
.Bl -column -offset indent "EQUS" "__ISO_8601_LOCAL__"
@@ -1360,9 +1351,9 @@
Refer to the spec at
.Lk https://reproducible-builds.org/docs/source-date-epoch/ .
.Sh DEFINING DATA
-.Ss Declaring variables in a RAM section
+.Ss Statically allocating space in RAM
.Ic DS
-allocates a number of empty bytes.
+statically allocates a number of empty bytes.
This is the preferred method of allocating space in a RAM section.
You can also use
.Ic DB , DW
@@ -1369,7 +1360,7 @@
and
.Ic DL
without any arguments instead (see
-.Sx Defining constant data
+.Sx Defining constant data in ROM
below).
.Bd -literal -offset indent
DS 42 ;\ Allocates 42 bytes
@@ -1380,7 +1371,7 @@
.Fl p
command-line option, except when using overlays with
.Fl O .
-.Ss Defining constant data
+.Ss Defining constant data in ROM
.Ic DB
defines a list of bytes that will be stored in the final image.
Ideal for tables and text.
@@ -1465,7 +1456,7 @@
The length argument is optional.
If only the start position is specified, the bytes from the start position until the end of the file will be included.
.Ss Unions
-Unions allow multiple memory allocations to overlap, like unions in C.
+Unions allow multiple static memory allocations to overlap, like unions in C.
This does not increase the amount of memory available, but allows re-using the same memory region for different purposes.
.Pp
A union starts with a
@@ -1513,7 +1504,7 @@
Unions may be used in any section, but inside them may only be
.Ic DS -
like commands (see
-.Sx Declaring variables in a RAM section ) .
+.Sx Statically allocating space in RAM ) .
.Sh THE MACRO LANGUAGE
.Ss Invoking macros
You execute the macro by inserting its name.
@@ -1600,7 +1591,7 @@
LoopyMacro MyVars,54
.Ed
.Pp
-Arguments are passed as string equates, although there's no need to enclose them in quotes.
+Arguments are passed as string constants, although there's no need to enclose them in quotes.
Thus, an expression will not be evaluated first but kind of copy-pasted.
This means that it's probably a very good idea to use brackets around
.Ic \[rs]1
@@ -1649,7 +1640,7 @@
Since there are only nine digits, you can only access the first nine macro arguments like this.
To use the rest, you need to put the multi-digit argument number in angle brackets, like
.Ql \[rs]<10> .
-This bracketed syntax supports decimal numbers and numeric symbol names.
+This bracketed syntax supports decimal numbers and numeric constant symbols.
For example,
.Ql \[rs]<_NARG>
will get the last argument.
@@ -1765,7 +1756,7 @@
and the matching
.Ic ENDR
will be repeated for each value of a given symbol.
-String equates are not expanded within the symbol name.
+String constants are not expanded within the symbol name.
For example, this code will produce a table of squared values from 0 to 255:
.Bd -literal -offset indent
FOR N, 256
@@ -1879,16 +1870,18 @@
.Bd -literal -offset indent
Function:
xor a
-ASSERT LOW(Variable) == 0
- ld h, HIGH(Variable)
+ASSERT LOW(MyByte) == 0
+ ld h, HIGH(MyByte)
ld l, a
ld a, [hli]
- ; You can also indent this!
+; You can also indent this!
ASSERT BANK(OtherFunction) == BANK(Function)
call OtherFunction
; Lowercase also works
-assert Variable + 1 == OtherVariable
- ld c, [hl]
+ ld hl, FirstByte
+ ld a, [hli]
+assert FirstByte + 1 == SecondByte
+ ld b, [hl]
ret
\&.end
; If you specify one, a message will be printed
--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -477,13 +477,13 @@
/*
* Alter a mutable symbol's value
*/
-struct Symbol *sym_AddSet(char const *symName, int32_t value)
+struct Symbol *sym_AddVar(char const *symName, int32_t value)
{
struct Symbol *sym = sym_FindExactSymbol(symName);
if (!sym) {
sym = createsymbol(symName);
- } else if (sym_IsDefined(sym) && sym->type != SYM_SET) {
+ } else if (sym_IsDefined(sym) && sym->type != SYM_VAR) {
error("'%s' already defined as %s at ",
symName, sym->type == SYM_LABEL ? "label" : "constant");
dumpFilename(sym);
@@ -493,7 +493,7 @@
updateSymbolFilename(sym);
}
- sym->type = SYM_SET;
+ sym->type = SYM_VAR;
sym->value = value;
return sym;
@@ -741,7 +741,7 @@
__FILE__Symbol->type = SYM_EQUS;
__FILE__Symbol->strCallback = Callback__FILE__;
- sym_AddSet("_RS", 0)->isBuiltin = true;
+ sym_AddVar("_RS", 0)->isBuiltin = true;
#define addNumber(name, val) sym_AddEqu(name, val)->isBuiltin = true
#define addString(name, val) sym_AddString(name, val)->isBuiltin = true