fspl/generator/function_test.go

273 lines
7.2 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] 'exit'
[main] 'main' = [exit 1]
`)
}
func TestFunctionCall (test *testing.T) {
testString (test,
`define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::f"() {
0:
%1 = call i64 @"0zNZN147MN2wzMAQ6NS2dQ==::g"(i64 5)
ret i64 %1
}
define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::g"(i64 %x) {
0:
%1 = alloca i64
store i64 %x, ptr %1
%2 = load i64, ptr %1
%3 = call i64 @"0zNZN147MN2wzMAQ6NS2dQ==::h"(i64 %2)
ret i64 %3
}
define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::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 @"0zNZN147MN2wzMAQ6NS2dQ==::f"() {
0:
%1 = call i64 @"0zNZN147MN2wzMAQ6NS2dQ==::g"(i64 5)
call void @"0zNZN147MN2wzMAQ6NS2dQ==::h"()
%2 = call i64 @"0zNZN147MN2wzMAQ6NS2dQ==::g"(i64 6)
ret void
}
define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::g"(i64 %x) {
0:
%1 = alloca i64
store i64 %x, ptr %1
%2 = load i64, ptr %1
ret i64 %2
}
define void @"0zNZN147MN2wzMAQ6NS2dQ==::h"() {
0:
ret void
}
`,
`
[f] = { [g 5] [h] [g 6] }
[g x:Int]:Int = x
[h] = { }
`)
}
func TestMethod (test *testing.T) {
testString (test,
`%"0zNZN147MN2wzMAQ6NS2dQ==::Number" = type i64
define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::main"() {
0:
%1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Number"
store i64 5, ptr %1
%2 = call i64 @"0zNZN147MN2wzMAQ6NS2dQ==::Number.number"(ptr %1)
ret i64 %2
}
define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::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 TestMethodPtr (test *testing.T) {
testString (test,
`%"0zNZN147MN2wzMAQ6NS2dQ==::Number" = type i64
define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::main"() {
0:
%1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Number"
store i64 5, ptr %1
%2 = alloca ptr
store ptr %1, ptr %2
%3 = load ptr, ptr %2
%4 = call i64 @"0zNZN147MN2wzMAQ6NS2dQ==::Number.number"(ptr %3)
ret i64 %4
}
define i64 @"0zNZN147MN2wzMAQ6NS2dQ==::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
numptr:*Number = [@num]
numptr.[number]
}
`)
}
func TestMethodChained (test *testing.T) {
testString (test,
`%"0zNZN147MN2wzMAQ6NS2dQ==::Number" = type i64
define %"0zNZN147MN2wzMAQ6NS2dQ==::Number" @"0zNZN147MN2wzMAQ6NS2dQ==::main"() {
0:
%1 = alloca i64
store i64 5, ptr %1
%2 = call %"0zNZN147MN2wzMAQ6NS2dQ==::Number" @"0zNZN147MN2wzMAQ6NS2dQ==::Number.add"(ptr %1, i64 8)
%3 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Number"
store %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %2, ptr %3
%4 = call %"0zNZN147MN2wzMAQ6NS2dQ==::Number" @"0zNZN147MN2wzMAQ6NS2dQ==::Number.mul"(ptr %3, i64 3)
ret %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %4
}
define %"0zNZN147MN2wzMAQ6NS2dQ==::Number" @"0zNZN147MN2wzMAQ6NS2dQ==::Number.mul"(ptr %this, %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %x) {
0:
%1 = alloca ptr
store ptr %this, ptr %1
%2 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Number"
store %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %x, ptr %2
%3 = load ptr, ptr %1
%4 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Number", ptr %3
%5 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Number", ptr %2
%6 = mul %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %4, %5
ret %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %6
}
define %"0zNZN147MN2wzMAQ6NS2dQ==::Number" @"0zNZN147MN2wzMAQ6NS2dQ==::Number.add"(ptr %this, %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %x) {
0:
%1 = alloca ptr
store ptr %this, ptr %1
%2 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Number"
store %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %x, ptr %2
%3 = load ptr, ptr %1
%4 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Number", ptr %3
%5 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Number", ptr %2
%6 = add %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %4, %5
ret %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %6
}
define %"0zNZN147MN2wzMAQ6NS2dQ==::Number" @"0zNZN147MN2wzMAQ6NS2dQ==::Number.div"(ptr %this, %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %x) {
0:
%1 = alloca ptr
store ptr %this, ptr %1
%2 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Number"
store %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %x, ptr %2
%3 = load ptr, ptr %1
%4 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Number", ptr %3
%5 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Number", ptr %2
%6 = sdiv %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %4, %5
ret %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %6
}
define %"0zNZN147MN2wzMAQ6NS2dQ==::Number" @"0zNZN147MN2wzMAQ6NS2dQ==::Number.sub"(ptr %this, %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %x) {
0:
%1 = alloca ptr
store ptr %this, ptr %1
%2 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Number"
store %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %x, ptr %2
%3 = load ptr, ptr %1
%4 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Number", ptr %3
%5 = load %"0zNZN147MN2wzMAQ6NS2dQ==::Number", ptr %2
%6 = sub %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %4, %5
ret %"0zNZN147MN2wzMAQ6NS2dQ==::Number" %6
}
`,
`
Number: Int
Number.[add x:Number]:Number = [+ [.this] x]
Number.[sub x:Number]:Number = [- [.this] x]
Number.[mul x:Number]:Number = [* [.this] x]
Number.[div x:Number]:Number = [/ [.this] x]
[main]: Number = [~Number 5].[add 8].[mul 3]
`)
}
func TestMethodGreeter (test *testing.T) {
testString (test,
`%"AAAAAAAAAAAAAAAAAAAAAA==::Index" = type i64
%"AAAAAAAAAAAAAAAAAAAAAA==::String" = type { ptr, %"AAAAAAAAAAAAAAAAAAAAAA==::Index" }
%"0zNZN147MN2wzMAQ6NS2dQ==::Greeter" = type { %"AAAAAAAAAAAAAAAAAAAAAA==::String" }
define void @main() {
0:
%1 = alloca %"0zNZN147MN2wzMAQ6NS2dQ==::Greeter"
%2 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Greeter", ptr %1, i32 0, i32 0
%3 = alloca [6 x i8]
%4 = getelementptr [6 x i8], ptr %3, i32 0, i32 0
store i8 104, ptr %4
%5 = getelementptr [6 x i8], ptr %3, i32 0, i32 1
store i8 101, ptr %5
%6 = getelementptr [6 x i8], ptr %3, i32 0, i32 2
store i8 108, ptr %6
%7 = getelementptr [6 x i8], ptr %3, i32 0, i32 3
store i8 108, ptr %7
%8 = getelementptr [6 x i8], ptr %3, i32 0, i32 4
store i8 111, ptr %8
%9 = getelementptr [6 x i8], ptr %3, i32 0, i32 5
store i8 0, ptr %9
%10 = getelementptr %"AAAAAAAAAAAAAAAAAAAAAA==::String", ptr %2, i32 0, i32 0
store ptr %3, ptr %10
%11 = getelementptr %"AAAAAAAAAAAAAAAAAAAAAA==::String", ptr %2, i32 0, i32 1
store %"AAAAAAAAAAAAAAAAAAAAAA==::Index" 6, ptr %11
call void @"0zNZN147MN2wzMAQ6NS2dQ==::Greeter.greet"(ptr %1)
ret void
}
define void @"0zNZN147MN2wzMAQ6NS2dQ==::Greeter.greet"(ptr %this) {
0:
%1 = alloca ptr
store ptr %this, ptr %1
%2 = load ptr, ptr %1
%3 = getelementptr %"0zNZN147MN2wzMAQ6NS2dQ==::Greeter", ptr %2, i32 0, i32 0
%4 = getelementptr %"AAAAAAAAAAAAAAAAAAAAAA==::String", ptr %3, i32 0, i32 0
%5 = load ptr, ptr %4
%6 = getelementptr i8, ptr %5, i64 0
%7 = call %"AAAAAAAAAAAAAAAAAAAAAA==::Index" @puts(ptr %6)
ret void
}
declare %"AAAAAAAAAAAAAAAAAAAAAA==::Index" @puts(ptr %string)
`,
`
[puts string: *Byte]: Index 'puts'
Greeter: (. message: String)
Greeter.[greet] = [puts [@[.this.message 0]]]
[main] 'main' = {
greeter: Greeter = (.
message: 'hello\0'
)
greeter.[greet]
}
`)
}