-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathop.go
76 lines (66 loc) · 1.38 KB
/
op.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
package main
import (
"fmt"
"reflect"
)
func intOp(op func(int, int) int) *funcval {
return &funcval{
func(args []val) (val, error) {
sum := &intval{}
for i, arg := range args {
val, ok := arg.(*intval)
if !ok {
return nil, fmt.Errorf("intadd arg is not an intval : %v : %v : %v", i, arg, reflect.TypeOf(arg))
}
if val == nil {
return nil, fmt.Errorf("intadd arg is nil : %v : %v", i, arg)
}
if i == 0 {
sum.val = val.val
} else {
sum.val = op(sum.val, val.val)
}
}
return sum, nil
}}
}
var (
intPlus = intOp(func(x int, y int) int {
return x + y
})
intMultiply = intOp(func(x int, y int) int {
return x * y
})
intSubtract = intOp(func(x int, y int) int {
return x - y
})
intDivide = intOp(func(x int, y int) int {
return x / y
})
)
func car(args []val) (val, error) {
if len(args) != 1 {
return nil, fmt.Errorf("car needs one argument")
}
list, ok := interface{}(args[0]).(listval)
if !ok {
return nil, fmt.Errorf("car requires a list argument")
}
if len(list) == 0 {
return nil, nil
}
return list[0], nil
}
func cdr(args []val) (val, error) {
if len(args) != 1 {
return nil, fmt.Errorf("cdr needs one argument")
}
list, ok := interface{}(args[0]).(listval)
if !ok {
return nil, fmt.Errorf("cdr requires a list argument")
}
if len(list) < 2 {
return nil, nil
}
return list[1:], nil
}