Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Console.WriteLine("---- Simple function def ----")
      uc.DefineFunction("f(x) = x ^ 2 + 5")
      Console.WriteLine(uc.Eval("f(10)"))
      
      Console.WriteLine("---- Function overloading ----")
      '// Overloading based on parameter type or number of parameters
      uc.DefineFunction("MyOverload(x As Double) = x + x")
      uc.DefineFunction("MyOverload(x As String) As String = x + x")
      uc.DefineFunction("MyOverload(x As String, y As String) As String = x + y")
      uc.DefineFunction("MyOverload(x, y) = x + y")
      Console.WriteLine(uc.EvalStr("MyOverload(5)"))
      Console.WriteLine(uc.EvalStr("MyOverload('Ha')"))
      Console.WriteLine(uc.EvalStr("MyOverload('Hello ', 'world!')"))
      Console.WriteLine(uc.EvalStr("MyOverload(5, 10)"))
      
      Console.WriteLine("---- Definition hiding/un-hiding ----")
      '// Shadowing (hiding) definitions
      uc.DefineFunction("h(x) = x * 10")
      Console.WriteLine(uc.Eval("h(3)"))
      Dim hFunc = uc.DefineFunction("h(x) = x * 100") '// hides previous def
      Console.WriteLine(uc.Eval("h(3)"))
      hFunc.Release() '// Releasing this restores previous def
      Console.WriteLine(uc.Eval("h(3)"))
      
      Console.WriteLine("---- Optional parameters ----")
      uc.DefineFunction("Opt(x, y = 5, z As String = 'Hello') = x + y + Length(z)")
      Console.WriteLine(uc.Eval("Opt(10)"))
      Console.WriteLine(uc.Eval("Opt(10, 20)"))
      Console.WriteLine(uc.Eval("Opt(10, 20, 'Just a test 123')"))
      
      Console.WriteLine("---- Recursion ----")
      uc.DefineFunction("Factorial(x) = iif(x > 1, x * Factorial(x - 1), 1)")
      uc.DefineFunction("Fib(n) = IIf(n < 2, n, Fib(n - 1) + Fib(n - 2))")
      Console.WriteLine(uc.Eval("Factorial(5)"))
      Console.WriteLine(uc.Eval("Fib(10)"))
      
      '// Bootstrap - builds new def on top of existing one
      Console.WriteLine("------ Bootstrapping -------")
      Console.WriteLine(uc.EvalStr("Hex(123)")) '// uses "built-in" version of Hex()
      
      
      Dim MyHex = uc.DefineFunction("Hex(number As Int) As String = '0x' + UCase(Hex(number))", bootstrap:=True)
      Console.WriteLine(uc.EvalStr("Hex(123)"))
      MyHex.Release()
      Console.WriteLine(uc.EvalStr("Hex(123)"))
      
      '// Overwrite - useful for spreadsheet-like functionality
      Console.WriteLine("------ Overwrite -------")
      
      
      uc.DefineFunction("SpreadsheetCell_A1() = 5", overwrite:=true)
      uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 10", Overwrite:=true)
      uc.DefineFunction("SpreadsheetCell_C3() = SpreadsheetCell_A1() + SpreadsheetCell_B2()", overwrite:=true)
      Console.WriteLine(uc.Eval("SpreadsheetCell_A1()"))
      Console.WriteLine(uc.Eval("SpreadsheetCell_B2()"))
      Console.WriteLine(uc.Eval("SpreadsheetCell_C3()"))
      '// SpreadsheetCell_C3() will be affected by the definition changes of SpreadsheetCell_A1() and  SpreadsheetCell_B3()
      
      
      uc.DefineFunction("SpreadsheetCell_B2() = SpreadsheetCell_A1() * 100", overwrite:=true)
      uc.DefineFunction("SpreadsheetCell_A1() = 25", overwrite:=true)
      Console.WriteLine("-------")
      '// Note: Empty parenthesis are optional for functions with no parameters
      Console.WriteLine(uc.Eval("SpreadsheetCell_A1"))
      Console.WriteLine(uc.Eval("SpreadsheetCell_B2"))
      Console.WriteLine(uc.Eval("SpreadsheetCell_C3"))
      
      '// See Define() topic for more
      
      
      
      
      
   End Sub
End Module