-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlet.go
157 lines (143 loc) · 3.52 KB
/
let.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
package gisp
import (
"fmt"
px "github.com/Dwarfartisan/goparsec/parsex"
)
// Let 实现 let 环境
type Let struct {
Meta map[string]interface{}
Content List
}
// LetFunc 构造一个 Let 环境
func LetFunc(env Env, args ...interface{}) (Lisp, error) {
st := px.NewStateInMemory(args)
_, err := TypeAs(LIST)(st)
if err != nil {
return nil, ParsexSignErrorf("Let Args Error: except args list but error: %v", err)
}
local := map[string]Var{}
vars := args[0].(List)
for _, v := range vars {
declares := v.(List)
varb := declares[0].(Atom)
slot := VarSlot(varb.Type)
value, err := Eval(env, (declares[1]))
if err != nil {
return nil, err
}
slot.Set(value)
local[varb.Name] = slot
}
meta := map[string]interface{}{
"local": local,
}
let := Let{meta, args}
return let, nil
}
// LetExpr 将 let => (let ((a, value), (b, value)...) ...) 形式构造为一个 let 环境
func LetExpr(env Env, args ...interface{}) (Tasker, error) {
var (
vars List
ok bool
)
if len(args) < 1 {
return nil, ParsexSignErrorf("let args error: except vars list at last but a empty let as (let )")
}
if vars, ok = args[0].(List); !ok {
return nil, ParsexSignErrorf("let args error: except vars list but %v", args[0])
}
return func(env Env) (interface{}, error) {
local := map[string]Var{}
for _, v := range vars {
declares := v.(List)
varb := declares[0].(Atom)
slot := VarSlot(varb.Type)
value, err := Eval(env, (declares[1]))
if err != nil {
return nil, err
}
slot.Set(value)
local[varb.Name] = slot
}
meta := map[string]interface{}{
"local": local,
}
let := Let{meta, args[1:]}
return let.Eval(env)
}, nil
}
// Defvar 实现 Env.Defvar
func (let Let) Defvar(name string, slot Var) error {
if _, ok := let.Local(name); ok {
return fmt.Errorf("local name %s is exists", name)
}
local := let.Meta["local"].(map[string]Var)
local[name] = slot
return nil
}
// Defun 实现 Env.Defun
func (let Let) Defun(name string, functor Functor) error {
if s, ok := let.Local(name); ok {
switch slot := s.(type) {
case Func:
slot.Overload(functor)
case Var:
return fmt.Errorf("%s defined as a var", name)
default:
return fmt.Errorf("exists name %s isn't Expr", name)
}
}
local := let.Meta["local"].(map[string]interface{})
local[name] = NewFunction(name, let, functor)
return nil
}
// Setvar 实现 Env.Setvar
func (let Let) Setvar(name string, value interface{}) error {
if _, ok := let.Local(name); ok {
local := let.Meta["local"].(map[string]Var)
local[name].Set(value)
return nil
}
global := let.Meta["global"].(Env)
return global.Setvar(name, value)
}
// Local 实现 Env.Local
func (let Let) Local(name string) (interface{}, bool) {
local := let.Meta["local"].(map[string]Var)
if slot, ok := local[name]; ok {
return slot.Get(), true
}
return nil, false
}
// Lookup 实现 Env.Lookup
func (let Let) Lookup(name string) (interface{}, bool) {
if value, ok := let.Local(name); ok {
return value, true
}
return let.Global(name)
}
// Global 实现 Env.Global
func (let Let) Global(name string) (interface{}, bool) {
global := let.Meta["global"].(Env)
return global.Lookup(name)
}
// Eval 实现 Lisp.Eval
func (let Let) Eval(env Env) (interface{}, error) {
let.Meta["global"] = env
l := len(let.Content)
switch l {
case 0:
return nil, nil
case 1:
return Eval(let, let.Content[0])
default:
for _, Expr := range let.Content[:l-1] {
_, err := Eval(let, Expr)
if err != nil {
return nil, err
}
}
Expr := let.Content[l-1]
return Eval(let, Expr)
}
}