#include #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; cout << "------ Basic examples -------" << endl; uc.Define("Function: f(x, y) = x + y"); uc.Define("Operator: {x} %% {y} = x * y"); uc.Define("Variable: MyVar = 123"); cout << uc.Eval("f(5, 10)") << endl; cout << uc.Eval("5 %% 10") << endl; cout << uc.Eval("MyVar * 100") << endl; // End users can also call Define() cout << "------ End user definition -------" << endl; uc.Eval("Define('Function: ff(x) = x * 1000')"); cout << uc.Eval("ff(987)") << endl; cout << "------ Boolean format -------" << endl; cout << uc.EvalStr("1 < 2") << endl; cout << uc.EvalStr("1 > 2") << endl; cout << uc.EvalStr("Int(1 < 2)") << endl; cout << uc.EvalStr("(True Or False) And (True And False)") << endl; uc.Define("Boolean: 55, TotallyTrue, CompletelyFalse"); cout << uc.EvalStr("1 < 2") << endl; cout << uc.EvalStr("1 > 2") << endl; cout << uc.EvalStr("Int(1 < 2)") << endl; cout << uc.EvalStr("(TotallyTrue Or CompletelyFalse) And (TotallyTrue And CompletelyFalse)") << endl; // Format - configures the formatting for the output given by EvalStr cout << "------ Format -------" << endl; uc.Define("Format: Result = 'Answer: <' + Result + '>'"); uc.Define("Format: String, val = 'String Value --> ' + val"); cout << uc.EvalStr("1+2") << endl; cout << uc.EvalStr("'Hello ' + 'world!'") << endl; auto Additional = uc.Define("Format: ret = 'Additional format: ' + ret"); cout << uc.EvalStr("1+2") << endl; uc.Define("Format: InsertAt: 0, result = 'The ' + result"); cout << uc.EvalStr("1+2") << endl; Additional.Release(); cout << uc.EvalStr("1+2") << endl; uc.FormatRemove(); // Bootstrap - builds new def on top of existing one cout << "------ Bootstrap -------" << endl; cout << uc.EvalStr("Hex(123)") << endl; // uses "built-in" version of Hex() auto MyHex = uc.Define("Bootstrap ~~ Function: Hex(number As Int) As String = '0x' + UCase(Hex(number))"); cout << uc.EvalStr("Hex(123)") << endl; MyHex.Release(); cout << uc.EvalStr("Hex(123)") << endl; // Overwrite - useful for spreadsheet-like functionality cout << "------ Overwrite -------" << endl; uc.Define("Overwrite ~~ Func: SpreadsheetCell_A1() = 5"); uc.Define("Overwrite ~~ Func: SpreadsheetCell_B2() = SpreadsheetCell_A1() * 10"); uc.Define("Overwrite ~~ Func: SpreadsheetCell_C3() = SpreadsheetCell_A1() + SpreadsheetCell_B2()"); cout << uc.Eval("SpreadsheetCell_A1()") << endl; cout << uc.Eval("SpreadsheetCell_B2()") << endl; cout << uc.Eval("SpreadsheetCell_C3()") << endl; // SpreadsheetCell_C3() will be affected by the definition changes of SpreadsheetCell_A1() and SpreadsheetCell_B3() uc.Define("Overwrite ~~ Func: SpreadsheetCell_B2() = SpreadsheetCell_A1() * 100"); uc.Define("Overwrite ~~ Func: SpreadsheetCell_A1() = 25"); cout << "-------" << endl; // Note: Empty parenthesis are optional for functions with no parameters cout << uc.Eval("SpreadsheetCell_A1") << endl; cout << uc.Eval("SpreadsheetCell_B2") << endl; cout << uc.Eval("SpreadsheetCell_C3") << endl; // Lock cout << "------ Lock -------" << endl; uc.Define("Variable: xy = 555"); uc.Define("Lock ~~ Variable: pi = 3.14"); // like using DefineConstant() cout << uc.EvalStr("xy") << endl; cout << uc.EvalStr("pi") << endl; cout << uc.EvalStr("xy = 222") << endl; // This variable is being changed cout << uc.EvalStr("pi = 3.14159") << endl; // This one is locked and cannot be changed cout << uc.EvalStr("xy") << endl; // Returns the new value of xy cout << uc.EvalStr("pi") << endl; // pi did not change; returns original value cout << "-------" << endl; uc.Define("Function: f1(x) = x + 100"); uc.Define("Lock ~~ Function: f2(x) = x + 200"); // End-user can't change f2 cout << uc.Eval("f1(5)") << endl; cout << uc.Eval("f2(5)") << endl; uc.Eval("Define('Function: f1(x) = x + 300')"); uc.Eval("Define('Function: f2(x) = x + 400')"); // This re-definition is ignored cout << uc.Eval("f1(5)") << endl; cout << uc.Eval("f2(5)") << endl; // Tokens cout << "------ Tokens -------" << endl; cout << uc.EvalStr("5 + 4 // This comment causes an error") << endl; cout << uc.EvalStr("5 + /* comment not recognized yet */ 10") << endl; uc.Define("TokenType: Whitespace ~~ Token: //.*"); // // C-style to end-of-line comment uc.Define("TokenType: Whitespace ~~ Token: /[*].*?[*]/"); // /* C-style enclosed comment */ cout << uc.EvalStr("5 + 4 // This comment will be ignored") << endl; cout << uc.EvalStr("5 + /* comment ignored */ 10") << endl; // Precedence cout << "------ Precedence -------" << endl; uc.Define("Precedence: 1 ~~ Operator: {a As Int32} OpA {b As Int32} = a + b"); uc.Define("Precedence: 1000 ~~ Operator: {a As Int32} OpB {b As Int32} = a + b"); cout << uc.Eval("5 OpA 4 * 10") << endl; cout << uc.Eval("5 OpB 4 * 10") << endl; // Associativity cout << "------ Associativity -------" << endl; uc.Define("Associativity: LeftToRight ~~ Operator: {x} OpX {y} = x / y"); uc.Define("Associativity: RightToLeft ~~ Operator: {x} OpY {y} = x / y"); cout << uc.Eval("3 OpX 4 OpX 5") << endl; cout << uc.Eval("3 OpY 4 OpY 5") << endl; }