A practical LISP interpreter that handles variadic (multiple arguments) and nested expressions.

ID: 1417

				
					using uCalcSoftware;

var uc = new uCalc();
var t = uc.NewTransformer();
t.DefaultRuleSet.RewindOnChange = true;

// {@@Eval} evaluates the expression obtained by concatinating the captured
// elements {op} for operator, and {a} and {b} for the two numbers.
// These elements are strings and do not need curly braces within {@@Eval}
// :1 tels it to capture one token at a time.
t.FromTo("({op:1} {a:1} {b:1})", "{@@Eval: a + op + b}");

// If there are more than to numbers, as indicated by {more}, then the first
// two numbers are evaluated and put back into the list.  The operator remains.
t.FromTo("({op:1} {a:1} {b:1} {more})", "({op} {@@Eval: a + op + b} {more})");

// If a nested expression is present, it is evaluated immediately, by using
// % in {expr%} and the section is reprocessed again with the resulting value
// since .@RewindOnChange(true) was set.
t.FromTo("({op:1} {expr%: ({exp})}", "({op} {expr}");
t.FromTo("({op:1} {a:1} {expr%: ({exp})}", "({op} {a} {expr}");

// --- Test Cases ---
Console.WriteLine("--- Simple Binary ---");
var expr = "(- 100 25)";
Console.WriteLine($"LISP: {expr}");
Console.WriteLine($"Result: {t.Transform(expr)}");
Console.WriteLine("");

Console.WriteLine("--- Variadic (Multiple Args) ---");
expr = "(* 2 3 4)";
Console.WriteLine($"LISP: {expr}");
Console.WriteLine($"Result: {t.Transform(expr)}");
Console.WriteLine("");

Console.WriteLine("--- Nested Expressions ---");
expr = "(/ 100 (+ 5 5))";
Console.WriteLine($"LISP: {expr}");
Console.WriteLine($"Result: {t.Transform(expr)}");
expr = "(+ (* (- 100 (/ 80 4)) 3) (- (* (+ 5 3) (- 12 7)) (+ (* 2 3) 4)))";
Console.WriteLine($"LISP: {expr}");
Console.WriteLine($"Result: {t.Transform(expr)}");
Console.WriteLine("");
				
			
--- Simple Binary ---
LISP: (- 100 25)
Result: 75

--- Variadic (Multiple Args) ---
LISP: (* 2 3 4)
Result: 24

--- Nested Expressions ---
LISP: (/ 100 (+ 5 5))
Result: 10
LISP: (+ (* (- 100 (/ 80 4)) 3) (- (* (+ 5 3) (- 12 7)) (+ (* 2 3) 4)))
Result: 270
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto t = uc.NewTransformer();
   t.DefaultRuleSet().RewindOnChange(true);

   // {@@Eval} evaluates the expression obtained by concatinating the captured
   // elements {op} for operator, and {a} and {b} for the two numbers.
   // These elements are strings and do not need curly braces within {@@Eval}
   // :1 tels it to capture one token at a time.
   t.FromTo("({op:1} {a:1} {b:1})", "{@@Eval: a + op + b}");

   // If there are more than to numbers, as indicated by {more}, then the first
   // two numbers are evaluated and put back into the list.  The operator remains.
   t.FromTo("({op:1} {a:1} {b:1} {more})", "({op} {@@Eval: a + op + b} {more})");

   // If a nested expression is present, it is evaluated immediately, by using
   // % in {expr%} and the section is reprocessed again with the resulting value
   // since .@RewindOnChange(true) was set.
   t.FromTo("({op:1} {expr%: ({exp})}", "({op} {expr}");
   t.FromTo("({op:1} {a:1} {expr%: ({exp})}", "({op} {a} {expr}");

   // --- Test Cases ---
   cout << "--- Simple Binary ---" << endl;
   auto expr = "(- 100 25)";
   cout << "LISP: " << expr << endl;
   cout << "Result: " << t.Transform(expr) << endl;
   cout << "" << endl;

   cout << "--- Variadic (Multiple Args) ---" << endl;
   expr = "(* 2 3 4)";
   cout << "LISP: " << expr << endl;
   cout << "Result: " << t.Transform(expr) << endl;
   cout << "" << endl;

   cout << "--- Nested Expressions ---" << endl;
   expr = "(/ 100 (+ 5 5))";
   cout << "LISP: " << expr << endl;
   cout << "Result: " << t.Transform(expr) << endl;
   expr = "(+ (* (- 100 (/ 80 4)) 3) (- (* (+ 5 3) (- 12 7)) (+ (* 2 3) 4)))";
   cout << "LISP: " << expr << endl;
   cout << "Result: " << t.Transform(expr) << endl;
   cout << "" << endl;
}
				
			
--- Simple Binary ---
LISP: (- 100 25)
Result: 75

--- Variadic (Multiple Args) ---
LISP: (* 2 3 4)
Result: 24

--- Nested Expressions ---
LISP: (/ 100 (+ 5 5))
Result: 10
LISP: (+ (* (- 100 (/ 80 4)) 3) (- (* (+ 5 3) (- 12 7)) (+ (* 2 3) 4)))
Result: 270
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      t.DefaultRuleSet.RewindOnChange = true
      
      '// {@@Eval} evaluates the expression obtained by concatinating the captured
      '// elements {op} for operator, and {a} and {b} for the two numbers.
      '// These elements are strings and do not need curly braces within {@@Eval}
      '// :1 tels it to capture one token at a time.
      t.FromTo("({op:1} {a:1} {b:1})", "{@@Eval: a + op + b}")
      
      '// If there are more than to numbers, as indicated by {more}, then the first
      '// two numbers are evaluated and put back into the list.  The operator remains.
      t.FromTo("({op:1} {a:1} {b:1} {more})", "({op} {@@Eval: a + op + b} {more})")
      
      '// If a nested expression is present, it is evaluated immediately, by using
      '// % in {expr%} and the section is reprocessed again with the resulting value
      '// since .@RewindOnChange(true) was set.
      t.FromTo("({op:1} {expr%: ({exp})}", "({op} {expr}")
      t.FromTo("({op:1} {a:1} {expr%: ({exp})}", "({op} {a} {expr}")
      
      '// --- Test Cases ---
      Console.WriteLine("--- Simple Binary ---")
      Dim expr = "(- 100 25)"
      Console.WriteLine($"LISP: {expr}")
      Console.WriteLine($"Result: {t.Transform(expr)}")
      Console.WriteLine("")
      
      Console.WriteLine("--- Variadic (Multiple Args) ---")
      expr = "(* 2 3 4)"
      Console.WriteLine($"LISP: {expr}")
      Console.WriteLine($"Result: {t.Transform(expr)}")
      Console.WriteLine("")
      
      Console.WriteLine("--- Nested Expressions ---")
      expr = "(/ 100 (+ 5 5))"
      Console.WriteLine($"LISP: {expr}")
      Console.WriteLine($"Result: {t.Transform(expr)}")
      expr = "(+ (* (- 100 (/ 80 4)) 3) (- (* (+ 5 3) (- 12 7)) (+ (* 2 3) 4)))"
      Console.WriteLine($"LISP: {expr}")
      Console.WriteLine($"Result: {t.Transform(expr)}")
      Console.WriteLine("")
   End Sub
End Module
				
			
--- Simple Binary ---
LISP: (- 100 25)
Result: 75

--- Variadic (Multiple Args) ---
LISP: (* 2 3 4)
Result: 24

--- Nested Expressions ---
LISP: (/ 100 (+ 5 5))
Result: 10
LISP: (+ (* (- 100 (/ 80 4)) 3) (- (* (+ 5 3) (- 12 7)) (+ (* 2 3) 4)))
Result: 270