Internal Test: An advanced example that adds logging to each transaction to trace the balance changes, showing how DSLs can be combined with custom functions.

ID: 1332

				
					using uCalcSoftware;

var uc = new uCalc();

static void LogBalance(uCalc.Callback cb) {
   // Get the message and the current balance to log
   var msg = cb.ArgStr(1);
   var bal = cb.uCalc.Eval("balance");
   Console.WriteLine($"[LOG] {msg} | New Balance: {bal}");
}


// 1. Initialize the balance and the logger function
uc.DefineVariable("balance = 0");
uc.DefineFunction("LOG(msg As String)", LogBalance);

// 2. Define DSL rules that also call the LOG function
var t = uc.ExpressionTransformer;

// Each rule now has a side effect: logging its action.
t.FromTo("DEPOSIT {@Number:amount}",
"balance = balance + {amount}; LOG('Deposited {amount}')");
t.FromTo("WITHDRAW {@Number:amount}",
"balance = balance - {amount}; LOG('Withdrew {amount}')");

// 3. A longer script to test the log
var script = """

DEPOSIT 500
WITHDRAW 100
DEPOSIT 250
WITHDRAW 75

""";

Console.WriteLine("--- Transaction Log ---");
uc.EvalStr(script);
Console.WriteLine("-----------------------");

Console.WriteLine($"Final Balance: {uc.Eval("balance")}");
				
			
--- Transaction Log ---
[LOG] Deposited 500 | New Balance: 500
[LOG] Withdrew 100 | New Balance: 400
[LOG] Deposited 250 | New Balance: 650
[LOG] Withdrew 75 | New Balance: 575
-----------------------
Final Balance: 575
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

void ucalc_call LogBalance(uCalcBase::Callback cb) {
   // Get the message and the current balance to log
   auto msg = cb.ArgStr(1);
   auto bal = cb.uCalc().Eval("balance");
   cout << "[LOG] " << msg << " | New Balance: " << bal << endl;
}

int main() {
   uCalc uc;
   // 1. Initialize the balance and the logger function
   uc.DefineVariable("balance = 0");
   uc.DefineFunction("LOG(msg As String)", LogBalance);

   // 2. Define DSL rules that also call the LOG function
   auto t = uc.ExpressionTransformer();

   // Each rule now has a side effect: logging its action.
   t.FromTo("DEPOSIT {@Number:amount}",
   "balance = balance + {amount}; LOG('Deposited {amount}')");
   t.FromTo("WITHDRAW {@Number:amount}",
   "balance = balance - {amount}; LOG('Withdrew {amount}')");

   // 3. A longer script to test the log
   auto script = R"(
DEPOSIT 500
WITHDRAW 100
DEPOSIT 250
WITHDRAW 75
)";

   cout << "--- Transaction Log ---" << endl;
   uc.EvalStr(script);
   cout << "-----------------------" << endl;

   cout << "Final Balance: " << uc.Eval("balance") << endl;
}
				
			
--- Transaction Log ---
[LOG] Deposited 500 | New Balance: 500
[LOG] Withdrew 100 | New Balance: 400
[LOG] Deposited 250 | New Balance: 650
[LOG] Withdrew 75 | New Balance: 575
-----------------------
Final Balance: 575
				
					Imports System
Imports uCalcSoftware
Public Module Program
   
   Public Sub LogBalance(ByVal cb As uCalc.Callback)
      '// Get the message and the current balance to log
      Dim msg = cb.ArgStr(1)
      Dim bal = cb.uCalc.Eval("balance")
      Console.WriteLine($"[LOG] {msg} | New Balance: {bal}")
   End Sub
   
   Public Sub Main()
      Dim uc As New uCalc()
      '// 1. Initialize the balance and the logger function
      uc.DefineVariable("balance = 0")
      uc.DefineFunction("LOG(msg As String)", AddressOf LogBalance)
      
      '// 2. Define DSL rules that also call the LOG function
      Dim t = uc.ExpressionTransformer
      
      '// Each rule now has a side effect: logging its action.
      t.FromTo("DEPOSIT {@Number:amount}",
      "balance = balance + {amount}; LOG('Deposited {amount}')")
      t.FromTo("WITHDRAW {@Number:amount}",
      "balance = balance - {amount}; LOG('Withdrew {amount}')")
      
      '// 3. A longer script to test the log
      Dim script = "
DEPOSIT 500
WITHDRAW 100
DEPOSIT 250
WITHDRAW 75
"
      
      Console.WriteLine("--- Transaction Log ---")
      uc.EvalStr(script)
      Console.WriteLine("-----------------------")
      
      Console.WriteLine($"Final Balance: {uc.Eval("balance")}")
   End Sub
End Module
				
			
--- Transaction Log ---
[LOG] Deposited 500 | New Balance: 500
[LOG] Withdrew 100 | New Balance: 400
[LOG] Deposited 250 | New Balance: 650
[LOG] Withdrew 75 | New Balance: 575
-----------------------
Final Balance: 575