Skip to content

Instantly share code, notes, and snippets.

@ZacharyPatten
Last active November 21, 2019 11:56
Show Gist options
  • Save ZacharyPatten/1054c58cff7493f3eee8c3f41bd5a280 to your computer and use it in GitHub Desktop.
Save ZacharyPatten/1054c58cff7493f3eee8c3f41bd5a280 to your computer and use it in GitHub Desktop.
An example of custom Switch syntax in C#. :D
using System;
using static Towel.Syntax;
namespace Example
{
class Program
{
static void Main()
{
// I made custom Switch syntax. :D
// I don't recommend using this. It is slow and always evaluates
// in defined order (not to mention it allows multiple defaults).
// But it is fun to tinker with. :P
// Please check out the https://github.com/ZacharyPatten/Towel project. :)
// It has actually useful code (unlike this "Switch" garbage)...
Console.Write("With Parameter: ");
for (int i = 1; i <= 4; i++)
{
// Parameter
Switch (i)
(
(1, () => Console.Write(1 + ", ")),
(2, () => Console.Write(2 + ", ")),
(3, () => Console.Write(3 + ", ")),
(Default, () => Console.Write("Default"))
);
}
Console.WriteLine();
Console.Write("Without Parameter: ");
for (int i = 1; i <= 4; i++)
{
// No Parameter
Switch
(
(i == 1, () => Console.Write(1 + ", ")),
(i == 2, () => Console.Write(2 + ", ")),
(i == 3, () => Console.Write(3 + ", ")),
(Default, () => Console.Write("Default"))
);
}
Console.WriteLine();
Console.Write("Mixing Conditions & Values: ");
for (int i = 1; i <= 4; i++)
{
// Parameter + Conditions
Switch (i)
(
(1, () => Console.Write(1 + ", ")),
(i == 2, () => Console.Write(2 + ", ")),
(i % 3 == 0, () => Console.Write(3 + ", ")),
(Default, () => Console.Write("Default"))
);
}
Console.WriteLine();
}
}
}
#region Towel Definitions
namespace Towel
{
public static class Syntax
{
public const SwitchSyntax.Keyword Default = SwitchSyntax.Keyword.Default;
public static void Switch(params (SwitchSyntax.Condition, Action)[] possibleActions) =>
SwitchSyntax.Do(possibleActions);
public static SwitchSyntax.SwitchDelegate<T> Switch<T>(T value) =>
SwitchSyntax.Do<T>(value);
}
public static class SwitchSyntax
{
internal static SwitchDelegate<T> Do<T>(T value) =>
possibleActions =>
{
foreach (var possibleAction in possibleActions)
{
if (possibleAction.Condition.Resolve(value))
{
possibleAction.Action();
return;
}
}
};
internal static void Do(params (Condition Condition, Action Action)[] possibleActions)
{
foreach (var possibleAction in possibleActions)
{
if (possibleAction.Condition)
{
possibleAction.Action();
return;
}
}
}
public enum Keyword
{
Default,
}
public delegate void SwitchDelegate<T>(params (Condition<T> Condition, Action Action)[] possibleActions);
public abstract class Condition<T>
{
public abstract bool Resolve(T b);
public static implicit operator Condition<T>(T value) => new Value<T> { A = value, };
public static implicit operator Condition<T>(bool result) => new Bool<T> { Result = result, };
public static implicit operator Condition<T>(Keyword keyword) => new Default<T>();
}
internal class Value<T> : Condition<T>
{
internal T A;
public override bool Resolve(T b) => A.Equals(b);
}
internal class Bool<T> : Condition<T>
{
internal bool Result;
public override bool Resolve(T b) => Result;
}
internal class Default<T> : Condition<T>
{
public override bool Resolve(T b) => true;
}
public abstract class Condition
{
public abstract bool Resolve();
public static implicit operator Condition(bool result) => new Bool { Result = result, };
public static implicit operator Condition(Keyword keyword) => new Default();
public static implicit operator bool(Condition condition) => condition.Resolve();
}
internal class Bool : Condition
{
internal bool Result;
public override bool Resolve() => Result;
}
internal class Default : Condition
{
public override bool Resolve() => true;
}
}
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment