-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvector_builtins.go
132 lines (106 loc) · 2.36 KB
/
vector_builtins.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
package main
import (
"errors"
"math/big"
)
func FnIsVector(nargs int) error {
if nargs != 1 {
return errors.New("Wrong arg count to vector?")
}
_, ok := stack.Pop().(Vector)
stack.Push(Boolean(ok))
return nil
}
func FnMakeVector(nargs int) error {
if nargs == 1 && nargs != 2 {
return errors.New("Wrong arg count to make-vector")
}
k, ok := stack.Pop().(Integer)
if !ok {
return errors.New("make-vector requires an integer for the first arg")
}
k_bi := big.Int(k)
fill := Empty
if nargs == 2 {
fill = stack.Pop()
}
vec := Vector{&[]Value{}}
n := int(k_bi.Int64())
for i := 0; i < n; i++ {
*vec.v = append(*vec.v, fill)
}
stack.Push(vec)
return nil
}
func FnVectorLength(nargs int) error {
if nargs != 1 {
return errors.New("vector-length takes 1 arg")
}
vec, ok := stack.Pop().(Vector)
if !ok {
return errors.New("vector-length takes a vector as the argument")
}
stack.Push(Integer(*big.NewInt(int64(len(*vec.v)))))
return nil
}
func FnVector(nargs int) error {
if nargs == 0 {
return errors.New("vector takes at least 1 args")
}
vec := Vector{&[]Value{}}
for i := 0; i < nargs; i++ {
*vec.v = append(*vec.v, stack.Pop())
}
stack.Push(vec)
return nil
}
func FnVectorRef(nargs int) error {
if nargs != 2 {
return errors.New("vector-ref takes 2 args")
}
vec, ok := stack.Pop().(Vector)
if !ok {
return errors.New("vector-ref requires a vector as the first argument")
}
idx, ok := stack.Pop().(Integer)
if !ok {
return errors.New(
"vector-ref requires an integer as the second argument")
}
idx_bi := big.Int(idx)
stack.Push((*vec.v)[idx_bi.Int64()])
return nil
}
func FnVectorSet(nargs int) error {
if nargs != 3 {
return errors.New("vector-set! takes 3 args")
}
vec, ok := stack.Pop().(Vector)
if !ok {
return errors.New("vector-set requires a vector as the first argument")
}
idx, ok := stack.Pop().(Integer)
if !ok {
return errors.New(
"vector-set requires an integer as the second argument")
}
idx_bi := big.Int(idx)
(*vec.v)[idx_bi.Int64()] = stack.Pop()
stack.Push(vec)
return nil
}
func FnList2Vector(nargs int) error {
if nargs != 1 {
return errors.New("list->vector takes 1 args")
}
p, ok := stack.Pop().(*Pair)
if !ok {
return errors.New("list->vector takes a list as the argument")
}
v, err := list2vec(p)
if err != nil {
return err
}
stack.Push(Vector{&v})
return nil
}