-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdynamic.go
More file actions
93 lines (87 loc) · 2.1 KB
/
dynamic.go
File metadata and controls
93 lines (87 loc) · 2.1 KB
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
// Copyright (c) 2022, Peter Ohler, All rights reserved.
package slip
// Dynamic represents a function defined by a call to defun or lambda.
type Dynamic struct {
Function
// Function.Self must point to a Caller.
}
// String representation of the Object.
func (f *Dynamic) String() string {
return string(f.Append([]byte{}))
}
// Append a buffer with a representation of the Object.
func (f *Dynamic) Append(b []byte) []byte {
b = append(b, '(')
if 0 < len(f.Name) {
b = append(b, f.Name...)
} else {
b = f.Self.(Object).Append(b)
}
for _, a := range f.Args {
b = append(b, ' ')
b = Append(b, a)
}
return append(b, ')')
}
// Simplify the function.
func (f *Dynamic) Simplify() any {
simple := make([]any, 0, len(f.Args)+1)
if 0 < len(f.Name) {
simple = append(simple, f.Name)
} else {
lc := f.Self.(*Lambda)
args := make([]any, len(lc.Doc.Args))
for i, da := range lc.Doc.Args {
args[i] = da.Name
}
lambda := make([]any, 0, len(lc.Forms)+2)
lambda = append(lambda, "lambda", args)
for _, form := range lc.Forms {
if form == nil {
lambda = append(lambda, nil)
} else {
lambda = append(lambda, form.Simplify())
}
}
simple = append(simple, lambda)
}
for _, a := range f.Args {
simple = append(simple, Simplify(a))
}
return simple
}
// LoadForm returns a form that can be evaluated to create the object.
func (obj *Dynamic) LoadForm() Object {
form := make(List, len(obj.Args)+1)
if 0 < len(obj.Name) {
form[0] = Symbol(obj.Name)
} else {
lambda := List{Symbol("lambda")}
lc := obj.Self.(*Lambda)
dl := make(List, len(lc.Doc.Args))
for i, da := range lc.Doc.Args {
switch {
case da.Default == nil:
dl[i] = Symbol(da.Name)
default:
dl[i] = List{Symbol(da.Name), da.Default}
}
}
lambda = append(lambda, dl)
lambda = append(lambda, lc.Forms...)
form[0] = lambda
}
for i, a := range obj.Args {
if a != nil {
switch ta := a.(type) {
case nil:
// already nil
case LoadFormer:
form[i+1] = ta.LoadForm()
default:
PrintNotReadablePanic(NewScope(), 0, ta, "Can not make a load form for %s.", ta)
}
}
}
return form
}