Skip to content

Instantly share code, notes, and snippets.

@chrdek
Created October 11, 2025 11:06
Show Gist options
  • Select an option

  • Save chrdek/9a5ff5ec36426ede97641fac355198d0 to your computer and use it in GitHub Desktop.

Select an option

Save chrdek/9a5ff5ec36426ede97641fac355198d0 to your computer and use it in GitHub Desktop.
Fluent Syntax Calculator in Csharp (2 examples)
using System;
using System.Collections.Generic;
namespace Calc
{
public class FluentCalculator
{
private static readonly int[] Values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
private enum OperatorType
{
None,
Plus,
Minus,
Times,
DividedBy
}
private OperatorType lastType;
private double result;
private Stack<double> operandStack;
private Stack<OperatorType> operatorStack;
public FluentCalculator()
{
result = 0;
lastType = OperatorType.None;
operandStack = new Stack<double>();
operatorStack = new Stack<OperatorType>();
}
private FluentCalculator ApplyOperator(OperatorType operatorType)
{
while (operatorStack.Count > 0 && Precedence(operatorStack.Peek()) >= Precedence(operatorType))
{
ProcessStackTop();
}
operatorStack.Push(operatorType);
return this;
}
private FluentCalculator ApplyValue(double value)
{
operandStack.Push(value);
return this;
}
private void ProcessStackTop()
{
if (operandStack.Count < 2 || operatorStack.Count < 1)
{
// Handle error or throw exception if needed
return;
}
double operand2 = operandStack.Pop();
double operand1 = operandStack.Pop();
OperatorType op = operatorStack.Pop();
double result = PerformOperation(operand1, operand2, op);
operandStack.Push(result);
}
private double PerformOperation(double operand1, double operand2, OperatorType op)
{
switch (op)
{
case OperatorType.Plus:
return operand1 + operand2;
case OperatorType.Minus:
return operand1 - operand2;
case OperatorType.Times:
return operand1 * operand2;
case OperatorType.DividedBy:
if (operand2 != 0)
{
return operand1 / operand2;
}
else
{
// Handle division by zero error or throw exception if needed
return 0;
}
default:
// Handle other cases if necessary
return 0;
}
}
private int Precedence(OperatorType op)
{
switch (op)
{
case OperatorType.Plus:
case OperatorType.Minus:
return 1;
case OperatorType.Times:
case OperatorType.DividedBy:
return 2;
default:
return 0;
}
}
// Methods for numbers and operators (Zero, One, Two, etc.)
public FluentCalculator Zero => ApplyValue(0);
public FluentCalculator One => ApplyValue(1);
public FluentCalculator Two => ApplyValue(2);
public FluentCalculator Three => ApplyValue(3);
public FluentCalculator Four => ApplyValue(4);
public FluentCalculator Five => ApplyValue(5);
public FluentCalculator Six => ApplyValue(6);
public FluentCalculator Seven => ApplyValue(7);
public FluentCalculator Eight => ApplyValue(8);
public FluentCalculator Nine => ApplyValue(9);
public FluentCalculator Ten => ApplyValue(10);
public FluentCalculator Plus => ApplyOperator(OperatorType.Plus);
public FluentCalculator Minus => ApplyOperator(OperatorType.Minus);
public FluentCalculator Times => ApplyOperator(OperatorType.Times);
public FluentCalculator DividedBy => ApplyOperator(OperatorType.DividedBy);
// Result method to retrieve the finalized result
public double Result()
{
while (operatorStack.Count > 0)
{
ProcessStackTop();
}
return operandStack.Count > 0 ? operandStack.Peek() : 0;
}
// Evaluate method to retrieve the finalized result
public double Evaluate()
{
return Result();
}
// Implicit conversion operator
public static implicit operator double(FluentCalculator calculator)
{
return calculator.Result();
}
//Operator Overloads
public static double operator +(FluentCalculator left, double right)
{
left.ApplyValue(right);
return left.Result();
}
public static double operator *(FluentCalculator left, int right)
{
left.ApplyValue(right);
return left.Result();
}
// Add other operator overloads as needed
}
}
/***************************************Alternative Approach******************************************************/
using System;
using System.Collections.Generic;
namespace Calc
{
public class FluentCalculator
{
private static readonly int[] Values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
private enum OperatorType
{
None,
Plus,
Minus,
Times,
DividedBy
}
private OperatorType lastType;
private double result;
private Stack<double> operandStack;
private Stack<OperatorType> operatorStack;
public FluentCalculator()
{
result = 0;
lastType = OperatorType.None;
operandStack = new Stack<double>();
operatorStack = new Stack<OperatorType>();
}
private FluentCalculator ApplyOperator(OperatorType operatorType)
{
while (operatorStack.Count > 0 && Precedence(operatorStack.Peek()) >= Precedence(operatorType))
{
ProcessStackTop();
}
operatorStack.Push(operatorType);
return this;
}
private FluentCalculator ApplyValue(double value)
{
operandStack.Push(value);
return this;
}
private void ProcessStackTop()
{
if (operandStack.Count < 2 || operatorStack.Count < 1)
{
// Handle error or throw exception if needed
return;
}
double operand2 = operandStack.Pop();
double operand1 = operandStack.Pop();
OperatorType op = operatorStack.Pop();
double result = PerformOperation(operand1, operand2, op);
operandStack.Push(result);
}
private double PerformOperation(double operand1, double operand2, OperatorType op)
{
switch (op)
{
case OperatorType.Plus:
return operand1 + operand2;
case OperatorType.Minus:
return operand1 - operand2;
case OperatorType.Times:
return operand1 * operand2;
case OperatorType.DividedBy:
if (operand2 != 0)
{
return operand1 / operand2;
}
else
{
// Handle division by zero error or throw exception if needed
return 0;
}
default:
// Handle other cases if necessary
return 0;
}
}
private int Precedence(OperatorType op)
{
switch (op)
{
case OperatorType.Plus:
case OperatorType.Minus:
return 1;
case OperatorType.Times:
case OperatorType.DividedBy:
return 2;
default:
return 0;
}
}
// Methods for numbers and operators (Zero, One, Two, etc.)
public FluentCalculator Zero => ApplyValue(0);
public FluentCalculator One => ApplyValue(1);
public FluentCalculator Two => ApplyValue(2);
public FluentCalculator Three => ApplyValue(3);
public FluentCalculator Four => ApplyValue(4);
public FluentCalculator Five => ApplyValue(5);
public FluentCalculator Six => ApplyValue(6);
public FluentCalculator Seven => ApplyValue(7);
public FluentCalculator Eight => ApplyValue(8);
public FluentCalculator Nine => ApplyValue(9);
public FluentCalculator Ten => ApplyValue(10);
public FluentCalculator Plus => ApplyOperator(OperatorType.Plus);
public FluentCalculator Minus => ApplyOperator(OperatorType.Minus);
public FluentCalculator Times => ApplyOperator(OperatorType.Times);
public FluentCalculator DividedBy => ApplyOperator(OperatorType.DividedBy);
// Result method to retrieve the finalized result
public double Result()
{
while (operatorStack.Count > 0)
{
ProcessStackTop();
}
return operandStack.Count > 0 ? operandStack.Peek() : 0;
}
// Evaluate method to retrieve the finalized result
public double Evaluate()
{
return Result();
}
// Implicit conversion operator
public static implicit operator double(FluentCalculator calculator)
{
return calculator.Result();
}
//Operator Overloads
/*public static FluentCalculator operator *(FluentCalculator left, int right)
{
left.ApplyValue(right);
return left;
}
public static FluentCalculator operator +(FluentCalculator left, double right)
{
left.ApplyValue(right);
return left;
}*/
public static double operator +(FluentCalculator left, double right)
{
left.ApplyValue(right);
return left.Result();
}
public static double operator *(FluentCalculator left, int right)
{
left.ApplyValue(right);
return left.Result();
}
// Add other operator overloads as needed
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment