ssa: string range; string convert bytes/rune; op eql/less
This commit is contained in:
@@ -847,7 +847,7 @@ _llgo_3: ; preds = %_llgo_0
|
|||||||
|
|
||||||
define void @main.printfloat(double %0) {
|
define void @main.printfloat(double %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = fcmp one double %0, %0
|
%1 = fcmp une double %0, %0
|
||||||
br i1 %1, label %_llgo_1, label %_llgo_3
|
br i1 %1, label %_llgo_1, label %_llgo_3
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_0
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
|||||||
@@ -40,7 +40,53 @@ func main() {
|
|||||||
println(n)
|
println(n)
|
||||||
}
|
}
|
||||||
println(demo, fn1, fn2, fn3)
|
println(demo, fn1, fn2, fn3)
|
||||||
|
|
||||||
|
for i, v := range "中abcd" {
|
||||||
|
println(i, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
println(Inf(1), Inf(-1), NaN(), IsNaN(NaN()), IsNaN(1.0))
|
||||||
|
|
||||||
|
data1 := []byte("中abcd")
|
||||||
|
data2 := []rune("中abcd")
|
||||||
|
println(data1, data2)
|
||||||
|
println(string(data1), string(data2), string(data1[3]), string(data2[0]))
|
||||||
|
s1 := "abc"
|
||||||
|
s2 := "abd"
|
||||||
|
println(s1 == "abc", s1 == s2, s1 != s2, s1 < s2, s1 <= s2, s1 > s2, s1 >= s2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func demo() {
|
func demo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
uvnan = 0x7FF8000000000001
|
||||||
|
uvinf = 0x7FF0000000000000
|
||||||
|
uvneginf = 0xFFF0000000000000
|
||||||
|
uvone = 0x3FF0000000000000
|
||||||
|
mask = 0x7FF
|
||||||
|
shift = 64 - 11 - 1
|
||||||
|
bias = 1023
|
||||||
|
signMask = 1 << 63
|
||||||
|
fracMask = 1<<shift - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
|
||||||
|
func Inf(sign int) float64 {
|
||||||
|
var v uint64
|
||||||
|
if sign >= 0 {
|
||||||
|
v = uvinf
|
||||||
|
} else {
|
||||||
|
v = uvneginf
|
||||||
|
}
|
||||||
|
return Float64frombits(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NaN returns an IEEE 754 “not-a-number” value.
|
||||||
|
func NaN() float64 { return Float64frombits(uvnan) }
|
||||||
|
|
||||||
|
func IsNaN(f float64) (is bool) {
|
||||||
|
return f != f
|
||||||
|
}
|
||||||
|
|
||||||
|
func Float64frombits(b uint64) float64 { return *(*float64)(unsafe.Pointer(&b)) }
|
||||||
|
|||||||
@@ -17,7 +17,61 @@ source_filename = "main"
|
|||||||
@3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
@3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
||||||
@4 = private unnamed_addr constant [4 x i8] c"def\00", align 1
|
@4 = private unnamed_addr constant [4 x i8] c"def\00", align 1
|
||||||
@5 = private unnamed_addr constant [5 x i8] c"ABCD\00", align 1
|
@5 = private unnamed_addr constant [5 x i8] c"ABCD\00", align 1
|
||||||
@6 = private unnamed_addr constant [3 x i8] c"fn\00", align 1
|
@6 = private unnamed_addr constant [8 x i8] c"\E4\B8\ADabcd\00", align 1
|
||||||
|
@7 = private unnamed_addr constant [8 x i8] c"\E4\B8\ADabcd\00", align 1
|
||||||
|
@8 = private unnamed_addr constant [8 x i8] c"\E4\B8\ADabcd\00", align 1
|
||||||
|
@9 = private unnamed_addr constant [4 x i8] c"abc\00", align 1
|
||||||
|
@10 = private unnamed_addr constant [4 x i8] c"abc\00", align 1
|
||||||
|
@11 = private unnamed_addr constant [4 x i8] c"abc\00", align 1
|
||||||
|
@12 = private unnamed_addr constant [4 x i8] c"abd\00", align 1
|
||||||
|
@13 = private unnamed_addr constant [4 x i8] c"abc\00", align 1
|
||||||
|
@14 = private unnamed_addr constant [4 x i8] c"abd\00", align 1
|
||||||
|
@15 = private unnamed_addr constant [4 x i8] c"abc\00", align 1
|
||||||
|
@16 = private unnamed_addr constant [4 x i8] c"abd\00", align 1
|
||||||
|
@17 = private unnamed_addr constant [4 x i8] c"abc\00", align 1
|
||||||
|
@18 = private unnamed_addr constant [4 x i8] c"abd\00", align 1
|
||||||
|
@19 = private unnamed_addr constant [4 x i8] c"abc\00", align 1
|
||||||
|
@20 = private unnamed_addr constant [4 x i8] c"abd\00", align 1
|
||||||
|
@21 = private unnamed_addr constant [4 x i8] c"abc\00", align 1
|
||||||
|
@22 = private unnamed_addr constant [4 x i8] c"abd\00", align 1
|
||||||
|
@23 = private unnamed_addr constant [3 x i8] c"fn\00", align 1
|
||||||
|
|
||||||
|
define double @main.Float64frombits(i64 %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8)
|
||||||
|
store i64 %0, ptr %1, align 4
|
||||||
|
%2 = load double, ptr %1, align 8
|
||||||
|
ret double %2
|
||||||
|
}
|
||||||
|
|
||||||
|
define double @main.Inf(i64 %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = icmp sge i64 %0, 0
|
||||||
|
br i1 %1, label %_llgo_1, label %_llgo_3
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_3, %_llgo_1
|
||||||
|
%2 = phi i64 [ 9218868437227405312, %_llgo_1 ], [ -4503599627370496, %_llgo_3 ]
|
||||||
|
%3 = call double @main.Float64frombits(i64 %2)
|
||||||
|
ret double %3
|
||||||
|
|
||||||
|
_llgo_3: ; preds = %_llgo_0
|
||||||
|
br label %_llgo_2
|
||||||
|
}
|
||||||
|
|
||||||
|
define i1 @main.IsNaN(double %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = fcmp une double %0, %0
|
||||||
|
ret i1 %1
|
||||||
|
}
|
||||||
|
|
||||||
|
define double @main.NaN() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = call double @main.Float64frombits(i64 9221120237041090561)
|
||||||
|
ret double %0
|
||||||
|
}
|
||||||
|
|
||||||
define void @main.demo() {
|
define void @main.demo() {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
@@ -380,13 +434,199 @@ _llgo_0:
|
|||||||
%175 = extractvalue { ptr, ptr } %174, 0
|
%175 = extractvalue { ptr, ptr } %174, 0
|
||||||
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %175)
|
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %175)
|
||||||
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
|
%176 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%177 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %176, i32 0, i32 0
|
||||||
|
store ptr @6, ptr %177, align 8
|
||||||
|
%178 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %176, i32 0, i32 1
|
||||||
|
store i64 7, ptr %178, align 4
|
||||||
|
%179 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %176, align 8
|
||||||
|
%180 = call ptr @"github.com/goplus/llgo/internal/runtime.NewStringIter"(%"github.com/goplus/llgo/internal/runtime.String" %179)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||||
|
%181 = call { i1, i64, i32 } @"github.com/goplus/llgo/internal/runtime.StringIterNext"(ptr %180)
|
||||||
|
%182 = extractvalue { i1, i64, i32 } %181, 0
|
||||||
|
br i1 %182, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1
|
||||||
|
%183 = extractvalue { i1, i64, i32 } %181, 1
|
||||||
|
%184 = extractvalue { i1, i64, i32 } %181, 2
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %183)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
%185 = sext i32 %184 to i64
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %185)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_3: ; preds = %_llgo_1
|
||||||
|
%186 = call double @main.Inf(i64 1)
|
||||||
|
%187 = call double @main.Inf(i64 -1)
|
||||||
|
%188 = call double @main.NaN()
|
||||||
|
%189 = call double @main.NaN()
|
||||||
|
%190 = call i1 @main.IsNaN(double %189)
|
||||||
|
%191 = call i1 @main.IsNaN(double 1.000000e+00)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %186)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %187)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %188)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %190)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %191)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
|
%192 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%193 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %192, i32 0, i32 0
|
||||||
|
store ptr @7, ptr %193, align 8
|
||||||
|
%194 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %192, i32 0, i32 1
|
||||||
|
store i64 7, ptr %194, align 4
|
||||||
|
%195 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %192, align 8
|
||||||
|
%196 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.StringToBytes"(%"github.com/goplus/llgo/internal/runtime.String" %195)
|
||||||
|
%197 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%198 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %197, i32 0, i32 0
|
||||||
|
store ptr @8, ptr %198, align 8
|
||||||
|
%199 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %197, i32 0, i32 1
|
||||||
|
store i64 7, ptr %199, align 4
|
||||||
|
%200 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %197, align 8
|
||||||
|
%201 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.StringToRunes"(%"github.com/goplus/llgo/internal/runtime.String" %200)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %196)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %201)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
|
%202 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromBytes"(%"github.com/goplus/llgo/internal/runtime.Slice" %196)
|
||||||
|
%203 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRunes"(%"github.com/goplus/llgo/internal/runtime.Slice" %201)
|
||||||
|
%204 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %196, 0
|
||||||
|
%205 = getelementptr inbounds i8, ptr %204, i64 3
|
||||||
|
%206 = load i8, ptr %205, align 1
|
||||||
|
%207 = sext i8 %206 to i32
|
||||||
|
%208 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRune"(i32 %207)
|
||||||
|
%209 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %201, 0
|
||||||
|
%210 = getelementptr inbounds i32, ptr %209, i64 0
|
||||||
|
%211 = load i32, ptr %210, align 4
|
||||||
|
%212 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRune"(i32 %211)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %202)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %203)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %208)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %212)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
|
%213 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%214 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %213, i32 0, i32 0
|
||||||
|
store ptr @9, ptr %214, align 8
|
||||||
|
%215 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %213, i32 0, i32 1
|
||||||
|
store i64 3, ptr %215, align 4
|
||||||
|
%216 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %213, align 8
|
||||||
|
%217 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%218 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %217, i32 0, i32 0
|
||||||
|
store ptr @10, ptr %218, align 8
|
||||||
|
%219 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %217, i32 0, i32 1
|
||||||
|
store i64 3, ptr %219, align 4
|
||||||
|
%220 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %217, align 8
|
||||||
|
%221 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %216, %"github.com/goplus/llgo/internal/runtime.String" %220)
|
||||||
|
%222 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%223 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %222, i32 0, i32 0
|
||||||
|
store ptr @11, ptr %223, align 8
|
||||||
|
%224 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %222, i32 0, i32 1
|
||||||
|
store i64 3, ptr %224, align 4
|
||||||
|
%225 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %222, align 8
|
||||||
|
%226 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%227 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %226, i32 0, i32 0
|
||||||
|
store ptr @12, ptr %227, align 8
|
||||||
|
%228 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %226, i32 0, i32 1
|
||||||
|
store i64 3, ptr %228, align 4
|
||||||
|
%229 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %226, align 8
|
||||||
|
%230 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %225, %"github.com/goplus/llgo/internal/runtime.String" %229)
|
||||||
|
%231 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%232 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %231, i32 0, i32 0
|
||||||
|
store ptr @13, ptr %232, align 8
|
||||||
|
%233 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %231, i32 0, i32 1
|
||||||
|
store i64 3, ptr %233, align 4
|
||||||
|
%234 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %231, align 8
|
||||||
|
%235 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%236 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %235, i32 0, i32 0
|
||||||
|
store ptr @14, ptr %236, align 8
|
||||||
|
%237 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %235, i32 0, i32 1
|
||||||
|
store i64 3, ptr %237, align 4
|
||||||
|
%238 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %235, align 8
|
||||||
|
%239 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %234, %"github.com/goplus/llgo/internal/runtime.String" %238)
|
||||||
|
%240 = xor i1 %239, true
|
||||||
|
%241 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%242 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %241, i32 0, i32 0
|
||||||
|
store ptr @15, ptr %242, align 8
|
||||||
|
%243 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %241, i32 0, i32 1
|
||||||
|
store i64 3, ptr %243, align 4
|
||||||
|
%244 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %241, align 8
|
||||||
|
%245 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%246 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %245, i32 0, i32 0
|
||||||
|
store ptr @16, ptr %246, align 8
|
||||||
|
%247 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %245, i32 0, i32 1
|
||||||
|
store i64 3, ptr %247, align 4
|
||||||
|
%248 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %245, align 8
|
||||||
|
%249 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %244, %"github.com/goplus/llgo/internal/runtime.String" %248)
|
||||||
|
%250 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%251 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %250, i32 0, i32 0
|
||||||
|
store ptr @17, ptr %251, align 8
|
||||||
|
%252 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %250, i32 0, i32 1
|
||||||
|
store i64 3, ptr %252, align 4
|
||||||
|
%253 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %250, align 8
|
||||||
|
%254 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%255 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %254, i32 0, i32 0
|
||||||
|
store ptr @18, ptr %255, align 8
|
||||||
|
%256 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %254, i32 0, i32 1
|
||||||
|
store i64 3, ptr %256, align 4
|
||||||
|
%257 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %254, align 8
|
||||||
|
%258 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %257, %"github.com/goplus/llgo/internal/runtime.String" %253)
|
||||||
|
%259 = xor i1 %258, true
|
||||||
|
%260 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%261 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %260, i32 0, i32 0
|
||||||
|
store ptr @19, ptr %261, align 8
|
||||||
|
%262 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %260, i32 0, i32 1
|
||||||
|
store i64 3, ptr %262, align 4
|
||||||
|
%263 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %260, align 8
|
||||||
|
%264 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%265 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %264, i32 0, i32 0
|
||||||
|
store ptr @20, ptr %265, align 8
|
||||||
|
%266 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %264, i32 0, i32 1
|
||||||
|
store i64 3, ptr %266, align 4
|
||||||
|
%267 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %264, align 8
|
||||||
|
%268 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %267, %"github.com/goplus/llgo/internal/runtime.String" %263)
|
||||||
|
%269 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%270 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %269, i32 0, i32 0
|
||||||
|
store ptr @21, ptr %270, align 8
|
||||||
|
%271 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %269, i32 0, i32 1
|
||||||
|
store i64 3, ptr %271, align 4
|
||||||
|
%272 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %269, align 8
|
||||||
|
%273 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
|
%274 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %273, i32 0, i32 0
|
||||||
|
store ptr @22, ptr %274, align 8
|
||||||
|
%275 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %273, i32 0, i32 1
|
||||||
|
store i64 3, ptr %275, align 4
|
||||||
|
%276 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %273, align 8
|
||||||
|
%277 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %272, %"github.com/goplus/llgo/internal/runtime.String" %276)
|
||||||
|
%278 = xor i1 %277, true
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %221)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %230)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %240)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %249)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %259)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %268)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %278)
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
||||||
|
|
||||||
declare void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
declare void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
||||||
@@ -431,7 +671,7 @@ define void @"main.main$1"() {
|
|||||||
_llgo_0:
|
_llgo_0:
|
||||||
%0 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%0 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 0
|
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 0
|
||||||
store ptr @6, ptr %1, align 8
|
store ptr @23, ptr %1, align 8
|
||||||
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 1
|
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 1
|
||||||
store i64 2, ptr %2, align 4
|
store i64 2, ptr %2, align 4
|
||||||
%3 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %0, align 8
|
%3 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %0, align 8
|
||||||
@@ -439,3 +679,21 @@ _llgo_0:
|
|||||||
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare ptr @"github.com/goplus/llgo/internal/runtime.NewStringIter"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
|
declare { i1, i64, i32 } @"github.com/goplus/llgo/internal/runtime.StringIterNext"(ptr)
|
||||||
|
|
||||||
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.StringToBytes"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.StringToRunes"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
|
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromBytes"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
||||||
|
|
||||||
|
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRunes"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
||||||
|
|
||||||
|
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRune"(i32)
|
||||||
|
|
||||||
|
declare i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
|
declare i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ _llgo_2: ; preds = %_llgo_0
|
|||||||
define void @main.cvt32Fto64F(float %0, double %1) {
|
define void @main.cvt32Fto64F(float %0, double %1) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%2 = fpext float %0 to double
|
%2 = fpext float %0 to double
|
||||||
%3 = fcmp one double %2, %1
|
%3 = fcmp une double %2, %1
|
||||||
br i1 %3, label %_llgo_1, label %_llgo_2
|
br i1 %3, label %_llgo_1, label %_llgo_2
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_0
|
_llgo_1: ; preds = %_llgo_0
|
||||||
@@ -198,7 +198,7 @@ _llgo_2: ; preds = %_llgo_0
|
|||||||
define void @main.cvt64Fto32F(double %0, float %1) {
|
define void @main.cvt64Fto32F(double %0, float %1) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%2 = fptrunc double %0 to float
|
%2 = fptrunc double %0 to float
|
||||||
%3 = fcmp one float %2, %1
|
%3 = fcmp une float %2, %1
|
||||||
br i1 %3, label %_llgo_1, label %_llgo_2
|
br i1 %3, label %_llgo_1, label %_llgo_2
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_0
|
_llgo_1: ; preds = %_llgo_0
|
||||||
@@ -227,7 +227,7 @@ _llgo_2: ; preds = %_llgo_0
|
|||||||
define void @main.cvt64Uto64F(i64 %0, double %1) {
|
define void @main.cvt64Uto64F(i64 %0, double %1) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%2 = uitofp i64 %0 to double
|
%2 = uitofp i64 %0 to double
|
||||||
%3 = fcmp one double %2, %1
|
%3 = fcmp une double %2, %1
|
||||||
br i1 %3, label %_llgo_1, label %_llgo_2
|
br i1 %3, label %_llgo_1, label %_llgo_2
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_0
|
_llgo_1: ; preds = %_llgo_0
|
||||||
@@ -256,7 +256,7 @@ _llgo_2: ; preds = %_llgo_0
|
|||||||
define void @main.cvt64to64F(i64 %0, double %1) {
|
define void @main.cvt64to64F(i64 %0, double %1) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%2 = sitofp i64 %0 to double
|
%2 = sitofp i64 %0 to double
|
||||||
%3 = fcmp one double %2, %1
|
%3 = fcmp une double %2, %1
|
||||||
br i1 %3, label %_llgo_1, label %_llgo_2
|
br i1 %3, label %_llgo_1, label %_llgo_2
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_0
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
|||||||
@@ -714,6 +714,12 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
|
|||||||
case *ssa.Extract:
|
case *ssa.Extract:
|
||||||
x := p.compileValue(b, v.Tuple)
|
x := p.compileValue(b, v.Tuple)
|
||||||
ret = b.Extract(x, v.Index)
|
ret = b.Extract(x, v.Index)
|
||||||
|
case *ssa.Range:
|
||||||
|
x := p.compileValue(b, v.X)
|
||||||
|
ret = b.Range(x)
|
||||||
|
case *ssa.Next:
|
||||||
|
iter := p.compileValue(b, v.Iter)
|
||||||
|
ret = b.Next(iter, v.IsString)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("compileInstrAndValue: unknown instr - %T\n", iv))
|
panic(fmt.Sprintf("compileInstrAndValue: unknown instr - %T\n", iv))
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
132
internal/runtime/utf8.go
Normal file
132
internal/runtime/utf8.go
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
// Numbers fundamental to the encoding.
|
||||||
|
const (
|
||||||
|
runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character"
|
||||||
|
runeSelf = 0x80 // characters below runeSelf are represented as themselves in a single byte.
|
||||||
|
maxRune = '\U0010FFFF' // Maximum valid Unicode code point.
|
||||||
|
)
|
||||||
|
|
||||||
|
// Code points in the surrogate range are not valid for UTF-8.
|
||||||
|
const (
|
||||||
|
surrogateMin = 0xD800
|
||||||
|
surrogateMax = 0xDFFF
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
t1 = 0x00 // 0000 0000
|
||||||
|
tx = 0x80 // 1000 0000
|
||||||
|
t2 = 0xC0 // 1100 0000
|
||||||
|
t3 = 0xE0 // 1110 0000
|
||||||
|
t4 = 0xF0 // 1111 0000
|
||||||
|
t5 = 0xF8 // 1111 1000
|
||||||
|
|
||||||
|
maskx = 0x3F // 0011 1111
|
||||||
|
mask2 = 0x1F // 0001 1111
|
||||||
|
mask3 = 0x0F // 0000 1111
|
||||||
|
mask4 = 0x07 // 0000 0111
|
||||||
|
|
||||||
|
rune1Max = 1<<7 - 1
|
||||||
|
rune2Max = 1<<11 - 1
|
||||||
|
rune3Max = 1<<16 - 1
|
||||||
|
|
||||||
|
// The default lowest and highest continuation byte.
|
||||||
|
locb = 0x80 // 1000 0000
|
||||||
|
hicb = 0xBF // 1011 1111
|
||||||
|
)
|
||||||
|
|
||||||
|
// countrunes returns the number of runes in s.
|
||||||
|
// func countrunes(s string) int {
|
||||||
|
// n := 0
|
||||||
|
// for range s {
|
||||||
|
// n++
|
||||||
|
// }
|
||||||
|
// return n
|
||||||
|
// }
|
||||||
|
|
||||||
|
// decoderune returns the non-ASCII rune at the start of
|
||||||
|
// s[k:] and the index after the rune in s.
|
||||||
|
//
|
||||||
|
// decoderune assumes that caller has checked that
|
||||||
|
// the to be decoded rune is a non-ASCII rune.
|
||||||
|
//
|
||||||
|
// If the string appears to be incomplete or decoding problems
|
||||||
|
// are encountered (runeerror, k + 1) is returned to ensure
|
||||||
|
// progress when decoderune is used to iterate over a string.
|
||||||
|
func decoderune(s string, k int) (r rune, pos int) {
|
||||||
|
pos = k
|
||||||
|
|
||||||
|
if k >= len(s) {
|
||||||
|
return runeError, k + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s[k:]
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case t2 <= s[0] && s[0] < t3:
|
||||||
|
// 0080-07FF two byte sequence
|
||||||
|
if len(s) > 1 && (locb <= s[1] && s[1] <= hicb) {
|
||||||
|
r = rune(s[0]&mask2)<<6 | rune(s[1]&maskx)
|
||||||
|
pos += 2
|
||||||
|
if rune1Max < r {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case t3 <= s[0] && s[0] < t4:
|
||||||
|
// 0800-FFFF three byte sequence
|
||||||
|
if len(s) > 2 && (locb <= s[1] && s[1] <= hicb) && (locb <= s[2] && s[2] <= hicb) {
|
||||||
|
r = rune(s[0]&mask3)<<12 | rune(s[1]&maskx)<<6 | rune(s[2]&maskx)
|
||||||
|
pos += 3
|
||||||
|
if rune2Max < r && !(surrogateMin <= r && r <= surrogateMax) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case t4 <= s[0] && s[0] < t5:
|
||||||
|
// 10000-1FFFFF four byte sequence
|
||||||
|
if len(s) > 3 && (locb <= s[1] && s[1] <= hicb) && (locb <= s[2] && s[2] <= hicb) && (locb <= s[3] && s[3] <= hicb) {
|
||||||
|
r = rune(s[0]&mask4)<<18 | rune(s[1]&maskx)<<12 | rune(s[2]&maskx)<<6 | rune(s[3]&maskx)
|
||||||
|
pos += 4
|
||||||
|
if rune3Max < r && r <= maxRune {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return runeError, k + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// encoderune writes into p (which must be large enough) the UTF-8 encoding of the rune.
|
||||||
|
// It returns the number of bytes written.
|
||||||
|
func encoderune(p []byte, r rune) int {
|
||||||
|
// Negative values are erroneous. Making it unsigned addresses the problem.
|
||||||
|
switch i := uint32(r); {
|
||||||
|
case i <= rune1Max:
|
||||||
|
p[0] = byte(r)
|
||||||
|
return 1
|
||||||
|
case i <= rune2Max:
|
||||||
|
_ = p[1] // eliminate bounds checks
|
||||||
|
p[0] = t2 | byte(r>>6)
|
||||||
|
p[1] = tx | byte(r)&maskx
|
||||||
|
return 2
|
||||||
|
case i > maxRune, surrogateMin <= i && i <= surrogateMax:
|
||||||
|
r = runeError
|
||||||
|
fallthrough
|
||||||
|
case i <= rune3Max:
|
||||||
|
_ = p[2] // eliminate bounds checks
|
||||||
|
p[0] = t3 | byte(r>>12)
|
||||||
|
p[1] = tx | byte(r>>6)&maskx
|
||||||
|
p[2] = tx | byte(r)&maskx
|
||||||
|
return 3
|
||||||
|
default:
|
||||||
|
_ = p[3] // eliminate bounds checks
|
||||||
|
p[0] = t4 | byte(r>>18)
|
||||||
|
p[1] = tx | byte(r>>12)&maskx
|
||||||
|
p[2] = tx | byte(r>>6)&maskx
|
||||||
|
p[3] = tx | byte(r)&maskx
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -70,4 +70,119 @@ func NewStringSlice(base String, i, j int) String {
|
|||||||
return String{nil, 0}
|
return String{nil, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StringIter struct {
|
||||||
|
s string
|
||||||
|
pos int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStringIter(s string) *StringIter {
|
||||||
|
return &StringIter{s, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringIterNext(it *StringIter) (ok bool, k int, v rune) {
|
||||||
|
if it.pos >= len(it.s) {
|
||||||
|
return false, 0, 0
|
||||||
|
}
|
||||||
|
k = it.pos
|
||||||
|
if c := it.s[it.pos]; c < runeSelf {
|
||||||
|
it.pos++
|
||||||
|
v = rune(c)
|
||||||
|
} else {
|
||||||
|
v, it.pos = decoderune(it.s, it.pos)
|
||||||
|
}
|
||||||
|
ok = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringToBytes(s String) []byte {
|
||||||
|
if s.len == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
data := make([]byte, s.len)
|
||||||
|
c.Memcpy(unsafe.Pointer(&data[0]), s.data, uintptr(s.len))
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringToRunes(s string) []rune {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
data := make([]rune, len(s))
|
||||||
|
var index uint
|
||||||
|
for i := 0; i < len(s); {
|
||||||
|
if c := s[i]; c < runeSelf {
|
||||||
|
data[index] = rune(c)
|
||||||
|
i++
|
||||||
|
} else {
|
||||||
|
data[index], i = decoderune(s, i)
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
return data[:index:index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringFromBytes(b Slice) (s String) {
|
||||||
|
if b.len == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.len = b.len
|
||||||
|
s.data = AllocU(uintptr(s.len))
|
||||||
|
c.Memcpy(s.data, b.data, uintptr(b.len))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringFromRunes(rs []rune) (s String) {
|
||||||
|
if len(rs) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data := make([]byte, len(rs)*4)
|
||||||
|
var index int
|
||||||
|
for _, r := range rs {
|
||||||
|
n := encoderune(data[index:], r)
|
||||||
|
index += n
|
||||||
|
}
|
||||||
|
s.len = index
|
||||||
|
s.data = unsafe.Pointer(&data[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringFromRune(r rune) (s String) {
|
||||||
|
var buf [4]byte
|
||||||
|
n := encoderune(buf[:], r)
|
||||||
|
s.len = n
|
||||||
|
s.data = unsafe.Pointer(&buf[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringEqual(x, y String) bool {
|
||||||
|
if x.len != y.len {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if x.data != y.data {
|
||||||
|
for i := 0; i < x.len; i++ {
|
||||||
|
if *(*byte)(c.Advance(x.data, i)) != *(*byte)(c.Advance(y.data, i)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringLess(x, y String) bool {
|
||||||
|
n := x.len
|
||||||
|
if n > y.len {
|
||||||
|
n = y.len
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
ix := *(*byte)(c.Advance(x.data, i))
|
||||||
|
iy := *(*byte)(c.Advance(y.data, i))
|
||||||
|
if ix < iy {
|
||||||
|
return true
|
||||||
|
} else if ix > iy {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x.len < y.len
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
102
ssa/expr.go
102
ssa/expr.go
@@ -315,7 +315,7 @@ var uintPredOpToLLVM = []llvm.IntPredicate{
|
|||||||
|
|
||||||
var floatPredOpToLLVM = []llvm.FloatPredicate{
|
var floatPredOpToLLVM = []llvm.FloatPredicate{
|
||||||
token.EQL - predOpBase: llvm.FloatOEQ,
|
token.EQL - predOpBase: llvm.FloatOEQ,
|
||||||
token.NEQ - predOpBase: llvm.FloatONE,
|
token.NEQ - predOpBase: llvm.FloatUNE,
|
||||||
token.LSS - predOpBase: llvm.FloatOLT,
|
token.LSS - predOpBase: llvm.FloatOLT,
|
||||||
token.LEQ - predOpBase: llvm.FloatOLE,
|
token.LEQ - predOpBase: llvm.FloatOLE,
|
||||||
token.GTR - predOpBase: llvm.FloatOGT,
|
token.GTR - predOpBase: llvm.FloatOGT,
|
||||||
@@ -405,7 +405,26 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
|
|||||||
pred := boolPredOpToLLVM[op-predOpBase]
|
pred := boolPredOpToLLVM[op-predOpBase]
|
||||||
return Expr{llvm.CreateICmp(b.impl, pred, x.impl, y.impl), tret}
|
return Expr{llvm.CreateICmp(b.impl, pred, x.impl, y.impl), tret}
|
||||||
case vkString, vkComplex:
|
case vkString, vkComplex:
|
||||||
panic("todo")
|
switch op {
|
||||||
|
case token.EQL:
|
||||||
|
return b.InlineCall(b.Pkg.rtFunc("StringEqual"), x, y)
|
||||||
|
case token.NEQ:
|
||||||
|
ret := b.InlineCall(b.Pkg.rtFunc("StringEqual"), x, y)
|
||||||
|
ret.impl = llvm.CreateNot(b.impl, ret.impl)
|
||||||
|
return ret
|
||||||
|
case token.LSS:
|
||||||
|
return b.InlineCall(b.Pkg.rtFunc("StringLess"), x, y)
|
||||||
|
case token.LEQ:
|
||||||
|
ret := b.InlineCall(b.Pkg.rtFunc("StringLess"), y, x)
|
||||||
|
ret.impl = llvm.CreateNot(b.impl, ret.impl)
|
||||||
|
return ret
|
||||||
|
case token.GTR:
|
||||||
|
return b.InlineCall(b.Pkg.rtFunc("StringLess"), y, x)
|
||||||
|
case token.GEQ:
|
||||||
|
ret := b.InlineCall(b.Pkg.rtFunc("StringLess"), x, y)
|
||||||
|
ret.impl = llvm.CreateNot(b.impl, ret.impl)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic("todo")
|
panic("todo")
|
||||||
@@ -833,6 +852,27 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
|
|||||||
case types.UnsafePointer:
|
case types.UnsafePointer:
|
||||||
ret.impl = castPtr(b.impl, x.impl, t.ll)
|
ret.impl = castPtr(b.impl, x.impl, t.ll)
|
||||||
return
|
return
|
||||||
|
case types.String:
|
||||||
|
switch xtyp := x.RawType().Underlying().(type) {
|
||||||
|
case *types.Slice:
|
||||||
|
if etyp, ok := xtyp.Elem().Underlying().(*types.Basic); ok {
|
||||||
|
switch etyp.Kind() {
|
||||||
|
case types.Byte:
|
||||||
|
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("StringFromBytes"), x).impl
|
||||||
|
return
|
||||||
|
case types.Rune:
|
||||||
|
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("StringFromRunes"), x).impl
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case *types.Basic:
|
||||||
|
if x.Type != b.Prog.Int32() {
|
||||||
|
x.Type = b.Prog.Int32()
|
||||||
|
x.impl = castInt(b, x.impl, b.Prog.Int32())
|
||||||
|
}
|
||||||
|
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("StringFromRune"), x).impl
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch xtyp := x.RawType().Underlying().(type) {
|
switch xtyp := x.RawType().Underlying().(type) {
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
@@ -867,6 +907,19 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
|
|||||||
case *types.Pointer:
|
case *types.Pointer:
|
||||||
ret.impl = castPtr(b.impl, x.impl, t.ll)
|
ret.impl = castPtr(b.impl, x.impl, t.ll)
|
||||||
return
|
return
|
||||||
|
case *types.Slice:
|
||||||
|
if x.kind == vkString {
|
||||||
|
if etyp, ok := typ.Elem().Underlying().(*types.Basic); ok {
|
||||||
|
switch etyp.Kind() {
|
||||||
|
case types.Byte:
|
||||||
|
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("StringToBytes"), x).impl
|
||||||
|
return
|
||||||
|
case types.Rune:
|
||||||
|
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("StringToRunes"), x).impl
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
@@ -969,6 +1022,51 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The Range instruction yields an iterator over the domain and range
|
||||||
|
// of X, which must be a string or map.
|
||||||
|
//
|
||||||
|
// Elements are accessed via Next.
|
||||||
|
//
|
||||||
|
// Type() returns an opaque and degenerate "rangeIter" type.
|
||||||
|
//
|
||||||
|
// Pos() returns the ast.RangeStmt.For.
|
||||||
|
//
|
||||||
|
// Example printed form:
|
||||||
|
//
|
||||||
|
// t0 = range "hello":string
|
||||||
|
func (b Builder) Range(x Expr) Expr {
|
||||||
|
switch x.kind {
|
||||||
|
case vkString:
|
||||||
|
return b.InlineCall(b.Pkg.rtFunc("NewStringIter"), x)
|
||||||
|
}
|
||||||
|
panic("todo")
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Next instruction reads and advances the (map or string)
|
||||||
|
// iterator Iter and returns a 3-tuple value (ok, k, v). If the
|
||||||
|
// iterator is not exhausted, ok is true and k and v are the next
|
||||||
|
// elements of the domain and range, respectively. Otherwise ok is
|
||||||
|
// false and k and v are undefined.
|
||||||
|
//
|
||||||
|
// Components of the tuple are accessed using Extract.
|
||||||
|
//
|
||||||
|
// The IsString field distinguishes iterators over strings from those
|
||||||
|
// over maps, as the Type() alone is insufficient: consider
|
||||||
|
// map[int]rune.
|
||||||
|
//
|
||||||
|
// Type() returns a *types.Tuple for the triple (ok, k, v).
|
||||||
|
// The types of k and/or v may be types.Invalid.
|
||||||
|
//
|
||||||
|
// Example printed form:
|
||||||
|
//
|
||||||
|
// t1 = next t0
|
||||||
|
func (b Builder) Next(iter Expr, isString bool) (ret Expr) {
|
||||||
|
if isString {
|
||||||
|
return b.InlineCall(b.Pkg.rtFunc("StringIterNext"), iter)
|
||||||
|
}
|
||||||
|
panic("todo")
|
||||||
|
}
|
||||||
|
|
||||||
// A Builtin represents a specific use of a built-in function, e.g. len.
|
// A Builtin represents a specific use of a built-in function, e.g. len.
|
||||||
//
|
//
|
||||||
// Builtins are immutable values. Builtins do not have addresses.
|
// Builtins are immutable values. Builtins do not have addresses.
|
||||||
|
|||||||
Reference in New Issue
Block a user