-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathfunction.go
137 lines (119 loc) · 2.98 KB
/
function.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
package gisp
import (
"fmt"
)
// TypeSignError 定义签名错误
type TypeSignError struct {
Type Type
Value interface{}
}
func (err TypeSignError) Error() string {
return fmt.Sprintf("%v can't match %v", err.Value, err.Type)
}
// ParsexSignError 定义了在解析过程中遇到的签名错误
type ParsexSignError struct {
message string
args []interface{}
}
// ParsexSignErrorf 方法构造指定的 ParsexSignError
func ParsexSignErrorf(message string, args ...interface{}) ParsexSignError {
return ParsexSignError{message, args}
}
func (err ParsexSignError) Error() string {
return fmt.Sprintf(err.message, err.args...)
}
// Func 接口定义可以 Overload 的 Gisp 函数类型
type Func interface {
Functor
Name() string
Overload(functor Functor) error
Content() []Functor
}
// TaskBox 定义了可执行的 task 结构
type TaskBox struct {
task func(env Env) (interface{}, error)
}
// Eval 实现了 Task 的求值行为
func (tb TaskBox) Eval(env Env) (interface{}, error) {
return tb.task(env)
}
// Function 定义了 Gisp 函数实现
type Function struct {
atom Atom
Global Env
content []Functor
}
// NewFunction 构造一个新的 Function 对象
func NewFunction(name string, global Env, functor Functor) *Function {
return &Function{
atom: Atom{name, Type{ANY, false}},
Global: global,
content: []Functor{functor},
}
}
// Name 给出函数名
func (fun Function) Name() string {
return fun.atom.Name
}
// Task 实现了 Function 对象的求值逻辑
func (fun Function) Task(env Env, args ...interface{}) (Lisp, error) {
for _, functor := range fun.content {
task, err := functor.Task(env, args...)
if err == nil {
return task, nil
}
}
if f, ok := fun.Global.Global(fun.Name()); ok {
switch foo := f.(type) {
case Functor:
return foo.Task(env, args...)
case TaskExpr:
task, err := foo(env, args...)
if err != nil {
return nil, err
}
return TaskBox{task}, nil
case LispExpr:
lisp, err := foo(env, args...)
if err != nil {
return nil, err
}
return lisp, nil
}
}
return nil, fmt.Errorf("not found args type sign for %v", args)
}
// Overload 实现了 Function 的 Overload 行为
func (fun *Function) Overload(functor Functor) error {
fun.content = append([]Functor{functor}, fun.content...)
return nil
}
// Content 返回函数体
func (fun Function) Content() []Functor {
return fun.content
}
// DefunExpr 是构造 Function 的表达式
func DefunExpr(env Env, args ...interface{}) (Tasker, error) {
funName := args[0].(Atom)
_args := args[1].(List)
var err error
lambda, err := DeclareLambda(env, _args, args[2:]...)
if err != nil {
return nil, err
}
if f, ok := env.Local(funName.Name); ok {
if fun, ok := f.(Function); ok {
err := fun.Overload(*lambda)
if err == nil {
return Q(fun).Eval, nil
}
return nil, err
}
return nil, fmt.Errorf("%v is defined as no Expr", funName.Name)
}
err = env.Defun(funName.Name, *lambda)
if err == nil {
return nil, nil
}
return nil, err
}