fspl/generator/function_test.go

171 lines
3.0 KiB
Go

package generator
import "testing"
func TestFunctionExternal (test *testing.T) {
testString (test,
`declare void @exit(i64 %status)
define void @main() {
0:
call void @exit(i64 1)
ret void
}
`,
`
[exit status:Int]
[main] = [exit 1]
`)
}
func TestFunctionCall (test *testing.T) {
testString (test,
`define i64 @f() {
0:
%1 = call i64 @g(i64 5)
ret i64 %1
}
define i64 @g(i64 %x) {
0:
%1 = alloca i64
store i64 %x, ptr %1
%2 = load i64, ptr %1
%3 = call i64 @h(i64 %2)
ret i64 %3
}
define i64 @h(i64 %x) {
0:
%1 = alloca i64
store i64 %x, ptr %1
%2 = load i64, ptr %1
ret i64 %2
}
`,
`
[f ]:Int = [g 5]
[g x:Int]:Int = [h x]
[h x:Int]:Int = x
`)
}
func TestFunctionCallVoid (test *testing.T) {
testString (test,
`define void @f() {
0:
%1 = call i64 @g(i64 5)
call void @h()
%2 = call i64 @g(i64 6)
ret void
}
define i64 @g(i64 %x) {
0:
%1 = alloca i64
store i64 %x, ptr %1
%2 = load i64, ptr %1
ret i64 %2
}
define void @h() {
0:
ret void
}
`,
`
[f] = { [g 5] [h] [g 6] }
[g x:Int]:Int = x
[h] = { }
`)
}
func TestMethod (test *testing.T) {
testString (test,
`%Number = type i64
define i64 @main() {
0:
%1 = alloca %Number
store i64 5, ptr %1
%2 = call i64 @Number.number(ptr %1)
ret i64 %2
}
define i64 @Number.number(ptr %this) {
0:
%1 = alloca ptr
store ptr %this, ptr %1
%2 = load ptr, ptr %1
%3 = load i64, ptr %2
ret i64 %3
}
`,
`
Number: Int
Number.[number]: Int = [.this]
[main]: Int = {
num:Number = 5
num.[number]
}
`)
}
func TestMethodGreeter (test *testing.T) {
testString (test,
`%Index = type i64
%String = type { ptr, %Index }
%Greeter = type { %String }
define void @main() {
0:
%1 = alloca { %String }
%2 = alloca [6 x i8]
%3 = getelementptr [6 x i8], ptr %2, i32 0, i32 0
store i8 104, ptr %3
%4 = getelementptr [6 x i8], ptr %2, i32 0, i32 1
store i8 101, ptr %4
%5 = getelementptr [6 x i8], ptr %2, i32 0, i32 2
store i8 108, ptr %5
%6 = getelementptr [6 x i8], ptr %2, i32 0, i32 3
store i8 108, ptr %6
%7 = getelementptr [6 x i8], ptr %2, i32 0, i32 4
store i8 111, ptr %7
%8 = getelementptr [6 x i8], ptr %2, i32 0, i32 5
store i8 0, ptr %8
%9 = alloca { ptr, %Index }
%10 = getelementptr { ptr, %Index }, ptr %9, i32 0, i32 0
store ptr %2, ptr %10
%11 = getelementptr { ptr, %Index }, ptr %9, i32 0, i32 1
store %Index 6, ptr %11
%12 = load %String, ptr %9
%13 = getelementptr { %String }, ptr %1, i32 0, i32 0
store %String %12, ptr %13
%14 = load %Greeter, ptr %1
%15 = alloca %Greeter
store %Greeter %14, ptr %15
call void @Greeter.greet(ptr %15)
ret void
}
define void @Greeter.greet(ptr %this) {
0:
%1 = alloca ptr
store ptr %this, ptr %1
%2 = load ptr, ptr %1
%3 = getelementptr { %String }, ptr %2, i32 0, i32 0
%4 = getelementptr { ptr, %Index }, ptr %3, i32 0, i32 0
%5 = load ptr, ptr %4
%6 = getelementptr i8, ptr %5, i64 0
%7 = call %Index @puts(ptr %6)
ret void
}
declare %Index @puts(ptr %string)
`,
`
[puts string: *Byte]: Index
Greeter: (message: String)
Greeter.[greet] = [puts [@[.this.message 0]]]
[main] = {
greeter: Greeter = (
message: 'hello\0'
)
greeter.[greet]
}
`)
}