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

using namespace std;
using namespace uCalcSoftware;

void ucalc_call ShortCircuitOr(uCalcBase::Callback cb) {
   auto arg1 = cb.ArgExpr(1);
   auto arg2 = cb.ArgExpr(2);

   // Evaluate the first argument
   auto result1 = arg1.EvaluateBool();

   // If the first is true, return immediately without touching the second
   if (result1) {
      cb.ReturnBool(true);
   } else {
      // Otherwise, evaluate and return the second argument's result
      cb.ReturnBool(arg2.EvaluateBool());
   }
}

void ucalc_call FuncA(uCalcBase::Callback cb) {
   cb.uCalc().Eval("countA = countA + 1");
   cb.ReturnBool(true);
}

void ucalc_call FuncB(uCalcBase::Callback cb) {
   cb.uCalc().Eval("countB = countB + 1");
   cb.ReturnBool(true);
}

int main() {
   uCalc uc;
   uc.DefineVariable("countA = 0");
   uc.DefineVariable("countB = 0");

   uc.DefineFunction("FuncA() As Bool", FuncA);
   uc.DefineFunction("FuncB() As Bool", FuncB);

   uc.DefineFunction("SC_Or(ByExpr a, ByExpr b) As Bool", ShortCircuitOr);

   cout << "Calling SC_Or(FuncA(), FuncB())..." << endl;
   uc.Eval("SC_Or(FuncA(), FuncB())");

   cout << "FuncA was called " << uc.Eval("countA") << " time(s)." << endl;
   cout << "FuncB was called " << uc.Eval("countB") << " time(s)." << endl; // Should be 0
}