8 Commits

Author SHA1 Message Date
Smaug123
4816fcaef2 Merge branch 'main' into castclass 2025-07-02 22:45:12 +01:00
Smaug123
fcc778d7aa Fix one test 2025-06-27 19:48:08 +01:00
Smaug123
9905bbf436 Merge branch 'main' into castclass 2025-06-27 15:10:04 +01:00
Smaug123
e3b797705d Merge branch 'main' into castclass 2025-06-27 15:04:28 +01:00
Smaug123
277f303431 WIP 2025-06-27 12:09:15 +01:00
Smaug123
c049313dd9 Merge branch 'main' into castclass 2025-06-27 12:02:33 +01:00
Smaug123
ca36bb3eba Merge branch 'main' into castclass 2025-06-27 11:56:26 +01:00
Smaug123
1ebcd0b4f5 Implement Castclass 2025-06-27 11:41:41 +01:00
23 changed files with 670 additions and 0 deletions

View File

@@ -92,6 +92,132 @@ module TestPureCases =
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = [ CliType.Numeric (CliNumericType.Int32 1) ] |> Some
}
{
FileName = "CastClassSimpleInheritance.cs"
ExpectedReturnCode = 5
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "IsInstSimpleInheritance.cs"
ExpectedReturnCode = 42
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassNull.cs"
ExpectedReturnCode = 42
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassArrayCovariance.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassToObject.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "IsinstPatternMatching.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassMultipleInterfaces.cs"
ExpectedReturnCode = 42
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassCrossAssembly.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassNestedTypes.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassGenerics.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassEnum.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassBoxing.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "IsinstBoxing.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassArray.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "IsinstArray.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "IsinstNull.cs"
ExpectedReturnCode = 42
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassInvalid.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "IsinstFailed.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "IsinstFailedInterface.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "CastClassInterface.cs"
ExpectedReturnCode = 1
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "IsinstInterface.cs"
ExpectedReturnCode = 42
NativeImpls = MockEnv.make ()
LocalVariablesOfMain = None
}
{
FileName = "StaticVariables.cs"
ExpectedReturnCode = 0

View File

@@ -32,6 +32,27 @@
<EmbeddedResource Include="sourcesPure\Threads.cs" />
<EmbeddedResource Include="sourcesPure\ResizeArray.cs" />
<EmbeddedResource Include="sourcesPure\ArgumentOrdering.cs" />
<EmbeddedResource Include="sourcesPure\CastClassSimpleInheritance.cs" />
<EmbeddedResource Include="sourcesPure\IsInstSimpleInheritance.cs" />
<EmbeddedResource Include="sourcesPure\CastClassNull.cs" />
<EmbeddedResource Include="sourcesPure\CastClassArrayCovariance.cs" />
<EmbeddedResource Include="sourcesPure\CastClassToObject.cs" />
<EmbeddedResource Include="sourcesPure\IsinstPatternMatching.cs" />
<EmbeddedResource Include="sourcesPure\CastClassMultipleInterfaces.cs" />
<EmbeddedResource Include="sourcesPure\CastClassCrossAssembly.cs" />
<EmbeddedResource Include="sourcesPure\CastClassNestedTypes.cs" />
<EmbeddedResource Include="sourcesPure\CastClassGenerics.cs" />
<EmbeddedResource Include="sourcesPure\CastClassEnum.cs" />
<EmbeddedResource Include="sourcesPure\CastClassBoxing.cs" />
<EmbeddedResource Include="sourcesPure\IsinstBoxing.cs" />
<EmbeddedResource Include="sourcesPure\CastClassArray.cs" />
<EmbeddedResource Include="sourcesPure\IsinstArray.cs" />
<EmbeddedResource Include="sourcesPure\IsinstNull.cs" />
<EmbeddedResource Include="sourcesPure\CastClassInvalid.cs" />
<EmbeddedResource Include="sourcesPure\IsinstFailed.cs" />
<EmbeddedResource Include="sourcesPure\IsinstFailedInterface.cs" />
<EmbeddedResource Include="sourcesPure\CastClassInterface.cs" />
<EmbeddedResource Include="sourcesPure\IsinstInterface.cs" />
<EmbeddedResource Include="sourcesPure\TestShl.cs" />
<EmbeddedResource Include="sourcesPure\TestShr.cs" />
<EmbeddedResource Include="sourcesPure\TestOr.cs" />

View File

@@ -0,0 +1,12 @@
public class Program
{
public static int Main(string[] args)
{
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
// Cast array to System.Array - should succeed
System.Array array = (System.Array)numbers;
return array.Length;
}
}

View File

@@ -0,0 +1,28 @@
public class Program
{
public struct Counter
{
public int Count;
public Counter(int count)
{
Count = count;
}
}
public static int Main(string[] args)
{
Counter counter = new Counter(42);
// Box the value type
object boxed = counter;
// Check if boxed value is System.ValueType
if (boxed is System.ValueType)
{
return 42;
}
return 0;
}
}

View File

@@ -0,0 +1,30 @@
public class Program
{
public struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
}
public static int Main(string[] args)
{
Point p = new Point(10, 32);
// Box the value type
object boxed = p;
// Cast boxed value type to object (should succeed)
object obj = (object)boxed;
// Unbox
Point unboxed = (Point)obj;
return unboxed.X + unboxed.Y;
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
public class Program
{
public static int Main(string[] args)
{
// Using types from System.Collections.Generic assembly
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
// Cast to interface from another assembly
IEnumerable<int> enumerable = (IEnumerable<int>)list;
int count = 0;
foreach (var item in enumerable)
{
count++;
}
return count == 5 ? 42 : 0;
}
}

View File

@@ -0,0 +1,25 @@
public class Program
{
public enum Color
{
Red = 1,
Green = 2,
Blue = 42
}
public static int Main(string[] args)
{
Color myColor = Color.Blue;
// Box enum value
object boxed = myColor;
// Cast to System.Enum
System.Enum enumValue = (System.Enum)boxed;
// Cast back to specific enum
Color unboxed = (Color)enumValue;
return (int)unboxed;
}
}

View File

@@ -0,0 +1,23 @@
public class Program
{
public class Container<T>
{
public T Value { get; set; }
}
public static int Main(string[] args)
{
Container<int> intContainer = new Container<int> { Value = 42 };
// Cast generic type to object
object obj = (object)intContainer;
// Check type and cast back
if (obj is Container<int> container)
{
return container.Value;
}
return 0;
}
}

View File

@@ -0,0 +1,25 @@
public class Program
{
public interface ICalculator
{
int Calculate(int x, int y);
}
public class Adder : ICalculator
{
public int Calculate(int x, int y)
{
return x + y;
}
}
public static int Main(string[] args)
{
Adder adder = new Adder();
// Cast to interface - should succeed
ICalculator calc = (ICalculator)adder;
return calc.Calculate(10, 32);
}
}

View File

@@ -0,0 +1,31 @@
public class Program
{
public class Cat
{
public string Name { get; set; }
}
public class Dog
{
public string Name { get; set; }
}
public static int Main(string[] args)
{
try
{
object cat = new Cat { Name = "Whiskers" };
// Invalid cast - should throw InvalidCastException
Dog dog = (Dog)cat;
// Should not reach here
return 0;
}
catch (System.InvalidCastException)
{
// Expected exception caught
return 42;
}
}
}

View File

@@ -0,0 +1,40 @@
public class Program
{
public interface IReadable
{
string Read();
}
public interface IWritable
{
void Write(string data);
}
public class File : IReadable, IWritable
{
private string content = "Hello";
public string Read()
{
return content;
}
public void Write(string data)
{
content = data;
}
}
public static int Main(string[] args)
{
File file = new File();
// Cast to first interface
IReadable readable = (IReadable)file;
// Cast to second interface
IWritable writable = (IWritable)file;
return readable != null && writable != null ? 42 : 0;
}
}

View File

@@ -0,0 +1,23 @@
public class Program
{
public class Outer
{
public class Inner
{
public int Value { get; set; }
}
}
public static int Main(string[] args)
{
Outer.Inner inner = new Outer.Inner { Value = 42 };
// Cast nested type to object
object obj = (object)inner;
// Cast back
Outer.Inner casted = (Outer.Inner)obj;
return casted.Value;
}
}

View File

@@ -0,0 +1,17 @@
public class Program
{
public class MyClass
{
public int Value { get; set; }
}
public static int Main(string[] args)
{
MyClass obj = null;
// Cast null reference - should succeed and remain null
object result = (object)obj;
return result == null ? 42 : 0;
}
}

View File

@@ -0,0 +1,22 @@
public class Program
{
public class Animal
{
public int Age { get; set; }
}
public class Dog : Animal
{
public string Name { get; set; }
}
public static int Main(string[] args)
{
Dog myDog = new Dog { Age = 5, Name = "Rex" };
// Cast to base class - should succeed
Animal animal = (Animal)myDog;
return animal.Age;
}
}

View File

@@ -0,0 +1,18 @@
public class Program
{
public class CustomClass
{
public int Id { get; set; }
}
public static int Main(string[] args)
{
CustomClass custom = new CustomClass { Id = 42 };
// Everything can be cast to System.Object
System.Object obj = (System.Object)custom;
// Verify it's the same object
return obj != null && obj == custom ? 42 : 0;
}
}

View File

@@ -0,0 +1,25 @@
public class Program
{
public class Vehicle
{
public int Wheels { get; set; }
}
public class Car : Vehicle
{
public string Model { get; set; }
}
public static int Main(string[] args)
{
Car myCar = new Car { Wheels = 4, Model = "Tesla" };
// 'is' operator uses isinst instruction
if (myCar is Vehicle)
{
return 42;
}
return 0;
}
}

View File

@@ -0,0 +1,15 @@
public class Program
{
public static int Main(string[] args)
{
string[] names = new string[] { "Alice", "Bob", "Charlie" };
// Check if array is System.Array
if (names is System.Array)
{
return 42;
}
return 0;
}
}

View File

@@ -0,0 +1,28 @@
public class Program
{
public struct Counter
{
public int Count;
public Counter(int count)
{
Count = count;
}
}
public static int Main(string[] args)
{
Counter counter = new Counter(42);
// Box the value type
object boxed = counter;
// Check if boxed value is System.ValueType
if (boxed is System.ValueType)
{
return 42;
}
return 0;
}
}

View File

@@ -0,0 +1,25 @@
public class Program
{
public class Bird
{
public bool CanFly { get; set; }
}
public class Fish
{
public bool CanSwim { get; set; }
}
public static int Main(string[] args)
{
Bird sparrow = new Bird { CanFly = true };
// Cast to object first to bypass compile-time checking
object obj = sparrow;
// This should fail at runtime and return null (not throw)
Fish fish = obj as Fish;
return fish == null ? 42 : 0;
}
}

View File

@@ -0,0 +1,30 @@
public class Program
{
public interface IAnimal
{
string Name { get; set; }
}
public class Bird : IAnimal
{
public string Name { get; set; }
public bool CanFly { get; set; }
}
public class Fish : IAnimal
{
public string Name { get; set; }
public bool CanSwim { get; set; }
}
public static int Main(string[] args)
{
IAnimal animal = new Bird { Name = "Sparrow", CanFly = true };
// This should fail at runtime and return null (not throw)
// because the actual object is Bird, not Fish
Fish fish = animal as Fish;
return fish == null ? 42 : 0;
}
}

View File

@@ -0,0 +1,27 @@
public class Program
{
public interface IDisposable
{
void Dispose();
}
public class Resource : IDisposable
{
public int Id { get; set; }
public void Dispose()
{
// Cleanup
}
}
public static int Main(string[] args)
{
Resource resource = new Resource { Id = 42 };
// 'as' operator uses isinst instruction
IDisposable disposable = resource as IDisposable;
return disposable != null ? resource.Id : 0;
}
}

View File

@@ -0,0 +1,17 @@
public class Program
{
public class MyType
{
public int Value { get; set; }
}
public static int Main(string[] args)
{
MyType obj = null;
// isinst on null should return null
object result = obj as object;
return result == null ? 42 : 0;
}
}

View File

@@ -0,0 +1,40 @@
public class Program
{
public abstract class Shape
{
public abstract double GetArea();
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double GetArea()
{
return 3.14 * Radius * Radius;
}
}
public class Square : Shape
{
public double Side { get; set; }
public override double GetArea()
{
return Side * Side;
}
}
public static int Main(string[] args)
{
Shape shape = new Circle { Radius = 10 };
// Pattern matching uses isinst
if (shape is Circle circle)
{
return (int)circle.Radius;
}
return 0;
}
}