Implement === and !== string comparison operators (#1832)

This commit is contained in:
Rangi
2025-09-19 14:06:36 -04:00
committed by GitHub
parent 67741ab428
commit e31bcabbaa
4 changed files with 41 additions and 6 deletions

View File

@@ -586,6 +586,19 @@ is equivalent to
or to
.Ql STRCAT("str", \&"ing") .
.Pp
You can use the
.Sq ===
and
.Sq !==
operators to compare two strings.
.Ql \&"str" === \&"ing"
is equivalent to
.Ql STRCMP("str", \&"ing") == 0 ,
and
.Ql \&"str" !== \&"ing"
is equivalent to
.Ql STRCMP("str", \&"ing") != 0 .
.Pp
The following functions operate on string expressions, and return strings themselves.
.Bl -column "STRSLICE(str, start, stop)"
.It Sy Name Ta Sy Operation

View File

@@ -1750,14 +1750,22 @@ static Token yylex_NORMAL() {
case '^': // Either ^= or XOR
return oneOrTwo('=', T_(POP_XOREQ), T_(OP_XOR));
case '=': // Either assignment or EQ
return oneOrTwo('=', T_(OP_LOGICEQU), T_(POP_EQUAL));
case '!': // Either a NEQ or negation
return oneOrTwo('=', T_(OP_LOGICNE), T_(OP_LOGICNOT));
// Handle ambiguous 1-, 2-, or 3-char tokens
case '=': // Either assignment, EQ or string EQ
if (peek() == '=') {
shiftChar();
return oneOrTwo('=', T_(OP_STREQU), T_(OP_LOGICEQU));
}
return Token(T_(POP_EQUAL));
case '!': // Either negation, NEQ, or string NEQ
if (peek() == '=') {
shiftChar();
return oneOrTwo('=', T_(OP_STRNE), T_(OP_LOGICNE));
}
return Token(T_(OP_LOGICNOT));
case '<': // Either <<=, LT, LTE, or left shift
if (peek() == '<') {
shiftChar();

View File

@@ -107,6 +107,7 @@
// String operators
%token OP_CAT "++"
%token OP_STREQU "===" OP_STRNE "!=="
// Comparison operators
%token OP_LOGICEQU "==" OP_LOGICNE "!="
@@ -1287,6 +1288,12 @@ relocexpr_no_str:
| CHARACTER {
$$.makeNumber(act_CharToNum($1));
}
| string OP_STREQU string {
$$.makeNumber($1.compare($3) == 0);
}
| string OP_STRNE string {
$$.makeNumber($1.compare($3) != 0);
}
| OP_LOGICNOT relocexpr %prec NEG {
$$.makeUnaryOp(RPN_LOGNOT, std::move($2));
}

View File

@@ -0,0 +1,7 @@
assert "hello" === "hello"
assert "hello" !== "goodbye"
assert "game" ++ "boy" === "gameboy"
assert "fire flower" === "fire" ++ " " ++ "flower"
assert "a" === "b" == 0
assert 1 == "a" !== "b"
assert 1 + 2 * 3 ** "x" !== "y" == 7