compiler: implement binop string: <, <=, >, >=

Include unit tests.
Этот коммит содержится в:
Marc-Antoine Ruel 2018-11-08 15:06:53 -05:00
родитель 76d04990f4
коммит b1cf69a523
4 изменённых файлов: 74 добавлений и 10 удалений

Просмотреть файл

@ -3054,7 +3054,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value) (
} else if typ.Info()&types.IsFloat != 0 { } else if typ.Info()&types.IsFloat != 0 {
// Operations on floats // Operations on floats
switch op { switch op {
case token.ADD: case token.ADD: // +
return c.builder.CreateFAdd(x, y, ""), nil return c.builder.CreateFAdd(x, y, ""), nil
case token.SUB: // - case token.SUB: // -
return c.builder.CreateFSub(x, y, ""), nil return c.builder.CreateFSub(x, y, ""), nil
@ -3102,14 +3102,23 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value) (
} else if typ.Info()&types.IsString != 0 { } else if typ.Info()&types.IsString != 0 {
// Operations on strings // Operations on strings
switch op { switch op {
case token.ADD: case token.ADD: // +
return c.createRuntimeCall("stringConcat", []llvm.Value{x, y}, ""), nil return c.createRuntimeCall("stringConcat", []llvm.Value{x, y}, ""), nil
case token.EQL, token.NEQ: // ==, != case token.EQL: // ==
return c.createRuntimeCall("stringEqual", []llvm.Value{x, y}, ""), nil
case token.NEQ: // !=
result := c.createRuntimeCall("stringEqual", []llvm.Value{x, y}, "") result := c.createRuntimeCall("stringEqual", []llvm.Value{x, y}, "")
if op == token.NEQ { return c.builder.CreateNot(result, ""), nil
result = c.builder.CreateNot(result, "") case token.LSS: // <
} return c.createRuntimeCall("stringLess", []llvm.Value{x, y}, ""), nil
return result, nil case token.LEQ: // <=
result := c.createRuntimeCall("stringLess", []llvm.Value{y, x}, "")
return c.builder.CreateNot(result, ""), nil
case token.GTR: // >
result := c.createRuntimeCall("stringLess", []llvm.Value{x, y}, "")
return c.builder.CreateNot(result, ""), nil
case token.GEQ: // >=
return c.createRuntimeCall("stringLess", []llvm.Value{y, x}, ""), nil
default: default:
return llvm.Value{}, errors.New("todo: binop on string: " + op.String()) return llvm.Value{}, errors.New("todo: binop on string: " + op.String())
} }

Просмотреть файл

@ -32,6 +32,24 @@ func stringEqual(x, y string) bool {
return true return true
} }
// Return true iff x < y.
//go:nobounds
func stringLess(x, y string) bool {
l := len(x)
if m := len(y); m < l {
l = m
}
for i := 0; i < l; i++ {
if x[i] < y[i] {
return true
}
if x[i] > y[i] {
return false
}
}
return len(x) < len(y)
}
// Add two strings together. // Add two strings together.
func stringConcat(x, y _string) _string { func stringConcat(x, y _string) _string {
if x.length == 0 { if x.length == 0 {

23
testdata/binop.go предоставленный
Просмотреть файл

@ -1,13 +1,30 @@
package main package main
func main() { func main() {
// string equality println("string equality")
println(a == "a") println(a == "a")
println(a == "b") println(a == "b")
println(a != "a") println(a != "a")
println(a != "b") println(a != "b")
println("string inequality")
println(a > "b")
println("b" > a)
println("b" > "b")
println(a <= "b")
println("b" <= a)
println("b" <= "b")
println(a > "b")
println("b" > a)
println("b" > "b")
println(a <= "b")
println("b" <= a)
println("b" <= "b")
println(a < "aa")
println("aa" < a)
println("ab" < "aa")
println("aa" < "ab")
// struct equality println("struct equality")
println(s1 == Struct1{3, true}) println(s1 == Struct1{3, true})
println(s1 == Struct1{4, true}) println(s1 == Struct1{4, true})
println(s1 == Struct1{3, false}) println(s1 == Struct1{3, false})
@ -17,7 +34,7 @@ func main() {
println(s1 != Struct1{3, false}) println(s1 != Struct1{3, false})
println(s1 != Struct1{4, false}) println(s1 != Struct1{4, false})
// blank fields in structs println("blank fields in structs")
println(s2 == Struct2{"foo", 0.0, 5}) println(s2 == Struct2{"foo", 0.0, 5})
println(s2 == Struct2{"foo", 0.0, 7}) println(s2 == Struct2{"foo", 0.0, 7})
println(s2 == Struct2{"foo", 1.0, 5}) println(s2 == Struct2{"foo", 1.0, 5})

20
testdata/binop.txt предоставленный
Просмотреть файл

@ -1,7 +1,26 @@
string equality
true true
false false
false false
true true
string inequality
false
true
false
true
false
true
false
true
false
true
false
true
true
false
false
true
struct equality
true true
false false
false false
@ -10,6 +29,7 @@ false
true true
true true
true true
blank fields in structs
true true
false false
true true