C# Classes Translation
Program Class
Each to-be-translated C# file should comply with the following rules:
- A class with Program methods must be marked with a
[Program]attribute. - Each compiled .exe file must contain exactly one class with a
[Program]attribute. - A Program class can inherit interfaces [future plans]
- A Program class only contains public fields and public or private methods.
- Static fields and methods are not allowed.
- Public methods are translated to Program methods.
- Private methods are translated to inner functions, the only difference from Program methods being that the inner functions are not accessible from the outside world and can only be called from a Program method.
- Fields (that can be only public) are translated to storage items with
utf8("p_<field_name>")keys. - Only one Program class constructor is allowed. This constructor must not have any arguments.
User Defined Classes
Users can freely define classes without a [Program] attribute. Objects of these classes are translated to data structs and behave very similar to objects in C#.
Formally, this translation follows these rules:
- A class doesn't have a
[Program]attribute, the[Program]attribute is only used for one class, which is translated to Program methods. - Interfaces are not translated, they only serve as compile-time entities.
- All (
private,protected,internalandpublic) fields are translated toutf8("<field_name>") -> <field_value>pairs instruct. - All methods are translated to
utf8("<method_name>_<args_types>")->ref(#<inner_function_offset>). The<args_types>prefix is needed to support overloading and<inner_function_offset>means the offset of the function that should be called for the<method_name>method of that class. Overridden methods will point to different<inner_function_offset>. This technique is similar to Virtual method table. staticfields are translated to storage items withutf8("s_<class_name>_<field_name>")keys.staticmethods are translated to inner functions with<class_name>_<method_name>_<args_types>names.- Constructors are translated to inner functions with
<class_name>_ctor_<args_types>names.
Example:
Let’s assume that we have the following classes definitions in C#:
interface Vehicle
{
void ComeIn(String someone);
}
class Bicycle : Vehicle
{
public String Owner = "no one";
void ComeIn(String someone) {
Owner = someone;
}
}
class Car : Vehicle
{
static private bool isBearBurnedDown = false;
static public bool IsBearBurnedDown()
{
return Car.isBearBurnedDown;
}
public int NumberOfTires;
public Car(int tires)
{
NumberOfTires = tires.
}
void ComeIn(String someone)
{
if (someone == "bear") {
Car.isBearBurnedDown = true;
}
}
}
interface Vehiclewon't be translated to anythingBicycle()constructor will be translated to theBicycle_ctorfunction that createsstruct(utf8("Owner") -> utf8("no one"), utf8("ComeIn_string") -> ref(#<function1>)Bicycle.ComeInwill be translated to a certain function (let's call itfunction1) that changes theutf8("Owner")field in the givenstruct.Car(int)constructor will be translated to theCar_ctor_int32function that createsstruct(utf8("NumberOfTires") -> int32(<given_int>), utf8("ComeIn_string") -> ref(#<function2>))isBearBurnedDownstatic field will be translated toutf8("s_Car_isBearBurnedDown") -> boolstorage item.IsBearBurnedDownstatic method will be translated toCar_IsBearBurnedDownfunction that readsutf8("s_Car_isBearBurnedDown")storage key.Car.ComeInwill be translated to a certain function (let's call itfunction2) that changesutf8("s_Car_isBearBurnedDown") -> boolstorage item according to the givenStringfrom the stack.