Repository: d5/tengo
Pull request #294 (2020-05-23 11:30:13)

add string comparison support
I'd like to add support for `< > <= >=` for strings. Tests and docs are added. Although bytecode contains only `> >=` operators `Int` object has `< <=` operator support so I added for consistency.

d5: can you merge/rebase your branch to the latest master?
ozanh: Is merge ok now? I was not using github often but I have been learning :smile: even at 36 yo :cry: 
d5: looks good. @geseq please review and feel free to merge it

Patch:
diff --git a/docs/operators.md b/docs/operators.md
index 4679ca3..68b7234 100644
--- a/docs/operators.md
+++ b/docs/operators.md
@@ -86,6 +86,13 @@
 - `(string) + (string) = (string)`: concatenation
 - `(string) + (other types) = (string)`: concatenation (after string-converted)
 
+### Comparison Operators
+
+- `(string) < (string) = (bool)`: less than
+- `(string) > (string) = (bool)`: greater than
+- `(string) <= (string) = (bool)`: less than or equal to
+- `(string) >= (string) = (bool)`: greater than or equal to
+
 ## Char
 
 ### Equality
@@ -184,4 +191,3 @@ Tests whether two _(immutable)_ maps contain the same key-objects.
 - `(immutable-map) != (immutable-map) = (bool)`: inequality
 - `(immutable-map) == (map) = (bool)`: equality
 - `(immutable-map) != (map) = (bool)`: inequality
-
diff --git a/docs/tutorial.md b/docs/tutorial.md
index a185c2a..75b7594 100644
--- a/docs/tutorial.md
+++ b/docs/tutorial.md
@@ -291,12 +291,12 @@ _In Tengo, all values can be either
 | `&^`   | bitclear (AND NOT) | int |
 | `<<`   | shift left | int |
 | `>>`   | shift right | int |
-| `<`   | less than | int, float, char, time |
-| `<=`   | less than or equal to | int, float, char, time |
-| `>`   | greater than | int, float, char, time |
-| `>=`   | greater than or equal to | int, float, char, time |
+| `<`   | less than | int, float, char, time, string |
+| `<=`   | less than or equal to | int, float, char, time, string |
+| `>`   | greater than | int, float, char, time, string |
+| `>=`   | greater than or equal to | int, float, char, time, string |
 
-_See [Operators](https://github.com/d5/tengo/blob/d5-patch-1/docs/operators.md)
+_See [Operators](https://github.com/d5/tengo/blob/master/docs/operators.md)
 for more details._
 
 ### Ternary Operators
diff --git a/objects.go b/objects.go
index 27c1d49..30913db 100644
--- a/objects.go
+++ b/objects.go
@@ -1342,6 +1342,38 @@ func (o *String) BinaryOp(op token.Token, rhs Object) (Object, error) {
 			}
 			return &String{Value: o.Value + rhsStr}, nil
 		}
+	case token.Less:
+		switch rhs := rhs.(type) {
+		case *String:
+			if o.Value < rhs.Value {
+				return TrueValue, nil
+			}
+			return FalseValue, nil
+		}
+	case token.LessEq:
+		switch rhs := rhs.(type) {
+		case *String:
+			if o.Value <= rhs.Value {
+				return TrueValue, nil
+			}
+			return FalseValue, nil
+		}
+	case token.Greater:
+		switch rhs := rhs.(type) {
+		case *String:
+			if o.Value > rhs.Value {
+				return TrueValue, nil
+			}
+			return FalseValue, nil
+		}
+	case token.GreaterEq:
+		switch rhs := rhs.(type) {
+		case *String:
+			if o.Value >= rhs.Value {
+				return TrueValue, nil
+			}
+			return FalseValue, nil
+		}
 	}
 	return nil, ErrInvalidOperator
 }


Test patch:
diff --git a/vm_test.go b/vm_test.go
index 0adefe7..b996280 100644
--- a/vm_test.go
+++ b/vm_test.go
@@ -3273,6 +3273,15 @@ func TestString(t *testing.T) {
 	expectRun(t, `out = "Hello" != "Hello"`, nil, false)
 	expectRun(t, `out = "Hello" != "World"`, nil, true)
 
+	expectRun(t, `out = "Hello" > "World"`, nil, false)
+	expectRun(t, `out = "World" < "Hello"`, nil, false)
+	expectRun(t, `out = "Hello" < "World"`, nil, true)
+	expectRun(t, `out = "World" > "Hello"`, nil, true)
+	expectRun(t, `out = "Hello" >= "World"`, nil, false)
+	expectRun(t, `out = "Hello" <= "World"`, nil, true)
+	expectRun(t, `out = "Hello" >= "Hello"`, nil, true)
+	expectRun(t, `out = "World" <= "World"`, nil, true)
+
 	// index operator
 	str := "abcdef"
 	strStr := `"abcdef"`