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

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uc.DefineVariable("x = 123");

   uCalc uc1; // Creates a new instance
   cout << uc1.EvalStr("x") << endl; // uc1 does not have a variable named x
   uc1.Release(); // Releases uc1 if it is no longer needed

   auto uc2 = uc.Clone(); // Creates new instance that is a clone of uc
   cout << uc2.EvalStr("x") << endl; // starts with the value of x obtained from uc
   uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc
   cout << uc2.EvalStr("x") << endl;
   cout << uc.EvalStr("x") << endl; // The original x in uc remains unchanged
   uc2.Release();

   // Language specific - auto-releasing uCalc object

   { // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
      auto uCalc1 = new uCalc();
      auto uCalc2 = uc.Clone();
      // Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
   }

   { // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
      
      uCalc uCalc1;
      uCalc uCalc2(uc.Clone());
      // No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
   }

}