-
-
Notifications
You must be signed in to change notification settings - Fork 424
/
Copy pathOperators.cs
105 lines (86 loc) · 3.51 KB
/
Operators.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System;
using LanguageExt;
using static LanguageExt.Prelude;
namespace LanguageExt.Parsec
{
public enum Assoc
{
None,
Left,
Right
}
public enum OperatorTag
{
Infix,
Prefix,
Postfix
}
public static partial class Operator
{
public static Operator<A> Infix<A>(Assoc assoc, Parser<Func<A, A, A>> p) =>
new InfixOp<A>(assoc, p);
public static Operator<A> Prefix<A>(Parser<Func<A, A>> p) =>
new PrefixOp<A>(p);
public static Operator<A> Postfix<A>(Parser<Func<A, A>> p) =>
new PostfixOp<A>(p);
}
public abstract class Operator<A>
{
public readonly OperatorTag Tag;
public Operator(OperatorTag tag)
{
Tag = tag;
}
public abstract (Seq<Parser<Func<A,A,A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) SplitOp(
(Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) state);
}
public class InfixOp<A> : Operator<A>
{
public readonly Assoc Assoc;
public readonly Parser<Func<A, A, A>> Op;
internal InfixOp(Assoc assoc, Parser<Func<A, A, A>> p)
:
base(OperatorTag.Infix)
{
Assoc = assoc;
Op = p;
}
public override (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) SplitOp(
(Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) state) =>
state.Map(
(rassoc, lassoc, nassoc, prefix, postfix) =>
Assoc == Assoc.None ? (rassoc, lassoc, Op.Cons(nassoc), prefix, postfix)
: Assoc == Assoc.Left ? (rassoc, Op.Cons(lassoc), nassoc, prefix, postfix)
: (Op.Cons(rassoc), lassoc, nassoc, prefix, postfix));
}
public class PrefixOp<A> : Operator<A>
{
public readonly Parser<Func<A, A>> Op;
internal PrefixOp(Parser<Func<A, A>> p)
:
base(OperatorTag.Prefix)
{
Op = p;
}
public override (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) SplitOp(
(Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) state) =>
state.Map(
(rassoc, lassoc, nassoc, prefix, postfix) =>
(rassoc, lassoc, nassoc, Op.Cons(prefix), postfix));
}
public class PostfixOp<A> : Operator<A>
{
public readonly Parser<Func<A, A>> Op;
internal PostfixOp(Parser<Func<A, A>> p)
:
base(OperatorTag.Postfix)
{
Op = p;
}
public override (Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) SplitOp(
(Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A, A>>>, Seq<Parser<Func<A, A>>>, Seq<Parser<Func<A, A>>>) state) =>
state.Map(
(rassoc, lassoc, nassoc, prefix, postfix) =>
(rassoc, lassoc, nassoc, prefix, Op.Cons(postfix)));
}
}