#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto Int8Var = uc.DefineVariable("x As Int8 = -1");
   auto Int16Var = uc.DefineVariable("y As Int16 = -1");
   auto StrVar = uc.DefineVariable("MyStr = 'Hello there'");
   cout << uc.EvalStr("x") << endl;
   cout << uc.EvalStr("y") << endl;
   cout << uc.EvalStr("MyStr") << endl;

   auto xPtr = uc.DefineVariable("xPtr As Pointer"); // General pointer
   auto yPtr = uc.DefineVariable("yPtr As Int16u Ptr"); // pointer specific to unsigned Int16
   auto yPtrB = uc.DefineVariable("yPtrB As Int16 Ptr = AddressOf(y)"); // Using AddressOf
   auto StrPtr = uc.DefineVariable("StrPtr As String Ptr");
   xPtr.ValuePtr(Int8Var.ValueAddr()); // Sets the pointer address
   yPtr.ValuePtr(Int16Var.ValueAddr()); // Note: address of signed Int16 going to an unsigned Ptr
   StrPtr.ValuePtr(StrVar.ValueAddr());

   // Note: for the ints we are now returning unsigned values; so -1 turns into positive numbers
   cout << uc.EvalStr("ValueAt(Int8u, xPtr)") << endl; // Type required because it's defined as generar pointer
   cout << uc.EvalStr("ValueAt(yPtr)") << endl; // Type name not needed because it's defined as Int16u Ptr
   cout << uc.EvalStr("ValueAt(yPtrB)") << endl;
   cout << uc.EvalStr("ValueAt(StrPtr)") << endl;

   // Iterate through uc.ItemOf(ItemIs.DataType, n).Name()
   // to see data type names you can use with ValueAt

   auto OtherInt = uc.DefineVariable("OtherInt As Int16 = 1234");
   uc.DataTypeOf(BuiltInType::Integer_16).SetScalar(Int16Var.ValueAddr(), OtherInt.ValueAddr());

   cout << uc.EvalStr("OtherInt") << endl;
   cout << uc.EvalStr("ValueAt(yPtrB)") << endl;





}