@@ -19,12 +19,21 @@ const (
19
19
)
20
20
21
21
type lval struct {
22
- ltype int
23
- num int64 // lvalNumType
24
- err string // lvalErrType
25
- sym string // lvalSymType
26
- function lbuiltin // lvalFunType
27
- cells []* lval // lvalSexprType, lvalQexprType
22
+ ltype int
23
+
24
+ // Basic
25
+ num int64 // lvalNumType
26
+ err string // lvalErrType
27
+ sym string // lvalSymType
28
+
29
+ // Function
30
+ builtin lbuiltin // lvalFunType, nil for user defined function
31
+ env * lenv
32
+ formals * lval
33
+ body * lval
34
+
35
+ // Expression
36
+ cells []* lval // lvalSexprType, lvalQexprType
28
37
}
29
38
30
39
// lvalNum creates an lval number
@@ -71,7 +80,21 @@ func lvalQexpr() *lval {
71
80
func lvalFun (function lbuiltin ) * lval {
72
81
v := new (lval )
73
82
v .ltype = lvalFunType
74
- v .function = function
83
+ v .builtin = function
84
+ return v
85
+ }
86
+
87
+ // lvalLambda creates a user defined lval function
88
+ func lvalLambda (formals * lval , body * lval ) * lval {
89
+ v := new (lval )
90
+ v .ltype = lvalFunType
91
+ // Builtin is nil for user defined functions
92
+ v .builtin = nil
93
+ // Init environment
94
+ v .env = lenvNew ()
95
+ // Set formals and body
96
+ v .formals = formals
97
+ v .body = body
75
98
return v
76
99
}
77
100
@@ -110,7 +133,10 @@ func (v *lval) lvalString() string {
110
133
case lvalSymType :
111
134
return (v .sym )
112
135
case lvalFunType :
113
- return "<function>"
136
+ if v .builtin == nil {
137
+ return "(\\ " + v .formals .lvalString () + " " + v .body .lvalString () + ")"
138
+ }
139
+ return "<builtin>"
114
140
case lvalSexprType :
115
141
return v .lvalExprString ("(" , ")" )
116
142
case lvalQexprType :
@@ -133,7 +159,14 @@ func lvalCopy(v *lval) *lval {
133
159
x .ltype = v .ltype
134
160
switch v .ltype {
135
161
case lvalFunType :
136
- x .function = v .function
162
+ if v .builtin == nil {
163
+ x .builtin = nil
164
+ x .env = lenvCopy (v .env )
165
+ x .formals = lvalCopy (v .formals )
166
+ x .body = lvalCopy (v .body )
167
+ } else {
168
+ x .builtin = v .builtin
169
+ }
137
170
case lvalNumType :
138
171
x .num = v .num
139
172
case lvalErrType :
@@ -144,18 +177,15 @@ func lvalCopy(v *lval) *lval {
144
177
fallthrough
145
178
case lvalQexprType :
146
179
for _ , cell := range v .cells {
147
- x .cells = append (x .cells , cell )
180
+ x .cells = append (x .cells , lvalCopy ( cell ) )
148
181
}
149
182
}
150
183
return x
151
184
}
152
185
153
- func (v * lval ) lvalAdd (x * lval ) {
154
- if x == nil {
155
- fmt .Println ("ERROR: Failed to add lval, addition is nil" )
156
- } else {
157
- v .cells = append (v .cells , x )
158
- }
186
+ func lvalAdd (v * lval , x * lval ) * lval {
187
+ v .cells = append (v .cells , x )
188
+ return v
159
189
}
160
190
161
191
func (v * lval ) lvalExprString (openChar string , closeChar string ) string {
@@ -210,7 +240,7 @@ func lvalRead(tree mpc.MpcAst) *lval {
210
240
mpc .GetTag (iChild ) == "regex" {
211
241
continue
212
242
} else {
213
- x . lvalAdd (lvalRead (iChild ))
243
+ x = lvalAdd (x , lvalRead (iChild ))
214
244
}
215
245
strconv .ParseInt (mpc .GetContents (tree ), 10 , 0 )
216
246
}
@@ -234,15 +264,15 @@ func (v *lval) lvalEvalSexpr(e *lenv) *lval {
234
264
}
235
265
// Single Expression
236
266
if v .cellCount () == 1 {
237
- return v .lvalTake (0 )
267
+ return v .lvalTake (0 ). lvalEval ( e )
238
268
}
239
269
// Ensure first element is a symbol
240
270
f := v .lvalPop (0 )
241
271
if f .ltype != lvalFunType {
242
272
return lvalErr ("S-expression does not start with symbol! got: %s" , f .ltypeName ())
243
273
}
244
274
// Use first element as a function to get result
245
- return f . function ( e , v )
275
+ return lvalCall ( e , f , v )
246
276
}
247
277
248
278
func (v * lval ) lvalEval (e * lenv ) * lval {
@@ -269,7 +299,40 @@ func (v *lval) lvalTake(i int) *lval {
269
299
270
300
func lvalJoin (x * lval , y * lval ) * lval {
271
301
for y .cellCount () > 0 {
272
- x . lvalAdd (y .lvalPop (0 ))
302
+ x = lvalAdd (x , y .lvalPop (0 ))
273
303
}
274
304
return x
275
305
}
306
+
307
+ func lvalCall (e * lenv , f * lval , a * lval ) * lval {
308
+ // Simple Builtin case:
309
+ if f .builtin != nil {
310
+ return f .builtin (e , a )
311
+ }
312
+ // Record argument counts
313
+ given := a .cellCount ()
314
+ total := f .formals .cellCount ()
315
+ // While arguments still remain to be processed
316
+ for a .cellCount () > 0 {
317
+ // If we've ran out of formal arguments to bind
318
+ if f .formals .cellCount () == 0 {
319
+ return lvalErr ("Function passed too many arguments. Got %d, Expected %d" , given , total )
320
+ }
321
+ // Pop the first symbol from the formal
322
+ sym := f .formals .lvalPop (0 )
323
+ // Pop the next argument from the list
324
+ val := a .lvalPop (0 )
325
+ // Bind a copy into the function's environment
326
+ f .env .lenvPut (sym , val )
327
+ }
328
+ // If all formals have been bound, evaluate
329
+ if f .formals .cellCount () == 0 {
330
+ // Set environment parent to evaluation environment
331
+ f .env .par = e
332
+ // Evaluate and return
333
+ ret := builtinEval (f .env , lvalAdd (lvalSexpr (), lvalCopy (f .body )))
334
+ return ret
335
+ }
336
+ // Otherwise, return partially evaluated function
337
+ return lvalCopy (f )
338
+ }
0 commit comments