1
2
3
4
5 package interp
6
7
8
9
10 import (
11 "bytes"
12 "math"
13 "os"
14 "runtime"
15 "sort"
16 "strconv"
17 "strings"
18 "time"
19 "unicode/utf8"
20 )
21
22 type externalFn func(fr *frame, args []value) value
23
24
25
26
27
28
29 var externals = make(map[string]externalFn)
30
31 func init() {
32
33 for k, v := range map[string]externalFn{
34 "(reflect.Value).Bool": ext۰reflect۰Value۰Bool,
35 "(reflect.Value).CanAddr": ext۰reflect۰Value۰CanAddr,
36 "(reflect.Value).CanInterface": ext۰reflect۰Value۰CanInterface,
37 "(reflect.Value).Elem": ext۰reflect۰Value۰Elem,
38 "(reflect.Value).Field": ext۰reflect۰Value۰Field,
39 "(reflect.Value).Float": ext۰reflect۰Value۰Float,
40 "(reflect.Value).Index": ext۰reflect۰Value۰Index,
41 "(reflect.Value).Int": ext۰reflect۰Value۰Int,
42 "(reflect.Value).Interface": ext۰reflect۰Value۰Interface,
43 "(reflect.Value).IsNil": ext۰reflect۰Value۰IsNil,
44 "(reflect.Value).IsValid": ext۰reflect۰Value۰IsValid,
45 "(reflect.Value).Kind": ext۰reflect۰Value۰Kind,
46 "(reflect.Value).Len": ext۰reflect۰Value۰Len,
47 "(reflect.Value).MapIndex": ext۰reflect۰Value۰MapIndex,
48 "(reflect.Value).MapKeys": ext۰reflect۰Value۰MapKeys,
49 "(reflect.Value).NumField": ext۰reflect۰Value۰NumField,
50 "(reflect.Value).NumMethod": ext۰reflect۰Value۰NumMethod,
51 "(reflect.Value).Pointer": ext۰reflect۰Value۰Pointer,
52 "(reflect.Value).Set": ext۰reflect۰Value۰Set,
53 "(reflect.Value).String": ext۰reflect۰Value۰String,
54 "(reflect.Value).Type": ext۰reflect۰Value۰Type,
55 "(reflect.Value).Uint": ext۰reflect۰Value۰Uint,
56 "(reflect.error).Error": ext۰reflect۰error۰Error,
57 "(reflect.rtype).Bits": ext۰reflect۰rtype۰Bits,
58 "(reflect.rtype).Elem": ext۰reflect۰rtype۰Elem,
59 "(reflect.rtype).Field": ext۰reflect۰rtype۰Field,
60 "(reflect.rtype).In": ext۰reflect۰rtype۰In,
61 "(reflect.rtype).Kind": ext۰reflect۰rtype۰Kind,
62 "(reflect.rtype).NumField": ext۰reflect۰rtype۰NumField,
63 "(reflect.rtype).NumIn": ext۰reflect۰rtype۰NumIn,
64 "(reflect.rtype).NumMethod": ext۰reflect۰rtype۰NumMethod,
65 "(reflect.rtype).NumOut": ext۰reflect۰rtype۰NumOut,
66 "(reflect.rtype).Out": ext۰reflect۰rtype۰Out,
67 "(reflect.rtype).Size": ext۰reflect۰rtype۰Size,
68 "(reflect.rtype).String": ext۰reflect۰rtype۰String,
69 "bytes.Equal": ext۰bytes۰Equal,
70 "bytes.IndexByte": ext۰bytes۰IndexByte,
71 "fmt.Sprint": ext۰fmt۰Sprint,
72 "math.Abs": ext۰math۰Abs,
73 "math.Copysign": ext۰math۰Copysign,
74 "math.Exp": ext۰math۰Exp,
75 "math.Float32bits": ext۰math۰Float32bits,
76 "math.Float32frombits": ext۰math۰Float32frombits,
77 "math.Float64bits": ext۰math۰Float64bits,
78 "math.Float64frombits": ext۰math۰Float64frombits,
79 "math.Inf": ext۰math۰Inf,
80 "math.IsNaN": ext۰math۰IsNaN,
81 "math.Ldexp": ext۰math۰Ldexp,
82 "math.Log": ext۰math۰Log,
83 "math.Min": ext۰math۰Min,
84 "math.NaN": ext۰math۰NaN,
85 "math.Sqrt": ext۰math۰Sqrt,
86 "os.Exit": ext۰os۰Exit,
87 "os.Getenv": ext۰os۰Getenv,
88 "reflect.New": ext۰reflect۰New,
89 "reflect.SliceOf": ext۰reflect۰SliceOf,
90 "reflect.TypeOf": ext۰reflect۰TypeOf,
91 "reflect.ValueOf": ext۰reflect۰ValueOf,
92 "reflect.Zero": ext۰reflect۰Zero,
93 "runtime.Breakpoint": ext۰runtime۰Breakpoint,
94 "runtime.GC": ext۰runtime۰GC,
95 "runtime.GOMAXPROCS": ext۰runtime۰GOMAXPROCS,
96 "runtime.GOROOT": ext۰runtime۰GOROOT,
97 "runtime.Goexit": ext۰runtime۰Goexit,
98 "runtime.Gosched": ext۰runtime۰Gosched,
99 "runtime.NumCPU": ext۰runtime۰NumCPU,
100 "sort.Float64s": ext۰sort۰Float64s,
101 "sort.Ints": ext۰sort۰Ints,
102 "sort.Strings": ext۰sort۰Strings,
103 "strconv.Atoi": ext۰strconv۰Atoi,
104 "strconv.Itoa": ext۰strconv۰Itoa,
105 "strconv.FormatFloat": ext۰strconv۰FormatFloat,
106 "strings.Count": ext۰strings۰Count,
107 "strings.EqualFold": ext۰strings۰EqualFold,
108 "strings.Index": ext۰strings۰Index,
109 "strings.IndexByte": ext۰strings۰IndexByte,
110 "strings.Replace": ext۰strings۰Replace,
111 "strings.ToLower": ext۰strings۰ToLower,
112 "time.Sleep": ext۰time۰Sleep,
113 "unicode/utf8.DecodeRuneInString": ext۰unicode۰utf8۰DecodeRuneInString,
114 } {
115 externals[k] = v
116 }
117 }
118
119 func ext۰bytes۰Equal(fr *frame, args []value) value {
120
121 a := args[0].([]value)
122 b := args[1].([]value)
123 if len(a) != len(b) {
124 return false
125 }
126 for i := range a {
127 if a[i] != b[i] {
128 return false
129 }
130 }
131 return true
132 }
133
134 func ext۰bytes۰IndexByte(fr *frame, args []value) value {
135
136 s := args[0].([]value)
137 c := args[1].(byte)
138 for i, b := range s {
139 if b.(byte) == c {
140 return i
141 }
142 }
143 return -1
144 }
145
146 func ext۰math۰Float64frombits(fr *frame, args []value) value {
147 return math.Float64frombits(args[0].(uint64))
148 }
149
150 func ext۰math۰Float64bits(fr *frame, args []value) value {
151 return math.Float64bits(args[0].(float64))
152 }
153
154 func ext۰math۰Float32frombits(fr *frame, args []value) value {
155 return math.Float32frombits(args[0].(uint32))
156 }
157
158 func ext۰math۰Abs(fr *frame, args []value) value {
159 return math.Abs(args[0].(float64))
160 }
161
162 func ext۰math۰Copysign(fr *frame, args []value) value {
163 return math.Copysign(args[0].(float64), args[1].(float64))
164 }
165
166 func ext۰math۰Exp(fr *frame, args []value) value {
167 return math.Exp(args[0].(float64))
168 }
169
170 func ext۰math۰Float32bits(fr *frame, args []value) value {
171 return math.Float32bits(args[0].(float32))
172 }
173
174 func ext۰math۰Min(fr *frame, args []value) value {
175 return math.Min(args[0].(float64), args[1].(float64))
176 }
177
178 func ext۰math۰NaN(fr *frame, args []value) value {
179 return math.NaN()
180 }
181
182 func ext۰math۰IsNaN(fr *frame, args []value) value {
183 return math.IsNaN(args[0].(float64))
184 }
185
186 func ext۰math۰Inf(fr *frame, args []value) value {
187 return math.Inf(args[0].(int))
188 }
189
190 func ext۰math۰Ldexp(fr *frame, args []value) value {
191 return math.Ldexp(args[0].(float64), args[1].(int))
192 }
193
194 func ext۰math۰Log(fr *frame, args []value) value {
195 return math.Log(args[0].(float64))
196 }
197
198 func ext۰math۰Sqrt(fr *frame, args []value) value {
199 return math.Sqrt(args[0].(float64))
200 }
201
202 func ext۰runtime۰Breakpoint(fr *frame, args []value) value {
203 runtime.Breakpoint()
204 return nil
205 }
206
207 func ext۰sort۰Ints(fr *frame, args []value) value {
208 x := args[0].([]value)
209 sort.Slice(x, func(i, j int) bool {
210 return x[i].(int) < x[j].(int)
211 })
212 return nil
213 }
214 func ext۰sort۰Strings(fr *frame, args []value) value {
215 x := args[0].([]value)
216 sort.Slice(x, func(i, j int) bool {
217 return x[i].(string) < x[j].(string)
218 })
219 return nil
220 }
221 func ext۰sort۰Float64s(fr *frame, args []value) value {
222 x := args[0].([]value)
223 sort.Slice(x, func(i, j int) bool {
224 return x[i].(float64) < x[j].(float64)
225 })
226 return nil
227 }
228
229 func ext۰strconv۰Atoi(fr *frame, args []value) value {
230 i, e := strconv.Atoi(args[0].(string))
231 if e != nil {
232 return tuple{i, iface{fr.i.runtimeErrorString, e.Error()}}
233 }
234 return tuple{i, iface{}}
235 }
236 func ext۰strconv۰Itoa(fr *frame, args []value) value {
237 return strconv.Itoa(args[0].(int))
238 }
239 func ext۰strconv۰FormatFloat(fr *frame, args []value) value {
240 return strconv.FormatFloat(args[0].(float64), args[1].(byte), args[2].(int), args[3].(int))
241 }
242
243 func ext۰strings۰Count(fr *frame, args []value) value {
244 return strings.Count(args[0].(string), args[1].(string))
245 }
246
247 func ext۰strings۰EqualFold(fr *frame, args []value) value {
248 return strings.EqualFold(args[0].(string), args[1].(string))
249 }
250 func ext۰strings۰IndexByte(fr *frame, args []value) value {
251 return strings.IndexByte(args[0].(string), args[1].(byte))
252 }
253
254 func ext۰strings۰Index(fr *frame, args []value) value {
255 return strings.Index(args[0].(string), args[1].(string))
256 }
257
258 func ext۰strings۰Replace(fr *frame, args []value) value {
259
260 s := args[0].(string)
261 new := args[1].(string)
262 old := args[2].(string)
263 n := args[3].(int)
264 return strings.Replace(s, old, new, n)
265 }
266
267 func ext۰strings۰ToLower(fr *frame, args []value) value {
268 return strings.ToLower(args[0].(string))
269 }
270
271 func ext۰runtime۰GOMAXPROCS(fr *frame, args []value) value {
272
273
274 return runtime.GOMAXPROCS(0)
275 }
276
277 func ext۰runtime۰Goexit(fr *frame, args []value) value {
278
279 runtime.Goexit()
280 return nil
281 }
282
283 func ext۰runtime۰GOROOT(fr *frame, args []value) value {
284 return runtime.GOROOT()
285 }
286
287 func ext۰runtime۰GC(fr *frame, args []value) value {
288 runtime.GC()
289 return nil
290 }
291
292 func ext۰runtime۰Gosched(fr *frame, args []value) value {
293 runtime.Gosched()
294 return nil
295 }
296
297 func ext۰runtime۰NumCPU(fr *frame, args []value) value {
298 return runtime.NumCPU()
299 }
300
301 func ext۰time۰Sleep(fr *frame, args []value) value {
302 time.Sleep(time.Duration(args[0].(int64)))
303 return nil
304 }
305
306 func valueToBytes(v value) []byte {
307 in := v.([]value)
308 b := make([]byte, len(in))
309 for i := range in {
310 b[i] = in[i].(byte)
311 }
312 return b
313 }
314
315 func ext۰os۰Getenv(fr *frame, args []value) value {
316 name := args[0].(string)
317 switch name {
318 case "GOSSAINTERP":
319 return "1"
320 }
321 return os.Getenv(name)
322 }
323
324 func ext۰os۰Exit(fr *frame, args []value) value {
325 panic(exitPanic(args[0].(int)))
326 }
327
328 func ext۰unicode۰utf8۰DecodeRuneInString(fr *frame, args []value) value {
329 r, n := utf8.DecodeRuneInString(args[0].(string))
330 return tuple{r, n}
331 }
332
333
334
335
336 func ext۰fmt۰Sprint(fr *frame, args []value) value {
337 buf := new(bytes.Buffer)
338 wasStr := false
339 for i, arg := range args[0].([]value) {
340 x := arg.(iface).v
341 _, isStr := x.(string)
342 if i > 0 && !wasStr && !isStr {
343 buf.WriteByte(' ')
344 }
345 wasStr = isStr
346 buf.WriteString(toString(x))
347 }
348 return buf.String()
349 }
350
View as plain text