1 /// Copyright: Copyright (c) 2017-2020 Andrey Penechko. 2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 3 /// Authors: Andrey Penechko. 4 module tests.ctfe; 5 6 import tester; 7 8 Test[] ctfeTests() { return collectTests!(tests.ctfe)(); } 9 10 11 @TestInfo(&tester1) 12 immutable ctfe1 = q{--- ctfe1 13 // Simplest case 14 i32 func() { return 42; } 15 enum i32 val = func(); // CTFE is performed at IR gen of `run`, `func` already has IR 16 i32 run() { 17 return val; // returns 42 18 } 19 }; 20 void tester1(ref TestContext ctx) { 21 assert(ctx.getFunctionPtr!(int)("run")() == 42); 22 } 23 24 25 @TestInfo(&tester2) 26 immutable ctfe2 = q{--- ctfe2 27 // Parameter and vreg 28 i32 func(i32 param) { return param; } 29 enum i32 val = func(42); // CTFE 30 i32 run() { 31 return val; // returns 42 32 } 33 }; 34 void tester2(ref TestContext ctx) { 35 assert(ctx.getFunctionPtr!(int)("run")() == 42); 36 } 37 38 39 @TestInfo(&tester3) 40 immutable ctfe3 = q{--- ctfe3 41 // add 42 i32 func(i32 param) { return param + param; } 43 enum i32 val = func(42); // CTFE 44 i32 run() { 45 return val; // returns 84 46 } 47 }; 48 void tester3(ref TestContext ctx) { 49 assert(ctx.getFunctionPtr!(int)("run")() == 84); 50 } 51 52 53 @TestInfo(&tester4) 54 immutable ctfe4 = q{--- ctfe4 55 // control flow 56 i32 sign(i32 number) { 57 i32 result; 58 if (number < 0) result = -1; 59 else if (number > 0) result = 1; 60 else result = 0; 61 return result; 62 } 63 enum i32 val0 = sign(-1); // CTFE 64 enum i32 val1 = sign( 0); // CTFE 65 enum i32 val2 = sign( 1); // CTFE 66 i32 get_val0() { return val0; } // -1 67 i32 get_val1() { return val1; } // 0 68 i32 get_val2() { return val2; } // 1 69 }; 70 void tester4(ref TestContext ctx) { 71 assert(ctx.getFunctionPtr!(int)("get_val0")() == -1); 72 assert(ctx.getFunctionPtr!(int)("get_val1")() == 0); 73 assert(ctx.getFunctionPtr!(int)("get_val2")() == 1); 74 } 75 76 77 @TestInfo(&tester5) 78 immutable ctfe5 = q{--- ctfe5 79 // call 80 i32 fib(i32 number) { 81 if (number < 1) return 0; 82 if (number < 3) return 1; 83 return fib(number-1) + fib(number-2); 84 } 85 // loop 86 i32 fib2(i32 number) { 87 i32 lo = 0; 88 i32 hi = 1; 89 for (i32 i = 0; i < number; ++i) { 90 hi = hi + lo; 91 lo = hi - lo; 92 } 93 return lo; 94 } 95 96 i32 get() { 97 enum i32 val = fib(6); // CTFE 98 return val; // 8 99 } 100 101 i32 get2() { 102 enum i32 val = fib2(30); // CTFE 103 return val; // 8 104 } 105 }; 106 void tester5(ref TestContext ctx) { 107 assert(ctx.getFunctionPtr!(int)("get")() == 8); 108 assert(ctx.getFunctionPtr!(int)("get2")() == 832040); 109 } 110 111 @TestInfo(&tester6) 112 immutable ctfe6 = q{--- ctfe6 113 i64 fib(i64 number) { 114 i64 lo = 0; 115 i64 hi = 1; 116 for (i64 i = 0; i < number; ++i) { 117 hi = hi + lo; 118 lo = hi - lo; 119 } 120 return lo; 121 } 122 enum i64 val = fib(62); // CTFE 123 i64 get() { return val; } 124 }; 125 void tester6(ref TestContext ctx) { 126 assert(ctx.getFunctionPtr!(long)("get")() == 4052739537881UL); 127 }