mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-19 16:40:26 +02:00
Initial const eval feature release
This commit is contained in:
parent
be929c3626
commit
ff1f8aff3f
27 changed files with 887 additions and 178 deletions
159
IDEHelper/Tests/src/ConstEval.bf
Normal file
159
IDEHelper/Tests/src/ConstEval.bf
Normal file
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class ConstEval
|
||||
{
|
||||
struct StructA
|
||||
{
|
||||
public int32 mA;
|
||||
public int32 mB;
|
||||
|
||||
public static int32 sVal = 1000;
|
||||
|
||||
public this(int32 a, int32 b)
|
||||
{
|
||||
mA = a + sVal;
|
||||
mB = b;
|
||||
}
|
||||
}
|
||||
|
||||
const String cStrA = "Abc";
|
||||
const String cStrB = GetStringA(cStrA, 12, 23);
|
||||
|
||||
[ConstEval]
|
||||
static String GetStringA(String str, int a, int b)
|
||||
{
|
||||
// Const-eval functions can return scope-allocated data
|
||||
return scope $"{str}:{a}:{b}";
|
||||
}
|
||||
|
||||
static int32 Factorial(int32 n)
|
||||
{
|
||||
return n <= 1 ? 1 : (n * Factorial(n - 1));
|
||||
}
|
||||
|
||||
static int32 Fibonacci(int32 n)
|
||||
{
|
||||
return n <= 1 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);
|
||||
}
|
||||
|
||||
public static String GetTypeDesc<T>()
|
||||
{
|
||||
String str = scope .();
|
||||
|
||||
T val = default;
|
||||
val.GetType().GetFullName(str);
|
||||
str.Append(" ");
|
||||
|
||||
for (var fieldInfo in typeof(T).GetFields())
|
||||
{
|
||||
if (!fieldInfo.IsInstanceField)
|
||||
continue;
|
||||
if (@fieldInfo.Index > 0)
|
||||
str.Append(", ");
|
||||
fieldInfo.FieldType.GetFullName(str);
|
||||
str.Append(" ");
|
||||
str.Append(fieldInfo.Name);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public static Span<int32> GetSorted(String numList)
|
||||
{
|
||||
List<int32> list = scope .();
|
||||
for (var sv in numList.Split(','))
|
||||
{
|
||||
sv.Trim();
|
||||
if (int32.Parse(sv) case .Ok(let val))
|
||||
list.Add(val);
|
||||
}
|
||||
list.Sort();
|
||||
return list;
|
||||
}
|
||||
|
||||
public static int32 MethodA()
|
||||
{
|
||||
mixin Add10(var a)
|
||||
{
|
||||
a += 10
|
||||
}
|
||||
|
||||
int32 a = 1;
|
||||
|
||||
void Inc()
|
||||
{
|
||||
a++;
|
||||
}
|
||||
|
||||
for (int i < 2)
|
||||
{
|
||||
defer { a *= 2; }
|
||||
Inc();
|
||||
Add10!(a);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// This method can only be const evaluated
|
||||
[ConstEval]
|
||||
public static int32 ConstSum(params int32[] vals)
|
||||
{
|
||||
int32 sum = 0;
|
||||
for (let val in vals)
|
||||
sum += val;
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static int32 MethodB()
|
||||
{
|
||||
// Returns different results depending on whether we are const-evaluating
|
||||
return Compiler.IsConstEval ? 1 : 0;
|
||||
}
|
||||
|
||||
public static int32 MethodC(StructA sa = .(1, 2), (int32, int32) tup = (20, 30), int32[2] arr = .(300, 400))
|
||||
{
|
||||
return sa.mA + sa.mB + tup.0 + tup.1 + arr[0] + arr[1];
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
const int fac = Factorial(8);
|
||||
Test.Assert(fac == 40320);
|
||||
const int fib = Fibonacci(27);
|
||||
Test.Assert(fib == 196418);
|
||||
|
||||
// Generated string has reference equality to equivalent literal
|
||||
Test.Assert(cStrB === "Abc:12:23");
|
||||
|
||||
const String strC = GetTypeDesc<StructA>();
|
||||
Test.Assert(strC === "Tests.ConstEval.StructA int32 mA, int32 mB");
|
||||
|
||||
// Const Span<T> results can be used to initialize statically-sized arrays
|
||||
const int32[?] iArr = GetSorted("8, 1, 3, 7");
|
||||
Compiler.Assert(iArr == .(1, 3, 7, 8));
|
||||
Test.Assert(iArr == .(1, 3, 7, 8));
|
||||
|
||||
let val0 = [ConstEval]MethodA();
|
||||
Compiler.Assert(val0 == 70);
|
||||
let val1 = MethodA();
|
||||
// 'val1' is a read-only variable, but not const, so the following line would fail
|
||||
//Compiler.Assert(val1 == 24);
|
||||
Test.Assert(val1 == 70);
|
||||
|
||||
// This method is marked as ConstEval so it always evaluates as const
|
||||
let val2 = ConstSum(3, 20, 100);
|
||||
Compiler.Assert(val2 == 123);
|
||||
|
||||
Test.Assert(MethodB() == 0);
|
||||
Test.Assert([ConstEval]MethodB() == 1);
|
||||
|
||||
Test.Assert(MethodC() == 1753);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue