-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathproposition.go
199 lines (187 loc) · 4.94 KB
/
proposition.go
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package gisp
import (
px "github.com/Dwarfartisan/goparsec/parsex"
)
// Propositions 给出了一组常用的操作
var Propositions = Toolkit{
Meta: map[string]interface{}{
"name": "propositions",
"category": "package",
},
Content: map[string]interface{}{
"lambda": BoxExpr(LambdaExpr),
"let": BoxExpr(LetExpr),
"+": EvalExpr(ParsexExpr(addx)),
"add": EvalExpr(ParsexExpr(addx)),
"-": EvalExpr(ParsexExpr(subx)),
"sub": EvalExpr(ParsexExpr(subx)),
"*": EvalExpr(ParsexExpr(mulx)),
"mul": EvalExpr(ParsexExpr(mulx)),
"/": EvalExpr(ParsexExpr(divx)),
"div": EvalExpr(ParsexExpr(divx)),
"cmp": EvalExpr(cmpExpr),
"less": EvalExpr(lessExpr),
"<": EvalExpr(lessExpr),
"<?": EvalExpr(lsoExpr),
"<=": EvalExpr(leExpr),
"<=?": EvalExpr(leoExpr),
">": EvalExpr(greatExpr),
">?": EvalExpr(gtoExpr),
">=": EvalExpr(geExpr),
">=?": EvalExpr(geoExpr),
"==": EvalExpr(eqsExpr),
"==?": EvalExpr(eqsoExpr),
"!=": EvalExpr(neqsExpr),
"!=?": EvalExpr(neqsoExpr),
},
}
// ParsexExpr 是 parsex 算子的解析表达式
func ParsexExpr(pxExpr px.Parser) LispExpr {
return func(env Env, args ...interface{}) (Lisp, error) {
data, err := Evals(env, args...)
if err != nil {
return nil, err
}
st := px.NewStateInMemory(data)
ret, err := pxExpr(st)
if err != nil {
return nil, err
}
return Q(ret), nil
}
}
// ExtExpr 带扩展环境
func ExtExpr(extExpr func(env Env) px.Parser) LispExpr {
return func(env Env, args ...interface{}) (Lisp, error) {
data, err := Evals(env, args...)
if err != nil {
return nil, err
}
st := px.NewStateInMemory(data)
ret, err := extExpr(env)(st)
if err != nil {
return nil, err
}
return Q(ret), nil
}
}
// NotParsex 是 not 运算符
func NotParsex(pxExpr px.Parser) px.Parser {
return func(st px.ParsexState) (interface{}, error) {
b, err := pxExpr(st)
if err != nil {
return nil, err
}
if boolean, ok := b.(bool); ok {
return !boolean, nil
}
return nil, ParsexSignErrorf("Unknow howto not %v", b)
}
}
// ParsexReverseExpr 是倒排运算
func ParsexReverseExpr(pxExpr px.Parser) LispExpr {
return func(env Env, args ...interface{}) (Lisp, error) {
data, err := Evals(env, args...)
if err != nil {
return nil, err
}
l := len(data)
last := l - 1
datax := make([]interface{}, l)
for idx, item := range data {
datax[last-idx] = item
}
st := px.NewStateInMemory(data)
x, err := pxExpr(st)
if err != nil {
return nil, err
}
return Q(x), nil
}
}
// NotExpr 定义了 not 表达式
func NotExpr(expr LispExpr) LispExpr {
return func(env Env, args ...interface{}) (Lisp, error) {
element, err := expr(env, args...)
if err != nil {
return nil, err
}
ret, err := element.Eval(env)
if err != nil {
return nil, err
}
var b bool
if b, ok := ret.(bool); ok {
return Q(!b), nil
}
return nil, ParsexSignErrorf("Unknow howto not %v", b)
}
}
// OrExpr 是 or 表达式
func OrExpr(x, y px.Parser) LispExpr {
return func(env Env, args ...interface{}) (Lisp, error) {
data, err := Evals(env, args...)
if err != nil {
return nil, err
}
st := px.NewStateInMemory(data)
rex, err := x(st)
if err != nil {
return nil, err
}
if b, ok := rex.(bool); ok {
if b {
return Q(true), nil
}
st.SeekTo(0)
rex, err = y(st)
if err != nil {
return nil, err
}
return Q(rex), nil
}
return nil, ParsexSignErrorf("Unknow howto combine %v or %v for %v", x, y, data)
}
}
// OrExtExpr 定了带环境扩展的 or 表达式
func OrExtExpr(x, y func(Env) px.Parser) LispExpr {
return func(env Env, args ...interface{}) (Lisp, error) {
return OrExpr(x(env), y(env))(env, args...)
}
}
// OrExtRExpr 定了带环境扩展的 or 逆向表达式
func OrExtRExpr(x px.Parser, y func(Env) px.Parser) LispExpr {
return func(env Env, args ...interface{}) (Lisp, error) {
return OrExpr(x, y(env))(env, args...)
}
}
// ExtReverseExpr 定了带环境扩展的倒排表达式
func ExtReverseExpr(expr func(Env) px.Parser) LispExpr {
return func(env Env, args ...interface{}) (Lisp, error) {
return ParsexReverseExpr(expr(env))(env, args...)
}
}
var addExpr = ParsexExpr(addx)
var subExpr = ParsexExpr(subx)
var mulExpr = ParsexExpr(mulx)
var divExpr = ParsexExpr(divx)
var lessExpr = ExtExpr(less)
var lsoExpr = ExtExpr(lessOption)
var leExpr = OrExtRExpr(equals, less)
var leoExpr = OrExtRExpr(equalsOption, lessOption)
var cmpExpr = ParsexExpr(compare)
var greatExpr = ExtReverseExpr(less)
var gtoExpr = ExtReverseExpr(lessOption)
var geExpr = OrExtRExpr(equals, less)
var geoExpr = func(env Env, args ...interface{}) (Lisp, error) {
st := px.NewStateInMemory(args)
ret, err := px.Choice(px.Try(NotParsex(less(env))), FalseIfHasNil)(st)
if err != nil {
return nil, err
}
return Q(ret), nil
}
var eqsExpr = ParsexExpr(equals)
var eqsoExpr = ParsexExpr(equalsOption)
var neqsExpr = NotExpr(eqsExpr)
var neqsoExpr = ParsexExpr(neqsOption)