using uCalcSoftware;

var uc = new uCalc();

static void MyFunction(uCalc.Callback cb) {
   var uc = cb.uCalc;
   Console.WriteLine("------ MyFunc ------");

   // Retrieve standard 32-bit and 64-bit integer arguments directly
   Console.WriteLine(cb.ArgInt32(1));
   Console.WriteLine(cb.ArgInt64(2));

   // Retrieve the value of a pointer argument by referencing its exact data type.
   Console.WriteLine(uc.ItemOf("Int8").DataType.ToString(cb.ArgAddr(3)));

   // The Item object correctly identifies the type before conversion
   Console.WriteLine(uc.ItemOf("Int").DataType.ToString(cb.ArgPtr(4)));
}

static void MyFunction2(uCalc.Callback cb) {
   var uc = cb.uCalc;
   Console.WriteLine("------ MyFunc2 ------");
   Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_8).ToString(cb.ArgPtr(1)));
}

static void MyFunction3(uCalc.Callback cb) {
   var uc = cb.uCalc;
   Console.WriteLine("------ MyFunc3 ------");
   Console.WriteLine(uc.DataTypeOf(BuiltInType.Integer_16).ToString(cb.ArgPtr(1)));
}

uc.DefineVariable("x As Int = 123"); // Int32
uc.DefineVariable("xPtr As Int Ptr = AddressOf(x)");
uc.DefineFunction("MyFunc(a As Int32, b As Int64, c As Byte, d As Int Ptr)", MyFunction);
uc.Eval("MyFunc(x*10, 1+1, 255, xPtr)");

uc.DefineVariable("x2 As Int8 = -123");
uc.DefineVariable("xPtr2 As Int8 Ptr = AddressOf(x2)");
uc.DefineFunction("MyFunc2(d As Int8 Ptr)", MyFunction2);
uc.Eval("MyFunc2(xPtr2)");

uc.DefineVariable("x3 As Int16 = 1234");
uc.DefineVariable("xPtr3 As Int16 Ptr = AddressOf(x3)");
uc.DefineFunction("MyFunc3(d As Int16 Ptr)", MyFunction3);
uc.Eval("MyFunc3(xPtr3)");