summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2019-06-15 17:49:00 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2019-06-15 17:49:00 (GMT)
commitaa443ce8d55f84fa49eb9c6272005383df882681 (patch)
tree18a965ed7dabaeaf39b49850ed3412e7f0494d91
parent475b6678272de33930144b7f27b4354095b86c6f (diff)
parent7bfc294816888f8f2186286107ac569f08bf68c4 (diff)
downloadtcl-aa443ce8d55f84fa49eb9c6272005383df882681.zip
tcl-aa443ce8d55f84fa49eb9c6272005383df882681.tar.gz
tcl-aa443ce8d55f84fa49eb9c6272005383df882681.tar.bz2
TIP 461: text comparison operators for [expr]
-rw-r--r--doc/expr.n21
-rw-r--r--doc/mathop.n67
-rw-r--r--generic/tclAssembly.c7
-rw-r--r--generic/tclBasic.c8
-rw-r--r--generic/tclCompCmdsSZ.c44
-rw-r--r--generic/tclCompExpr.c49
-rw-r--r--generic/tclCompile.c9
-rw-r--r--generic/tclCompile.h8
-rw-r--r--generic/tclExecute.c8
-rw-r--r--generic/tclInt.h12
-rw-r--r--tests/expr.test20
-rw-r--r--tests/mathop.test44
12 files changed, 276 insertions, 21 deletions
diff --git a/doc/expr.n b/doc/expr.n
index d7536d8..8ea1688 100644
--- a/doc/expr.n
+++ b/doc/expr.n
@@ -159,7 +159,18 @@ A right shift always propagates the sign bit.
.TP 20
\fB<\0\0>\0\0<=\0\0>=\fR
.
-Boolean less than, greater than, less than or equal, and greater than or equal.
+Boolean numeric-preferring comparisons: less than, greater than, less than or
+equal, and greater than or equal. If either argument is not numeric, the
+comparison is done using UNICODE string comparison, as with the string
+comparison operators below, which have the same precedence.
+.TP 20
+\fBlt\0\0gt\0\0le\0\0ge\fR
+.VS "8.7, TIP461"
+Boolean string comparisons: less than, greater than, less than or equal, and
+greater than or equal. These always compare values using their UNICODE strings
+(also see \fBstring compare\fR), unlike with the numeric-preferring
+comparisons abov, which have the same precedence.
+.VE "8.7, TIP461"
.TP 20
\fB==\0\0!=\fR
.
@@ -403,6 +414,14 @@ A string comparison whose result is 1:
\fBexpr\fR {"0y" > "0x12"}
.CE
.PP
+.VS "8.7, TIP461"
+A forced string comparison whose result is 0:
+.PP
+.CS
+\fBexpr\fR {"0x03" gt "2"}
+.CE
+.VE "8.7, TIP461"
+.PP
Define a procedure that computes an
.QW interesting
mathematical function:
diff --git a/doc/mathop.n b/doc/mathop.n
index 84cf308..1c70e95 100644
--- a/doc/mathop.n
+++ b/doc/mathop.n
@@ -55,6 +55,16 @@ package require \fBTcl 8.5\fR
.br
\fB::tcl::mathop::ne\fR \fIarg arg\fR
.br
+.VS "8.7, TIP461"
+\fB::tcl::mathop::lt\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::le\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::gt\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::ge\fR ?\fIarg\fR ...?
+.VE "8.7, TIP461"
+.br
\fB::tcl::mathop::in\fR \fIarg list\fR
.br
\fB::tcl::mathop::ni\fR \fIarg list\fR
@@ -76,7 +86,8 @@ The following operator commands are supported:
\fB/\fR \fB%\fR \fB**\fR \fB&\fR \fB|\fR
\fB^\fR \fB>>\fR \fB<<\fR \fB==\fR \fBeq\fR
\fB!=\fR \fBne\fR \fB<\fR \fB<=\fR \fB>\fR
-\fB>=\fR \fBin\fR \fBni\fR
+\fB>=\fR \fBin\fR \fBni\fR \fBlt\fR \fBle\fR
+\fBgt\fR \fBge\fR
.DE
.SS "MATHEMATICAL OPERATORS"
.PP
@@ -192,8 +203,8 @@ after the first having to be strictly more than the one preceding it.
Comparisons are performed preferentially on the numeric values, and are
otherwise performed using UNICODE string comparison. If fewer than two
arguments are present, this operation always returns a true value. When the
-arguments are numeric but should be compared as strings, the \fBstring
-compare\fR command should be used instead.
+arguments are numeric but should be compared as strings, the \fBlt\fR
+operator or the \fBstring compare\fR command should be used instead.
.TP
\fB<=\fR ?\fIarg\fR ...?
.
@@ -202,8 +213,8 @@ after the first having to be equal to or more than the one preceding it.
Comparisons are performed preferentially on the numeric values, and are
otherwise performed using UNICODE string comparison. If fewer than two
arguments are present, this operation always returns a true value. When the
-arguments are numeric but should be compared as strings, the \fBstring
-compare\fR command should be used instead.
+arguments are numeric but should be compared as strings, the \fBle\fR
+operator or the \fBstring compare\fR command should be used instead.
.TP
\fB>\fR ?\fIarg\fR ...?
.
@@ -212,8 +223,8 @@ after the first having to be strictly less than the one preceding it.
Comparisons are performed preferentially on the numeric values, and are
otherwise performed using UNICODE string comparison. If fewer than two
arguments are present, this operation always returns a true value. When the
-arguments are numeric but should be compared as strings, the \fBstring
-compare\fR command should be used instead.
+arguments are numeric but should be compared as strings, the \fBgt\fR
+operator or the \fBstring compare\fR command should be used instead.
.TP
\fB>=\fR ?\fIarg\fR ...?
.
@@ -222,8 +233,40 @@ after the first having to be equal to or less than the one preceding it.
Comparisons are performed preferentially on the numeric values, and are
otherwise performed using UNICODE string comparison. If fewer than two
arguments are present, this operation always returns a true value. When the
-arguments are numeric but should be compared as strings, the \fBstring
-compare\fR command should be used instead.
+arguments are numeric but should be compared as strings, the \fBge\fR
+operator or the \fBstring compare\fR command should be used instead.
+.TP
+\fBlt\fR ?\fIarg\fR ...?
+.VS "8.7, TIP461"
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be strictly more than the one preceding it.
+Comparisons are performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value.
+.VE "8.7, TIP461"
+.TP
+\fBle\fR ?\fIarg\fR ...?
+.VS "8.7, TIP461"
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be equal to or strictly more than the one preceding it.
+Comparisons are performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value.
+.VE "8.7, TIP461"
+.TP
+\fBgt\fR ?\fIarg\fR ...?
+.VS "8.7, TIP461"
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be strictly less than the one preceding it.
+Comparisons are performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value.
+.VE "8.7, TIP461"
+.TP
+\fBge\fR ?\fIarg\fR ...?
+.VS "8.7, TIP461"
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be equal to or strictly less than the one preceding it.
+Comparisons are performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value.
+.VE "8.7, TIP461"
.SS "BIT-WISE OPERATORS"
.PP
The behaviors of the bit-wise operator commands (all of which only operate on
@@ -299,8 +342,12 @@ set gotIt [\fBin\fR 3 $list]
\fI# Test to see if a value is within some defined range\fR
set inRange [\fB<=\fR 1 $x 5]
-\fI# Test to see if a list is sorted\fR
+\fI# Test to see if a list is numerically sorted\fR
set sorted [\fB<=\fR {*}$list]
+
+\fI# Test to see if a list is lexically sorted\fR
+set alphaList {a b c d e f}
+set sorted [\fBle\fR {*}$alphaList]
.CE
.SH "SEE ALSO"
expr(n), mathfunc(n), namespace(n)
diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c
index 3615f33..c70fb08 100644
--- a/generic/tclAssembly.c
+++ b/generic/tclAssembly.c
@@ -474,8 +474,12 @@ static const TalInstDesc TalInstructionTable[] = {
{"strcat", ASSEM_CONCAT1, INST_STR_CONCAT1, INT_MIN,1},
{"streq", ASSEM_1BYTE, INST_STR_EQ, 2, 1},
{"strfind", ASSEM_1BYTE, INST_STR_FIND, 2, 1},
+ {"strge", ASSEM_1BYTE, INST_STR_GE, 2, 1},
+ {"strgt", ASSEM_1BYTE, INST_STR_GT, 2, 1},
{"strindex", ASSEM_1BYTE, INST_STR_INDEX, 2, 1},
+ {"strle", ASSEM_1BYTE, INST_STR_LE, 2, 1},
{"strlen", ASSEM_1BYTE, INST_STR_LEN, 1, 1},
+ {"strlt", ASSEM_1BYTE, INST_STR_LT, 2, 1},
{"strmap", ASSEM_1BYTE, INST_STR_MAP, 3, 1},
{"strmatch", ASSEM_BOOL, INST_STR_MATCH, 2, 1},
{"strneq", ASSEM_1BYTE, INST_STR_NEQ, 2, 1},
@@ -532,7 +536,8 @@ static const unsigned char NonThrowingByteCodes[] = {
INST_STR_TRIM, INST_STR_TRIM_LEFT, INST_STR_TRIM_RIGHT, /* 166-168 */
INST_CONCAT_STK, /* 169 */
INST_STR_UPPER, INST_STR_LOWER, INST_STR_TITLE, /* 170-172 */
- INST_NUM_TYPE /* 180 */
+ INST_NUM_TYPE, /* 180 */
+ INST_STR_LT, INST_STR_GT, INST_STR_LE, INST_STR_GE /* 191-194 */
};
/*
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 5d764e2..de334b5 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -504,6 +504,14 @@ static const OpCmdInfo mathOpCmds[] = {
/* unused */ {0}, NULL},
{ "eq", TclSortingOpCmd, TclCompileStreqOpCmd,
/* unused */ {0}, NULL},
+ { "lt", TclSortingOpCmd, TclCompileStrLtOpCmd,
+ /* unused */ {0}, NULL},
+ { "le", TclSortingOpCmd, TclCompileStrLeOpCmd,
+ /* unused */ {0}, NULL},
+ { "gt", TclSortingOpCmd, TclCompileStrGtOpCmd,
+ /* unused */ {0}, NULL},
+ { "ge", TclSortingOpCmd, TclCompileStrGeOpCmd,
+ /* unused */ {0}, NULL},
{ NULL, NULL, NULL,
{0}, NULL}
};
diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c
index 83ade0b..da45cb3 100644
--- a/generic/tclCompCmdsSZ.c
+++ b/generic/tclCompCmdsSZ.c
@@ -4493,6 +4493,50 @@ TclCompileStreqOpCmd(
{
return CompileComparisonOpCmd(interp, parsePtr, INST_STR_EQ, envPtr);
}
+
+int
+TclCompileStrLtOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_STR_LT, envPtr);
+}
+
+int
+TclCompileStrLeOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_STR_LE, envPtr);
+}
+
+int
+TclCompileStrGtOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_STR_GT, envPtr);
+}
+
+int
+TclCompileStrGeOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_STR_GE, envPtr);
+}
int
TclCompileMinusOpCmd(
diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c
index 56c8931..dec9600 100644
--- a/generic/tclCompExpr.c
+++ b/generic/tclCompExpr.c
@@ -281,7 +281,11 @@ enum Marks {
* parse tree. The sub-expression between
* parens becomes the single argument of the
* matching OPEN_PAREN unary operator. */
-#define END (BINARY | 28)
+#define STR_LT (BINARY | 28)
+#define STR_GT (BINARY | 29)
+#define STR_LEQ (BINARY | 30)
+#define STR_GEQ (BINARY | 31)
+#define END (BINARY | 32)
/* This lexeme represents the end of the
* string being parsed. Treating it as a
* binary operator follows the same logic as
@@ -360,12 +364,14 @@ static const unsigned char prec[] = {
PREC_EQUAL, /* IN_LIST */
PREC_EQUAL, /* NOT_IN_LIST */
PREC_CLOSE_PAREN, /* CLOSE_PAREN */
+ PREC_COMPARE, /* STR_LT */
+ PREC_COMPARE, /* STR_GT */
+ PREC_COMPARE, /* STR_LEQ */
+ PREC_COMPARE, /* STR_GEQ */
PREC_END, /* END */
/* Expansion room for more binary operators */
- 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
/* Unary operator lexemes */
PREC_UNARY, /* UNARY_PLUS */
PREC_UNARY, /* UNARY_MINUS */
@@ -415,12 +421,14 @@ static const unsigned char instruction[] = {
INST_LIST_IN, /* IN_LIST */
INST_LIST_NOT_IN, /* NOT_IN_LIST */
0, /* CLOSE_PAREN */
+ INST_STR_LT, /* STR_LT */
+ INST_STR_GT, /* STR_GT */
+ INST_STR_LE, /* STR_LEQ */
+ INST_STR_GE, /* STR_GEQ */
0, /* END */
/* Expansion room for more binary operators */
- 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,
/* Unary operator lexemes */
INST_UPLUS, /* UNARY_PLUS */
INST_UMINUS, /* UNARY_MINUS */
@@ -2001,6 +2009,35 @@ ParseLexeme(
return 2;
}
}
+ break;
+
+ case 'l':
+ if ((numBytes > 1)
+ && ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) {
+ switch (start[1]) {
+ case 't':
+ *lexemePtr = STR_LT;
+ return 2;
+ case 'e':
+ *lexemePtr = STR_LEQ;
+ return 2;
+ }
+ }
+ break;
+
+ case 'g':
+ if ((numBytes > 1)
+ && ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) {
+ switch (start[1]) {
+ case 't':
+ *lexemePtr = STR_GT;
+ return 2;
+ case 'e':
+ *lexemePtr = STR_GEQ;
+ return 2;
+ }
+ }
+ break;
}
literal = Tcl_NewObj();
@@ -2568,7 +2605,7 @@ TclSingleOpCmd(
*
* TclSortingOpCmd --
* Implements the commands:
- * <, <=, >, >=, ==, eq
+ * <, <=, >, >=, ==, eq, lt, le, gt, ge
* in the ::tcl::mathop namespace. These commands are defined for
* arbitrary number of arguments by computing the AND of the base
* operator applied to all neighbor argument pairs.
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 0afa9cb..c10e3ee 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -667,6 +667,15 @@ InstructionDesc const tclInstructionTable[] = {
* default is pushed instead.
* Stack: ... dict key1 ... keyN default => ... value */
+ {"strlt", 1, -1, 0, {OPERAND_NONE}},
+ /* String Less: push (stknext < stktop) */
+ {"strgt", 1, -1, 0, {OPERAND_NONE}},
+ /* String Greater: push (stknext > stktop) */
+ {"strle", 1, -1, 0, {OPERAND_NONE}},
+ /* String Less or equal: push (stknext <= stktop) */
+ {"strge", 1, -1, 0, {OPERAND_NONE}},
+ /* String Greater or equal: push (stknext >= stktop) */
+
{NULL, 0, 0, 0, {OPERAND_NONE}}
};
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index 117fa46..686b2dd 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -842,8 +842,14 @@ typedef struct ByteCode {
#define INST_DICT_GET_DEF 190
+/* TIP 461 */
+#define INST_STR_LT 191
+#define INST_STR_GT 192
+#define INST_STR_LE 193
+#define INST_STR_GE 194
+
/* The last opcode */
-#define LAST_INST_OPCODE 190
+#define LAST_INST_OPCODE 194
/*
* Table describing the Tcl bytecode instructions: their name (for displaying
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 8785d36..91c6a42 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -5084,6 +5084,10 @@ TEBCresume(
case INST_STR_EQ:
case INST_STR_NEQ: /* String (in)equality check */
case INST_STR_CMP: /* String compare. */
+ case INST_STR_LT:
+ case INST_STR_GT:
+ case INST_STR_LE:
+ case INST_STR_GE:
stringCompare:
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
@@ -5114,15 +5118,19 @@ TEBCresume(
match = (match != 0);
break;
case INST_LT:
+ case INST_STR_LT:
match = (match < 0);
break;
case INST_GT:
+ case INST_STR_GT:
match = (match > 0);
break;
case INST_LE:
+ case INST_STR_LE:
match = (match <= 0);
break;
case INST_GE:
+ case INST_STR_GE:
match = (match >= 0);
break;
}
diff --git a/generic/tclInt.h b/generic/tclInt.h
index c844cc4..80b4493 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -4047,6 +4047,18 @@ MODULE_SCOPE int TclCompileEqOpCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileStreqOpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStrLtOpCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStrLeOpCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStrGtOpCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
+MODULE_SCOPE int TclCompileStrGeOpCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, Command *cmdPtr,
+ struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
diff --git a/tests/expr.test b/tests/expr.test
index cb0c24d..01c5213 100644
--- a/tests/expr.test
+++ b/tests/expr.test
@@ -411,6 +411,26 @@ test expr-8.34 {expr edge cases} -body {
test expr-8.35 {expr edge cases} -body {
expr {1ea}
} -returnCodes error -match glob -result *
+test expr-8.36 {CompileEqualtyExpr: string comparison ops} {
+ set x 012
+ set y 0x0
+ list [expr {$x < $y}] [expr {$x lt $y}] [expr {$x lt $x}]
+} {0 1 0}
+test expr-8.37 {CompileEqualtyExpr: string comparison ops} {
+ set x 012
+ set y 0x0
+ list [expr {$x <= $y}] [expr {$x le $y}] [expr {$x le $x}]
+} {0 1 1}
+test expr-8.38 {CompileEqualtyExpr: string comparison ops} {
+ set x 012
+ set y 0x0
+ list [expr {$x > $y}] [expr {$x gt $y}] [expr {$x gt $x}]
+} {1 0 0}
+test expr-8.39 {CompileEqualtyExpr: string comparison ops} {
+ set x 012
+ set y 0x0
+ list [expr {$x >= $y}] [expr {$x ge $y}] [expr {$x ge $x}]
+} {1 0 1}
test expr-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12
test expr-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63
diff --git a/tests/mathop.test b/tests/mathop.test
index a1a3f80..958a56f 100644
--- a/tests/mathop.test
+++ b/tests/mathop.test
@@ -95,7 +95,7 @@ proc TestOp {op args} {
}
return [lindex $results 0]
}
-
+
# start of tests
namespace eval ::testmathop {
@@ -1342,6 +1342,46 @@ test mathop-26.2 { misc ops, corner cases } {
set res
} [list 2147483648 9223372036854775808 9223372036854775808 4294967296 18446744073709551616]
+test mathop-27.1 {lt operator} {::tcl::mathop::lt} 1
+test mathop-27.2 {lt operator} {::tcl::mathop::lt a} 1
+test mathop-27.3 {lt operator} {::tcl::mathop::lt a b} 1
+test mathop-27.4 {lt operator} {::tcl::mathop::lt b a} 0
+test mathop-27.5 {lt operator} {::tcl::mathop::lt a a} 0
+test mathop-27.6 {lt operator} {::tcl::mathop::lt a b c} 1
+test mathop-27.7 {lt operator} {::tcl::mathop::lt b a c} 0
+test mathop-27.8 {lt operator} {::tcl::mathop::lt a c b} 0
+test mathop-27.9 {lt operator} {::tcl::mathop::lt 012 0x0} 1
+
+test mathop-28.1 {le operator} {::tcl::mathop::le} 1
+test mathop-28.2 {le operator} {::tcl::mathop::le a} 1
+test mathop-28.3 {le operator} {::tcl::mathop::le a b} 1
+test mathop-28.4 {le operator} {::tcl::mathop::le b a} 0
+test mathop-28.5 {le operator} {::tcl::mathop::le a a} 1
+test mathop-28.6 {le operator} {::tcl::mathop::le a b c} 1
+test mathop-28.7 {le operator} {::tcl::mathop::le b a c} 0
+test mathop-28.8 {le operator} {::tcl::mathop::le a c b} 0
+test mathop-28.9 {le operator} {::tcl::mathop::le 012 0x0} 1
+
+test mathop-29.1 {gt operator} {::tcl::mathop::gt} 1
+test mathop-29.2 {gt operator} {::tcl::mathop::gt a} 1
+test mathop-29.3 {gt operator} {::tcl::mathop::gt a b} 0
+test mathop-29.4 {gt operator} {::tcl::mathop::gt b a} 1
+test mathop-29.5 {gt operator} {::tcl::mathop::gt a a} 0
+test mathop-29.6 {gt operator} {::tcl::mathop::gt c b a} 1
+test mathop-29.7 {gt operator} {::tcl::mathop::gt b a c} 0
+test mathop-29.8 {gt operator} {::tcl::mathop::gt a c b} 0
+test mathop-29.9 {gt operator} {::tcl::mathop::gt 0x0 012} 1
+
+test mathop-30.1 {ge operator} {::tcl::mathop::ge} 1
+test mathop-30.2 {ge operator} {::tcl::mathop::ge a} 1
+test mathop-30.3 {ge operator} {::tcl::mathop::ge a b} 0
+test mathop-30.4 {ge operator} {::tcl::mathop::ge b a} 1
+test mathop-30.5 {ge operator} {::tcl::mathop::ge a a} 1
+test mathop-30.6 {ge operator} {::tcl::mathop::ge c b a} 1
+test mathop-30.7 {ge operator} {::tcl::mathop::ge b a c} 0
+test mathop-30.8 {ge operator} {::tcl::mathop::ge a c b} 0
+test mathop-30.9 {ge operator} {::tcl::mathop::ge 0x0 012} 1
+
if 0 {
# Compare ops to expr bytecodes
namespace import ::tcl::mathop::*
@@ -1354,7 +1394,7 @@ if 0 {
_X 3 4 5
set ::tcl_traceCompile 0
}
-
+
# cleanup
namespace delete ::testmathop
namespace delete ::testmathop2