1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-27 20:18:01 +02:00

Initial checkin

This commit is contained in:
Brian Fiete 2019-08-23 11:56:54 -07:00
parent c74712dad9
commit 078564ac9e
3242 changed files with 1616395 additions and 0 deletions

View file

@ -0,0 +1,115 @@
#pragma warning disable 168
using System;
namespace Tests
{
class Append
{
class ClassA
{
int32 mA = 0x11223344;
[AllowAppend]
public this()
{
uint8* ptr = append uint8[3]*;
ptr[0] = 0x55;
ptr[1] = 0x66;
ptr[2] = 0x77;
}
}
class ClassB
{
[AllowAppend]
public this(int16 i, int32 j)
{
uint8* ptr = append uint8[i]*;
for (int k < i)
ptr[k] = (uint8)(0xA0 | k);
}
}
class ClassC : ClassB
{
public static int sCallCount;
static int GetIntVal()
{
sCallCount++;
return 123;
}
[AllowAppend]
public this(int16 i) : base(i, (int32)GetIntVal())
{
uint32* val = append uint32[2]*;
val[0] = 0x11223344;
val[1] = 0x55667788;
}
}
class ClassD
{
int16 mA = 0x1122;
[AllowAppend]
public this()
{
uint32* val = append uint32[1]*;
uint8* val2 = append uint8[1]*;
val[0] = 0x33445566;
//Foof();
val2[0] = 0xBB;
}
}
class ClassE : ClassD
{
[AllowAppend]
public this()
{
uint64* val = append uint64[1]*;
val[0] = 0x1020304050607080L;
}
}
static void CheckData(Object obj, int lastAllocSize, uint8[] data)
{
int objSize = typeof(Object).InstanceSize;
Test.Assert(lastAllocSize == data.Count + objSize);
uint8* ptr = (uint8*)Internal.UnsafeCastToPtr(obj) + objSize;
for (int i < data.Count)
Test.Assert(ptr[i] == data[i]);
}
[Test]
public static void Test()
{
TrackedAlloc trackedAlloc = scope .();
int objSize = typeof(Object).InstanceSize;
let ca = new:trackedAlloc ClassA();
CheckData(ca, trackedAlloc.mLastAllocSize, scope .(
0x44, 0x33, 0x22, 0x11, 0x55, 0x66, 0x77));
delete:trackedAlloc ca;
let cc = new:trackedAlloc ClassC(10);
Test.Assert(ClassC.sCallCount == 1); // This ensures we had a constant evaluation of the size
CheckData(cc, trackedAlloc.mLastAllocSize, scope .(
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x00, 0x00, 0x44, 0x33, 0x22, 0x11,
0x88, 0x77, 0x66, 0x55));
delete:trackedAlloc cc;
let ce = new:trackedAlloc ClassE();
CheckData(cc, trackedAlloc.mLastAllocSize, scope .(
0x22, 0x11, 0x00, 0x00, 0x66, 0x55, 0x44, 0x33, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10
));
delete:trackedAlloc ce;
}
}
}

View file

@ -0,0 +1,40 @@
using System;
namespace Tests
{
class Boxing
{
interface IFace
{
int Get() mut;
}
struct Struct : IFace
{
public int mA = 100;
public int mB = 200;
public int Get() mut
{
mA += 1000;
return mA;
}
}
[Test]
public static void TestBasics()
{
Struct val0 = .();
Object obj0 = val0;
IFace iface0 = (IFace)obj0;
Test.Assert(iface0.Get() == 1100);
Test.Assert(val0.mA == 100); // This should copy values
/*Struct val1 = .();
Object obj1 = (Object)(ref val1);
IFace iface1 = (IFace)obj1;
Test.Assert(iface1.Get() == 1100);
Test.Assert(val1.mA == 1100); // This should reference values*/
}
}
}

View file

@ -0,0 +1,94 @@
using System;
namespace Tests
{
class Delegates
{
struct Valueless
{
public int MutMethod(int a) mut
{
return 210 + a;
}
public int NonMutMethod(int a)
{
return 210 + a;
}
}
struct Splattable
{
public int32 mA = 10;
public int16 mB = 200;
public int MutMethod(int a) mut
{
mB += 100;
return mA + mB + a;
}
public int NonMutMethod(int a)
{
return mA + mB + a;
}
}
struct NonSplattable
{
public int32 mA = 10;
public int16 mB = 200;
public int64 mC = 300;
public int64 mD = 400;
public int MutMethod(int a) mut
{
mB += 100;
return mA + mB + a;
}
public int NonMutMethod(int a)
{
return mA + mB + a;
}
}
[Test]
public static void TestBasics()
{
delegate int(int a) dlg;
Valueless val0 = .();
dlg = scope => val0.MutMethod;
Test.Assert(dlg(9) == 219);
dlg = scope => val0.NonMutMethod;
Test.Assert(dlg(9) == 219);
Splattable val1 = .();
dlg = scope => val1.MutMethod;
Test.Assert(dlg(9) == 319);
dlg = scope => val1.NonMutMethod;
Test.Assert(dlg(9) == 219);
Test.Assert(val1.mB == 200);
dlg = scope => (ref val1).MutMethod;
Test.Assert(dlg(9) == 319);
dlg = scope => (ref val1).NonMutMethod;
Test.Assert(dlg(9) == 319);
Test.Assert(val1.mB == 300);
NonSplattable val2 = .();
dlg = scope => val2.MutMethod;
Test.Assert(dlg(9) == 319);
dlg = scope => val2.NonMutMethod;
Test.Assert(dlg(9) == 219);
Test.Assert(val2.mB == 200);
dlg = scope => (ref val2).MutMethod;
Test.Assert(dlg(9) == 319);
dlg = scope => (ref val2).NonMutMethod;
Test.Assert(dlg(9) == 319);
Test.Assert(val2.mB == 300);
}
}
}

View file

@ -0,0 +1,118 @@
#pragma warning disable 168
using System;
namespace Tests
{
class Enums
{
enum EnumA
{
A,
B
}
enum EnumB
{
A,
B = 600
}
enum EnumC
{
A,
B = 0x7FFFFFFF
}
enum EnumD
{
A,
B = 0x7FFFFFFFFFFFFFFFL
}
enum EnumE
{
case A;
case B(int a);
case C(int a, int b);
}
enum EnumF
{
case None;
case EE(EnumE ee);
}
[Test]
static void TestBasic()
{
EnumA ea = .A;
Test.Assert((int)ea == 0);
Test.Assert(sizeof(EnumA) == 1);
Test.Assert(sizeof(EnumB) == 2);
Test.Assert(sizeof(EnumC) == 4);
Test.Assert(sizeof(EnumD) == 8);
}
[Test]
static void TestPayloads()
{
Test.Assert(sizeof(EnumE) == sizeof(int)*2 + 1);
Test.Assert(sizeof(EnumF) == sizeof(int)*2 + 1 + 1);
EnumE ee = .C(1, 2);
int a = 0;
int b = 0;
switch (ee)
{
case .A:
case .B(out a):
case .C(out a, out b):
}
Test.Assert(a == 1);
Test.Assert(b == 2);
EnumF ef = .EE(.C(3, 4));
switch (ef)
{
case .EE(let eeVal):
if (!(eeVal case .C(out a, out b)))
{
Test.FatalError();
}
default:
}
Test.Assert(a == 3);
Test.Assert(b == 4);
}
[Test]
static void TestCases()
{
EnumE ee = .A;
int val = 123;
bool matches = ee case .B(out val);
Test.Assert(val == 0);
// We only assign to 'val' on true here
val = 123;
if (ee case .B(out val))
{
Test.Assert(val == 0 );
}
Test.Assert(val == 123);
// We always assign to 'val' here because we may enter even if there's no match
val = 123;
if ((ee case .B(out val)) || (val > 0))
{
}
Test.Assert(val == 0);
ee = .B(10);
}
}
}

View file

@ -0,0 +1,174 @@
using System;
namespace System.Collections.Generic
{
extension List<T> where T : Tests.Extensions.IGetExVal
{
public int GetExVals()
{
int total = 0;
for (var val in this)
{
total += val.GetExVal();
}
return total;
}
}
}
namespace System.Collections.Generic
{
extension TClass<T>
{
}
}
namespace Tests
{
class Extensions
{
public interface IGetExVal
{
int GetExVal();
}
class ClassA
{
public int32 mA;
}
extension ClassA
{
public int32 mB;
}
class TClassA<T> where T : IDisposable
{
public int32 mA = 10;
public void Dispose()
{
mA += 20;
}
public int GetB()
{
return 1;
}
}
extension TClassA<T> where T : IGetExVal
{
public T mTVal;
public T GetIt()
{
return mTVal;
}
public int GetB()
{
return 2;
}
}
class ImpGetExVal : IGetExVal, IDisposable
{
public int32 mVal = 999;
void IDisposable.Dispose()
{
}
int IGetExVal.GetExVal()
{
return mVal;
}
}
class ImpDisp : IDisposable
{
public int32 mVal = 999;
void IDisposable.Dispose()
{
}
}
static int UseTClass<T>(TClassA<T> val) where T : IDisposable
{
return -1;
}
static int UseTClass<T>(TClassA<T> val) where T : IDisposable, IGetExVal
{
return val.GetIt().GetExVal();
}
[Test]
public static void TestBasics()
{
Test.Assert(typeof(ClassA).InstanceSize == typeof(Object).InstanceSize + 4+4);
ClassA ca = scope ClassA();
ca.mA = 123;
ca.mB = 234;
}
[Test]
public static void TestTClass()
{
TClassA<ImpGetExVal> ta = scope TClassA<ImpGetExVal>();
ta.mTVal = scope ImpGetExVal();
int val = ta.GetIt().mVal;
Test.Assert(val == 999);
Test.Assert(typeof(decltype(ta)).InstanceSize == typeof(Object).InstanceSize + 4 + sizeof(Object));
Test.Assert(UseTClass(ta) == 999);
Test.Assert(ta.GetB() == 2);
TClassA<ImpDisp> tb = scope TClassA<ImpDisp>();
Test.Assert(typeof(decltype(tb)).InstanceSize == typeof(Object).InstanceSize + 4);
Test.Assert(UseTClass(tb) == -1);
Test.Assert(tb.GetB() == 1);
}
[Test]
public static void TestList()
{
System.Collections.Generic.List<ImpGetExVal> list = scope .();
ImpGetExVal val0 = scope ImpGetExVal();
list.Add(val0);
val0.mVal = 10;
ImpGetExVal val1 = scope ImpGetExVal();
list.Add(val1);
val1.mVal = 100;
int val = list.GetExVals();
Test.Assert(val == 110);
}
[Test]
public static void TestSharedData()
{
LibClassA ca = scope LibClassA();
Test.Assert(ca.mA == 7);
Test.Assert(ca.LibB_GetB() == 108);
Test.Assert(ca.LibC_GetB() == 13);
Test.Assert(ca.GetVal2() == 9);
ca = scope LibClassA(12345);
Test.Assert(ca.mA == 7);
Test.Assert(ca.LibB_GetB() == 1008);
Test.Assert(ca.LibC_GetB() == 13);
ca = scope LibClassA((int8)2);
Test.Assert(ca.mA == 7);
Test.Assert(ca.LibB_GetB() == 8);
Test.Assert(ca.LibC_GetB() == 30013);
}
}
}

View file

@ -0,0 +1,397 @@
using System;
namespace Tests
{
class FuncRefs2
{
public static int Do10Ext<T>(T func, int val) where T : delegate int(int a)
{
int total = 0;
for (int i < 10)
total += func(val);
return total;
}
}
class FuncRefs
{
static int FuncA(int val)
{
return val * 10;
}
static float FuncA(float val)
{
return val * -10;
}
static int Do10<T>(T func, int val) where T : delegate int(int a)
{
int total = 0;
for (int i < 5)
total += func(val);
delegate int(int a) dlg = scope => func;
for (int i < 5)
total += dlg(val);
return total;
}
static float Do10f<T>(T func, float val) where T : delegate float(float a)
{
float total = 0;
for (int i < 10)
total += func(val);
return total;
}
[Test]
public static void TestBasics()
{
int val0 = Do10(scope => FuncA, 3);
Test.Assert(val0 == 300);
int val1 = Do10(=> FuncA, 3);
Test.Assert(val1 == 300);
int val2 = FuncRefs2.Do10Ext(=> FuncA, 3);
Test.Assert(val2 == 300);
float val3 = Do10f(scope => FuncA, 0.34f);
Test.Assert(val3 == -34);
float val4 = Do10f(=> FuncA, 0.34f);
Test.Assert(val4 == -34);
}
struct MethodRefHolder<T> where T : delegate int(int num)
{
public T mVal;
public void Set(T val) mut
{
mVal = val;
}
public int Use(int num)
{
return mVal(num);
}
[SkipCall]
public void Dispose()
{
}
}
extension MethodRefHolder<T> where T : Delegate
{
public void Dispose()
{
delete mVal;
}
}
static int Use<T>(T val, int num) where T : delegate int(int num)
{
T copied = val;
copied(num);
int result = val(num);
return result;
}
static MethodRefHolder<T> Bind<T>(T val) where T : delegate int(int num)
{
MethodRefHolder<T> bind = .();
bind.Set(val);
return bind;
}
class Class
{
public int32 mA = 100;
public int16 mB = 200;
public void Test()
{
int a = 0;
Splattable splat;
splat.mA = 300;
splat.mB = 400;
int LFunc(int p)
{
a += p;
mA += splat.mA;
return splat.mB;
}
Test.Assert(Use(=> LFunc, 10) == 400);
Test.Assert(a == 10+10);
Test.Assert(mA == 100+300+300);
var bind = Bind(=> LFunc);
Test.Assert(bind.Use(30) == 400);
Test.Assert(a == 10+10 + 30);
Test.Assert(mA == 100+300+300 + 300);
bind.Dispose();
}
public void TestDlg()
{
int a = 0;
Splattable splat;
splat.mA = 300;
splat.mB = 400;
int LFunc(int p)
{
a += p;
mA += splat.mA;
return splat.mB;
}
delegate int(int num) dlg = new => LFunc;
Test.Assert(Use(dlg, 10) == 400);
Test.Assert(a == 10+10);
Test.Assert(mA == 100+300+300);
var bind = Bind(dlg);
Test.Assert(bind.Use(30) == 400);
Test.Assert(a == 10+10 + 30);
Test.Assert(mA == 100+300+300 + 300);
bind.Dispose();
}
}
struct Valueless
{
public void Test() mut
{
int a = 0;
Splattable splat;
splat.mA = 300;
splat.mB = 400;
int LFunc(int p)
{
a += p;
a += GetVal();
return splat.mB;
}
Test.Assert(Use(=> LFunc, 10) == 400);
Test.Assert(a == 10*2+20*2);
var bind = Bind(=> LFunc);
Test.Assert(bind.Use(30) == 400);
Test.Assert(a == 10*2+20*2 + 30+20);
bind.Dispose();
}
public void TestDlg()
{
int a = 0;
Splattable splat;
splat.mA = 300;
splat.mB = 400;
int LFunc(int p)
{
a += p;
a += GetVal();
return splat.mB;
}
delegate int(int num) dlg = new => LFunc;
Test.Assert(Use(dlg, 10) == 400);
Test.Assert(a == 10*2+20*2);
var bind = Bind(dlg);
Test.Assert(bind.Use(30) == 400);
Test.Assert(a == 10*2+20*2 + 30+20);
bind.Dispose();
}
public int GetVal()
{
return 20;
}
}
struct Splattable
{
public int32 mA = 100;
public int16 mB = 200;
public void Test() mut
{
int a = 0;
Splattable splat;
splat.mA = 300;
splat.mB = 400;
int LFunc(int p)
{
a += p;
mA += splat.mA;
return splat.mB;
}
Test.Assert(Use(=> LFunc, 10) == 400);
Test.Assert(a == 10+10);
Test.Assert(mA == 100+300+300);
var bind = Bind(=> LFunc);
Test.Assert(bind.Use(30) == 400);
Test.Assert(a == 10+10 + 30);
Test.Assert(mA == 100+300+300 + 300);
bind.Dispose();
}
public void TestDlg() mut
{
int a = 0;
Splattable splat;
splat.mA = 300;
splat.mB = 400;
int LFunc(int p)
{
a += p;
mA += splat.mA;
return splat.mB;
}
delegate int(int num) dlg = new => LFunc;
Test.Assert(Use(dlg, 10) == 400);
Test.Assert(a == 10+10);
Test.Assert(mA == 100+300+300);
var bind = Bind(dlg);
Test.Assert(bind.Use(30) == 400);
Test.Assert(a == 10+10 + 30);
Test.Assert(mA == 100+300+300 + 300);
bind.Dispose();
}
}
struct NonSplattable
{
public int32 mA = 100;
public int16 mB = 200;
public int64 mC = 300;
public int64 mD = 400;
public void Test() mut
{
int a = 0;
Splattable splat;
splat.mA = 300;
splat.mB = 400;
int LFunc(int p)
{
a += p;
mA += splat.mA;
return splat.mB;
}
Test.Assert(Use(=> LFunc, 10) == 400);
Test.Assert(a == 10+10);
Test.Assert(mA == 100+300+300);
var bind = Bind(=> LFunc);
Test.Assert(bind.Use(30) == 400);
Test.Assert(a == 10+10 + 30);
Test.Assert(mA == 100+300+300 + 300);
bind.Dispose();
}
public void TestDlg() mut
{
int a = 0;
Splattable splat;
splat.mA = 300;
splat.mB = 400;
int LFunc(int p)
{
a += p;
mA += splat.mA;
return splat.mB;
}
delegate int(int num) dlg = new => LFunc;
Test.Assert(Use(dlg, 10) == 400);
Test.Assert(a == 10+10);
Test.Assert(mA == 100+300+300);
var bind = Bind(dlg);
Test.Assert(bind.Use(30) == 400);
Test.Assert(a == 10+10 + 30);
Test.Assert(mA == 100+300+300 + 300);
bind.Dispose();
}
}
[Test]
public static void ClassTestA()
{
Class val = scope Class();
val.Test();
val = scope Class();
val.TestDlg();
}
[Test]
public static void ValuelessTestA()
{
Valueless val = .();
val.Test();
val = .();
val.TestDlg();
}
[Test]
public static void SplattableTestA()
{
Splattable val = .();
val.Test();
val = .();
val.TestDlg();
}
[Test]
public static void NonSplattableTestA()
{
NonSplattable val = .();
val.Test();
val = .();
val.TestDlg();
}
}
}

View file

@ -0,0 +1,13 @@
namespace System.Collections.Generic
{
class TClass<T> : IDisposable
{
public void Dispose()
{
Variant GetVariant()
{
return default;
}
}
}
}

View file

@ -0,0 +1,127 @@
using System;
namespace Tests
{
class Interfaces
{
interface IFaceA
{
int FuncA(int a) mut;
int FuncA2() mut { return 0; }
}
interface IFaceB : IFaceA
{
void FuncB(int a) mut
{
FuncA(a + 100);
}
}
concrete interface IFaceC
{
concrete IFaceA GetConcreteIA();
}
struct StructA : IFaceB
{
public int mA = 10;
int IFaceA.FuncA(int a) mut
{
mA += a;
return mA;
}
}
struct StructB : IFaceC
{
public StructA GetConcreteIA()
{
return StructA();
}
}
static int UseIA<T>(mut T val, int a) where T : IFaceA
{
return val.FuncA(a);
}
static int UseIA2<T>(mut T val) where T : IFaceA
{
return val.FuncA2();
}
static void UseIB<T>(mut T val, int a) where T : IFaceB
{
val.FuncB(a);
}
class ClassA : IFaceA
{
public int FuncA(int a)
{
return 5;
}
public virtual int FuncA2()
{
return 50;
}
}
class ClassB : ClassA
{
public new int FuncA(int a)
{
return 6;
}
public override int FuncA2()
{
return 60;
}
}
class ClassC : ClassA, IFaceA
{
public new int FuncA(int a)
{
return 7;
}
public override int FuncA2()
{
return 70;
}
}
[Test]
public static void TestBasics()
{
StructA sa = .();
UseIB(mut sa, 9);
Test.Assert(sa.mA == 119);
ClassA ca = scope ClassA();
ClassB cb = scope ClassB();
ClassA cba = cb;
ClassC cc = scope ClassC();
ClassA cca = cc;
Test.Assert(UseIA(ca, 100) == 5);
Test.Assert(UseIA(cb, 100) == 5);
Test.Assert(UseIA(cba, 100) == 5);
Test.Assert(UseIA((IFaceA)cba, 100) == 5);
Test.Assert(UseIA(cc, 100) == 7);
Test.Assert(UseIA(cca, 100) == 5);
Test.Assert(UseIA2(ca) == 50);
Test.Assert(UseIA2(cb) == 60);
Test.Assert(UseIA2(cba) == 60);
Test.Assert(UseIA2((IFaceA)cba) == 60);
Test.Assert(UseIA2(cc) == 70);
Test.Assert(UseIA2(cca) == 70);
}
}
}

View file

@ -0,0 +1,25 @@
using System;
namespace Tests
{
class Ints
{
[Test]
public static void TestUInt64()
{
var str = scope String();
uint64 val = 0x11223344'55667788;
str.AppendF("{0:X}", val);
//Test.Assert(str == "1122334455667788");
}
[Test]
public static void TestInt64()
{
Test.Assert(Math.Min((int64)-1, (int64)0) == -1);
Test.Assert(Math.Max((int64)-1, (int64)0) == 0);
}
}
}

View file

@ -0,0 +1,40 @@
using System;
namespace Tests
{
class Lambdas
{
[Test]
static void TestBasics()
{
int a = 1;
Action act = scope [&] () =>
{
Action act2 = scope [&] () =>
{
a += 100;
};
act2();
};
act();
Test.Assert(a == 101);
}
static int Add3<T>(T func) where T : delegate int()
{
return func() + func() + func();
}
[Test]
static void TestValueless()
{
Test.Assert(Add3(() => 100) == 300);
int a = 20;
int result = Add3(() => a++);
Test.Assert(result == 63);
}
}
}

View file

@ -0,0 +1,346 @@
#pragma warning disable 168
using System;
namespace Tests
{
class LocalFunctions
{
[Test]
static void TestA()
{
int a = 1;
void FuncA()
{
void FuncB()
{
a += 100;
}
FuncB();
}
FuncA();
Test.Assert(a == 101);
}
[Test]
static void TestB()
{
int a = 1;
Action act = scope [&] () =>
{
a += 100;
};
act();
Test.Assert(a == 101);
}
[Test]
static void TestC()
{
int a = 1;
const int c = 10;
Action OuterLocal()
{
return new [&] () =>
{
void FuncA()
{
FuncB();
}
void FuncB()
{
a += c;
}
FuncA();
};
}
var act = OuterLocal();
act();
delete act;
Test.Assert(a == 11);
}
[Test]
static void TestD()
{
int a = 1;
int b = 2;
void FuncA()
{
a += 100;
}
mixin MixA(var refVal)
{
refVal += 10;
FuncA();
MixB!();
}
mixin MixB()
{
b += 20;
}
MixA!(b);
Test.Assert(a == 101);
Test.Assert(b == 32);
}
[Test]
static void TestE()
{
int a = 1;
int b = 2;
int c = 3;
void FuncA()
{
a += 100;
FuncB();
b += 200;
}
void FuncB()
{
c += 300;
}
FuncA();
Test.Assert(a == 101);
Test.Assert(b == 202);
Test.Assert(c == 303);
}
[Test]
static void TestF()
{
int a = 1;
const int c = 100;
Action act = scope [&] () =>
{
void FuncA()
{
FuncB();
const int d = 1000;
void FuncB()
{
a += c;
a += d;
}
}
FuncA();
};
act();
Test.Assert(a == 1101);
}
[Test]
static void TestG()
{
int a = 1;
void FuncA()
{
a += 100;
int a = 2;
void FuncB()
{
a += 1000;
}
FuncB();
}
FuncA();
Test.Assert(a == 101);
}
[Test]
public static void TestH()
{
int a = 1;
void FuncA(int b)
{
a += 100;
if (b == 0)
FuncB();
}
void FuncB()
{
Action act = scope [&] () =>
{
FuncA(1);
};
act();
}
}
[Test]
public static void TestI()
{
int a = 1;
void FuncA()
{
a += 100;
}
void FuncB()
{
int a = 2;
FuncA();
}
FuncB();
Test.Assert(a == 101);
}
class ClassA
{
public int mA;
public mixin MixA()
{
mA += 10;
void LocalA()
{
mA += 20;
}
}
public void FuncA()
{
MixA!();
}
public (int, int) MethodT<T>()
{
int a = 8;
int b = 90;
int FuncT<T2>()
{
int GetIt()
{
return b;
}
int GetIt<T3>(T3 val)
{
return sizeof(T3);
}
return mA + sizeof(T)*10000 + sizeof(T2)*1000 + GetIt<float>(2.0f)*100 + GetIt() + a;
}
int val = FuncT<int8>();
return (FuncT<int8>(), FuncT<int16>());
}
}
[Test]
public static void TestJ()
{
int a = 8;
int b = 90;
int FuncT<T>()
{
int GetIt()
{
return b;
}
int GetIt<T2>(T2 val)
{
return sizeof(T2);
}
return sizeof(T)*1000 + GetIt(2.0f)*100 + GetIt() + a;
}
Test.Assert(FuncT<int8>() == 1498);
Test.Assert(FuncT<int16>() == 2498);
///
ClassA ca = scope ClassA();
ca.mA = 300000;
let res2 = ca.MethodT<int32>();
Test.Assert(res2.0 == 341498);
Test.Assert(res2.1 == 342498);
}
[Test]
public static void TestK()
{
int a = 8;
int b = 90;
int GetIt(Object val)
{
return 0;
}
int GetIt(int8 val)
{
return a + val;
}
int GetIt(int16 val)
{
return b + val;
}
// We want to ensure that each specialization of Get<T> has its own capture list
int Get<T>(T val)
{
return GetIt(val);
}
Test.Assert(GetIt((int8)100) == 108);
Test.Assert(GetIt((int16)100) == 190);
}
[Test]
public static void TestL()
{
int a = 8;
int LocalA()
{
return 9;
}
int LocalB()
{
return a;
}
function int() func = => LocalA;
Test.Assert(func() == 9);
delegate int() dlg = scope => LocalB;
Test.Assert(dlg() == 8);
}
}
}

View file

@ -0,0 +1,47 @@
using System;
namespace Tests
{
class Mixins
{
class MixClass
{
public int mA = 100;
public mixin MixA(var addTo)
{
mA += addTo;
}
}
[Test]
public static void TestBasics()
{
MixClass mc = scope MixClass();
mc.MixA!(10);
Test.Assert(mc.mA == 110);
}
[Test]
public static void TestLocalMixin()
{
mixin AppendAndNullify(String str)
{
int a = 1;
a++;
str.Append("B");
str = null;
}
int a = 2;
a++;
String str0 = scope String("A");
String str1 = str0;
AppendAndNullify!(str0);
Test.Assert(str0 == null);
Test.Assert(str1 == "AB");
}
}
}

View file

@ -0,0 +1,89 @@
#pragma warning disable 168
using System;
namespace Tests
{
class CondB
{
public int mInt = 123;
public int Val
{
get
{
return 234;
}
}
public int GetVal()
{
return 345;
}
}
class CondA
{
public CondB mCondB;
public CondB mCondB2;
CondB CondBVal
{
get
{
return mCondB;
}
}
CondB GetCondB()
{
return mCondB;
}
}
class NullConditional
{
[Test]
static void TestBasic()
{
CondA ca = scope CondA();
ca.mCondB = scope CondB();
if (int i = ca?.mCondB?.mInt)
Test.Assert(i == 123);
else
Test.FatalError();
if (let i = ca?.mCondB?.mInt)
{
Test.Assert(typeof(decltype(i)) == typeof(int));
Test.Assert(i == 123);
}
else
Test.FatalError();
var i2 = ca?.mCondB?.Val;
Test.Assert(i2.Value == 234);
var i3 = ca?.mCondB?.GetVal();
Test.Assert(i3.Value == 345);
if (int i4 = ca?.mCondB2?.mInt)
{
Test.FatalError();
}
}
[Test]
static void TestParen()
{
CondA ca = scope CondA();
ca.mCondB = scope CondB();
let i = (ca?.mCondB?.mInt).GetValueOrDefault();
Test.Assert(i == 123);
let i2 = (ca?.mCondB2?.mInt).GetValueOrDefault();
Test.Assert(i2 == 0);
}
}
}

View file

@ -0,0 +1,21 @@
namespace Tests
{
class Objects
{
class ClassA
{
public virtual void MethodA()
{
}
}
class ClassB : ClassA
{
public override void MethodA()
{
base.MethodA();
}
}
}
}

View file

@ -0,0 +1,38 @@
using System;
namespace Tests
{
class Operators
{
struct StructA
{
public int mA;
public static StructA operator+(StructA lhs, StructA rhs)
{
StructA res;
res.mA = lhs.mA + rhs.mA;
return res;
}
public static StructA operator-(StructA lhs, StructA rhs)
{
StructA res;
res.mA = lhs.mA - rhs.mA;
return res;
}
}
[Test]
public static void TestBasics()
{
StructA sa0 = default;
sa0.mA = 1;
StructA sa1 = default;
sa1.mA = 2;
StructA sa2 = sa0 + sa1;
Test.Assert(sa2.mA == 3);
}
}
}

View file

@ -0,0 +1,19 @@
using System;
namespace Tests
{
class Precedence
{
[Test]
static void Test()
{
int a = -1;
bool b = true;
bool c = true;
if (a == -1 && b && c)
a = 2;
Test.Assert(a == 2);
Test.Assert(1*10 + 2 + 3 + 5*100*10 + 6*10000 == 65015);
}
}
}

View file

@ -0,0 +1,163 @@
using System;
namespace Tests
{
class Reflection
{
[AttributeUsage(.Field, .ReflectAttribute)]
struct AttrAAttribute : Attribute
{
public int32 mA;
public float mB;
public String mC;
public String mD;
public this(int32 a, float b, String c, String d)
{
PrintF("this: %p A: %d B: %f", this, a, (double)b);
mA = a;
mB = b;
mC = c;
mD = d;
}
}
[AttributeUsage(.Field)]
struct AttrBAttribute : Attribute
{
int32 mA;
float mB;
public this(int32 a, float b)
{
mA = a;
mB = b;
}
}
[Reflect]
class ClassA
{
[AlwaysInclude]
static float StaticMethodA(int32 a, int32 b, float c)
{
return a + b + c;
}
[AlwaysInclude]
float MemberMethodA(int32 a, int32 b, float c)
{
return a + b + c;
}
public virtual int GetA(int32 a)
{
return a + 1000;
}
public virtual int GetB(int32 a)
{
return a + 3000;
}
}
class ClassA2 : ClassA
{
public override int GetA(int32 a)
{
return a + 2000;
}
public override int GetB(int32 a)
{
return a + 4000;
}
}
[Reflect(.All)]
class ClassB
{
[AttrA(11, 22, "StrA", "StrB")]
int mA;
[AttrB(44, 55)]
int mB;
int mC;
}
[Reflect(.Type)]
class ClassC
{
[AttrA(11, 22, "StrA", "StrC")]
int mA;
[AttrB(44, 55)]
int mB;
int mC;
}
[Test]
static void TestA()
{
ClassA ca = scope ClassA();
ClassA2 ca2 = scope ClassA2();
Test.Assert(ca2.GetA(9) == 2009);
int methodIdx = 0;
var typeInfo = typeof(ClassA);
for (let methodInfo in typeInfo.GetMethods())
{
switch (methodIdx)
{
case 0:
Test.Assert(methodInfo.Name == "StaticMethodA");
var result = methodInfo.Invoke(null, 100, (int32)20, 3.0f).Get();
Test.Assert(result.Get<float>() == 123);
result.Dispose();
case 1:
Test.Assert(methodInfo.Name == "MemberMethodA");
var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get();
Test.Assert(result.Get<float>() == 123);
result.Dispose();
case 2:
Test.Assert(methodInfo.Name == "GetA");
var result = methodInfo.Invoke(ca, 123).Get();
Test.Assert(result.Get<int>() == 1123);
result.Dispose();
result = methodInfo.Invoke(ca2, 123).Get();
Test.Assert(result.Get<int>() == 2123);
result.Dispose();
case 3:
Test.Assert(methodInfo.Name == "__BfCtor");
Test.Assert(methodInfo.IsConstructor);
case 4:
Test.FatalError(); // Shouldn't have any more
}
methodIdx++;
}
}
[Test]
static void TestB()
{
ClassB cb = scope ClassB();
int fieldIdx = 0;
for (let fieldInfo in cb.GetType().GetFields())
{
switch (fieldIdx)
{
case 0:
Test.Assert(fieldInfo.Name == "mA");
var attrA = fieldInfo.GetCustomAttribute<AttrAAttribute>().Get();
Test.Assert(attrA.mA == 11);
Test.Assert(attrA.mB == 22);
Test.Assert(attrA.mC == "StrA");
Test.Assert(attrA.mD == "StrB");
}
fieldIdx++;
}
}
}
}

View file

@ -0,0 +1,177 @@
using System;
namespace Tests
{
class Scopes
{
[Test]
public static void TestRestore()
{
// This shouldn't overflow because we should restore the stack between 'i' iterations
for (int i < 100)
IBlock:
{
// Allocate 500kb
for (int j < 5)
{
scope:IBlock uint8[100*1024];
}
}
}
[Test]
public static void TestGetStrScope()
{
var str = GetStr!();
Test.Assert(str == "TestString");
{
str = GetStr!::();
}
Test.Assert(str == "TestString");
}
/*[Test(ShouldFail=true)]
public static void TestFailGetStrScope()
{
String str;
{
str = GetStr!();
}
// Should detect as deleted
#unwarn
str.Contains('T');
}*/
public static mixin GetStr()
{
scope:mixin String("TestString")
}
class ClassA
{
public int mA = 123;
public static int sAllocCount = 0;
public this()
{
sAllocCount++;
}
public ~this()
{
Test.Assert(mA == 123);
sAllocCount--;
}
}
class ClassB
{
public int mA = 234;
public static int sAllocCount = 0;
public this()
{
sAllocCount++;
}
public ~this()
{
Test.Assert(mA == 234);
sAllocCount--;
}
}
static bool CheckTrue(Object obj)
{
return true;
}
static bool CheckFalse(Object obj)
{
return false;
}
[Test]
public static void TestIf()
{
//
{
if ((CheckTrue(scope ClassA())) || (CheckTrue(scope ClassB())))
{
Test.Assert(ClassA.sAllocCount == 1);
Test.Assert(ClassB.sAllocCount == 0);
}
Test.Assert(ClassA.sAllocCount == 0);
Test.Assert(ClassB.sAllocCount == 0);
}
//
{
if ((CheckFalse(scope ClassA())) || (CheckTrue(scope ClassB())))
{
Test.Assert(ClassA.sAllocCount == 1);
Test.Assert(ClassB.sAllocCount == 1);
}
Test.Assert(ClassA.sAllocCount == 0);
Test.Assert(ClassB.sAllocCount == 0);
}
//
{
if ((CheckFalse(scope ClassA())) || (CheckFalse(scope ClassB())))
{
Test.FatalError();
}
else
{
Test.Assert(ClassA.sAllocCount == 1);
Test.Assert(ClassB.sAllocCount == 1);
}
Test.Assert(ClassA.sAllocCount == 0);
Test.Assert(ClassB.sAllocCount == 0);
}
//
{
if ((CheckTrue(scope ClassA())) && (CheckTrue(scope ClassB())))
{
Test.Assert(ClassA.sAllocCount == 1);
Test.Assert(ClassB.sAllocCount == 1);
}
Test.Assert(ClassA.sAllocCount == 0);
Test.Assert(ClassB.sAllocCount == 0);
}
//
{
if ((CheckTrue(scope ClassA())) && (CheckFalse(scope ClassB())))
{
Test.FatalError();
}
else
{
Test.Assert(ClassA.sAllocCount == 1);
Test.Assert(ClassB.sAllocCount == 1);
}
Test.Assert(ClassA.sAllocCount == 0);
Test.Assert(ClassB.sAllocCount == 0);
}
//
{
if ((CheckFalse(scope ClassA())) && (CheckFalse(scope ClassB())))
{
Test.FatalError();
}
else
{
Test.Assert(ClassA.sAllocCount == 1);
Test.Assert(ClassB.sAllocCount == 0);
}
Test.Assert(ClassA.sAllocCount == 0);
Test.Assert(ClassB.sAllocCount == 0);
}
}
}
}

View file

@ -0,0 +1,27 @@
using System;
namespace Tests
{
class SizedArrays
{
[Test]
static void TestBasics()
{
int[3][2] val0 = .((1, 2), (3, 4), (5, 6));
Test.Assert(sizeof(decltype(val0)) == sizeof(int)*6);
Test.Assert(val0[0][0] == 1);
Test.Assert(val0[0][1] == 2);
Test.Assert(val0[1][0] == 3);
int[2] val1 = .(7, 8);
val0[1] = val1;
int[3][2] val2 = .((1, 2), (7, 8), (5, 6));
Test.Assert(val0 == val2);
val2[0][0] = 9;
Test.Assert(val0 != val2);
Test.Assert(val2[1] == val1);
}
}
}

View file

@ -0,0 +1,118 @@
using System;
namespace Tests
{
class Structs
{
struct StructA
{
}
struct StructB
{
public int mA;
public int mB;
public this()
{
mA = 0;
mB = 0;
}
public this(int a, int b)
{
mA = a;
mB = b;
}
}
struct StructC
{
int8 mA;
int32 mB;
int8 mC;
}
[Ordered]
struct StructD
{
int8 mA;
int32 mB;
int8 mC;
}
[CRepr]
struct StructE
{
int8 mA;
int32 mB;
int8 mC;
}
struct StructF : StructC
{
int8 mD;
}
struct StructG : StructD
{
int8 mD;
}
struct StructH : StructE
{
int8 mD;
}
[CRepr]
struct StructI : StructE
{
int8 mD;
}
[Test]
static void TestBasics()
{
Test.Assert(sizeof(StructA) == 0);
StructB sb0 = .(1, 2);
StructB sb1;
sb1.mA = 1;
sb1.mB = 2;
Test.Assert(sb0 == sb1);
}
[Test]
static void TestLayouts()
{
Test.Assert(sizeof(StructC) == 6);
Test.Assert(alignof(StructC) == 4);
Test.Assert(strideof(StructC) == 8);
Test.Assert(sizeof(StructD) == 9);
Test.Assert(alignof(StructD) == 4);
Test.Assert(strideof(StructD) == 12);
Test.Assert(sizeof(StructE) == 12);
Test.Assert(alignof(StructE) == 4);
Test.Assert(strideof(StructE) == 12);
Test.Assert(sizeof(StructF) == 7);
Test.Assert(alignof(StructF) == 4);
Test.Assert(strideof(StructF) == 8);
Test.Assert(sizeof(StructG) == 10);
Test.Assert(alignof(StructG) == 4);
Test.Assert(strideof(StructG) == 12);
Test.Assert(sizeof(StructH) == 13);
Test.Assert(alignof(StructH) == 4);
Test.Assert(strideof(StructH) == 16);
Test.Assert(sizeof(StructI) == 16);
Test.Assert(alignof(StructI) == 4);
Test.Assert(strideof(StructI) == 16);
}
}
}

View file

@ -0,0 +1,22 @@
using System;
namespace Tests
{
class TrackedAlloc
{
public int mLastAllocSize;
public void* Alloc(int size, int align)
{
mLastAllocSize = size;
let ptr = new uint8[size]*;
Internal.MemSet(ptr, 0, size);
return ptr;
}
public void Free(void* ptr)
{
delete ptr;
}
}
}

View file

@ -0,0 +1,56 @@
#pragma warning disable 168
using System;
namespace Tests
{
class Tuples
{
[Test]
public static void TestBasic()
{
let (a, b, c) = (1, 2, 3);
Test.Assert(a == 1);
Test.Assert(b == 2);
Test.Assert(c == 3);
Test.Assert(typeof(decltype(a)) == typeof(int));
(int32, float) tVal1 = (1, 2.0f);
// Allow conversion from named to unnamed
tVal1 = (int32 a, float b)(2, 3.0f);
let v0 = tVal1.0;
Test.Assert(v0 == 2);
}
class ValClass
{
public int mA;
public int Prop
{
set
{
mA = value;
}
}
}
[Test]
public static void TestDecompose()
{
ValClass vc = scope .();
uint8 zz = 202;
(var val0, vc.Prop) = (101, zz);
Test.Assert(val0 == 101);
Test.Assert(vc.mA == 202);
let tup0 = (111, 222);
(int a, int b) tup1 = tup0;
Test.Assert(tup0.0 == 111);
Test.Assert(tup0.1 == 222);
}
}
}

View file

@ -0,0 +1,123 @@
#pragma warning disable 168
namespace Tests
{
class ClassE
{
public int mGlobal_E;
}
class TypeLookup
{
class ClassA
{
public int mA;
}
class ClassB
{
private class ClassA
{
public int mClassB_A2;
public void Hey()
{
ClassC cc = scope .();
cc.mClassB_C = 1;
}
}
public class ClassC
{
public int mClassB_C;
public void Hey()
{
ClassA ca = scope .();
ca.mClassB_A2 = 1;
}
}
}
class ClassC
{
public int mC;
}
private class ClassE
{
public int mE;
}
class ClassD : ClassB
{
public void Hey()
{
// Shouldn't be able to find ClassB.ClassB since it's private
ClassA ca = scope .();
ca.mA = 1;
// We should find ClassB.ClassC since it's public
ClassC cc = scope .();
cc.mClassB_C = 1;
ClassE ce = scope .();
ce.mE = 2;
}
}
class ClassF
{
private class ClassA
{
public int mClassF_A;
}
}
extension ClassF
{
public void Hey()
{
ClassA ca = scope .();
ca.mClassF_A = 1;
}
}
class ClassG
{
public class InnerG
{
}
public class InnerG2<T>
{
}
}
class ClassH
{
public class InnerH
{
}
}
class ClassI : ClassG
{
class InnerI : ClassH
{
class InnerInI : InnerG
{
public void UseIt()
{
InnerG2<int> ig2 = default;
InnerH ih = default;
}
}
}
}
}
}

View file

@ -0,0 +1,35 @@
using System;
namespace Tests
{
class Unions
{
// Not really a union
[Union]
struct UnionA
{
public int32 mInt32;
}
[Union]
struct UnionB
{
public int32 mInt32;
public float mFloat;
}
[Test]
static void TestBasics()
{
UnionA ua = .();
ua.mInt32 = 123;
Test.Assert(sizeof(UnionA) == 4);
UnionB ub = .();
ub.mInt32 = 123;
*((float*)&ub.mInt32) = 1.2f;
Test.Assert(ub.mFloat == 1.2f);
Test.Assert(sizeof(UnionB) == 4);
}
}
}