#include #include "uCalc.h" using namespace std; using namespace uCalcSoftware; void ucalc_call AssignValueA(uCalcBase::Callback cb) { cb.uCalc().DataTypeOf(BuiltInType::Integer_64).SetScalar(cb.ArgPtr(1), cb.ArgAddr(2)); // C++ can do it with pointers instead like the commented line below: // *(int64_t *)cb.ArgInt64(1) = cb.ArgInt64(2); } void ucalc_call AssignValueB(uCalcBase::Callback cb) { if (cb.ArgItem(1).DataType().BuiltInTypeEnum() == BuiltInType::String) { cb.ArgItem(1).ValueStr(cb.ArgItem(2).ValueStr()); } else { cb.ArgItem(1).DataType().SetScalar(cb.ArgItem(1).ValueAddr(), cb.ArgItem(2).ValueAddr()); } } int main() { uCalc uc; // ByRef approach (only for primitive types only, like double, int, etc., not composite types like strings) cout << "-- ByRef approach --" << endl; uc.DefineOperator("{ByRef variable As AnyType} SetValA {value As SameTypeAs:0} As SameTypeAs:0", uc.ItemOf("=").Precedence(), Associativity::RightToLeft, AssignValueA); uc.DefineVariable("MyDbl As Double"); uc.DefineVariable("MyInt As Int"); uc.DefineVariable("MyStr As String"); uc.Eval("MyDbl SetValA 3.14"); uc.Eval("MyInt SetValA Int(3.14 * 10)"); cout << "MyDbl: " + uc.EvalStr("MyDbl") << endl; cout << "MyInt: " + uc.EvalStr("MyInt") << endl; // ByHandle approach cout << "-- ByHandle approach --" << endl; uc.DefineOperator("{ByHandle variable As AnyType} SetValB {ByHandle val As SameTypeAs:0}", uc.ItemOf("=").Precedence(), Associativity::RightToLeft, AssignValueB); uc.Eval("MyDbl SetValB 123.456"); uc.Eval("MyInt SetValB Int(555.123)"); uc.Eval("MyStr SetValB 'Hello World'"); cout << "MyDbl: " + uc.EvalStr("MyDbl") << endl; cout << "MyInt: " + uc.EvalStr("MyInt") << endl; cout << "MyStr: " + uc.EvalStr("MyStr") << endl; }