1/*
2 * gomacro - A Go interpreter with Lisp-like macros
3 *
4 * Copyright (C) 2017-2019 Massimiliano Ghilardi
5 *
6 *     This Source Code Form is subject to the terms of the Mozilla Public
7 *     License, v. 2.0. If a copy of the MPL was not distributed with this
8 *     file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 *
11 * call_ellipsis.go
12 *
13 *  Created on May 01, 2017
14 *      Author Massimiliano Ghilardi
15 */
16
17package fast
18
19import (
20	r "reflect"
21)
22
23// call a variadic function, when arguments CONTAIN '...'
24func call_ellipsis_ret0(c *Call, maxdepth int) func(env *Env) {
25	exprfun := c.Fun.AsX1()
26	argfunsX1 := c.MakeArgfunsX1()
27	var call func(*Env)
28	switch c.Fun.Type.NumIn() {
29	case 1:
30		argfun := argfunsX1[0]
31		call = func(env *Env) {
32			funv := exprfun(env)
33			argv := []r.Value{
34				argfun(env),
35			}
36			callslicexr(funv, argv)
37		}
38	case 2:
39		argfuns := [2]func(env *Env) r.Value{
40			argfunsX1[0],
41			argfunsX1[1],
42		}
43		call = func(env *Env) {
44			funv := exprfun(env)
45			argv := []r.Value{
46				argfuns[0](env),
47				argfuns[1](env),
48			}
49			callslicexr(funv, argv)
50		}
51	case 3:
52		argfuns := [3]func(env *Env) r.Value{
53			argfunsX1[0],
54			argfunsX1[1],
55			argfunsX1[2],
56		}
57		call = func(env *Env) {
58			funv := exprfun(env)
59			argv := []r.Value{
60				argfuns[0](env),
61				argfuns[1](env),
62				argfuns[2](env),
63			}
64			callslicexr(funv, argv)
65		}
66	}
67	if call == nil {
68		call = func(env *Env) {
69			funv := exprfun(env)
70			argv := make([]r.Value, len(argfunsX1))
71			for i, argfun := range argfunsX1 {
72				argv[i] = argfun(env)
73			}
74			callslicexr(funv, argv)
75		}
76	}
77	return call
78}
79
80// mandatory optimization: fast_interpreter ASSUMES that expressions
81// returning bool, int, uint, float, complex, string do NOT wrap them in reflect.Value
82func call_ellipsis_ret1(c *Call, maxdepth int) I {
83	exprfun := c.Fun.AsX1()
84	argfunsX1 := c.MakeArgfunsX1()
85	kout := c.Fun.Type.Out(0).Kind()
86	var call I
87	switch c.Fun.Type.NumIn() {
88	case 1:
89		argfun := argfunsX1[0]
90		switch kout {
91		case r.Bool:
92			call = func(env *Env) bool {
93				funv := exprfun(env)
94				argv := []r.Value{
95					argfun(env),
96				}
97				retv := callslicexr(funv, argv)[0]
98				return retv.Bool()
99			}
100		case r.Int:
101			call = func(env *Env) int {
102				funv := exprfun(env)
103				argv := []r.Value{
104					argfun(env),
105				}
106				retv := callslicexr(funv, argv)[0]
107				return int(retv.Int())
108			}
109		case r.Int8:
110			call = func(env *Env) int8 {
111				funv := exprfun(env)
112				argv := []r.Value{
113					argfun(env),
114				}
115				retv := callslicexr(funv, argv)[0]
116				return int8(retv.Int())
117			}
118		case r.Int16:
119			call = func(env *Env) int16 {
120				funv := exprfun(env)
121				argv := []r.Value{
122					argfun(env),
123				}
124				retv := callslicexr(funv, argv)[0]
125				return int16(retv.Int())
126			}
127		case r.Int32:
128			call = func(env *Env) int32 {
129				funv := exprfun(env)
130				argv := []r.Value{
131					argfun(env),
132				}
133				retv := callslicexr(funv, argv)[0]
134				return int32(retv.Int())
135			}
136		case r.Int64:
137			call = func(env *Env) int64 {
138				funv := exprfun(env)
139				argv := []r.Value{
140					argfun(env),
141				}
142				retv := callslicexr(funv, argv)[0]
143				return retv.Int()
144			}
145		case r.Uint:
146			call = func(env *Env) uint {
147				funv := exprfun(env)
148				argv := []r.Value{
149					argfun(env),
150				}
151				retv := callslicexr(funv, argv)[0]
152				return uint(retv.Uint())
153			}
154		case r.Uint8:
155			call = func(env *Env) uint8 {
156				funv := exprfun(env)
157				argv := []r.Value{
158					argfun(env),
159				}
160				retv := callslicexr(funv, argv)[0]
161				return uint8(retv.Uint())
162			}
163		case r.Uint16:
164			call = func(env *Env) uint16 {
165				funv := exprfun(env)
166				argv := []r.Value{
167					argfun(env),
168				}
169				retv := callslicexr(funv, argv)[0]
170				return uint16(retv.Uint())
171			}
172		case r.Uint32:
173			call = func(env *Env) uint32 {
174				funv := exprfun(env)
175				argv := []r.Value{
176					argfun(env),
177				}
178				retv := callslicexr(funv, argv)[0]
179				return uint32(retv.Uint())
180			}
181		case r.Uint64:
182			call = func(env *Env) uint64 {
183				funv := exprfun(env)
184				argv := []r.Value{
185					argfun(env),
186				}
187				retv := callslicexr(funv, argv)[0]
188				return retv.Uint()
189			}
190		case r.Uintptr:
191			call = func(env *Env) uintptr {
192				funv := exprfun(env)
193				argv := []r.Value{
194					argfun(env),
195				}
196				retv := callslicexr(funv, argv)[0]
197				return uintptr(retv.Uint())
198			}
199		case r.Float32:
200			call = func(env *Env) float32 {
201				funv := exprfun(env)
202				argv := []r.Value{
203					argfun(env),
204				}
205				retv := callslicexr(funv, argv)[0]
206				return float32(retv.Float())
207			}
208		case r.Float64:
209			call = func(env *Env) float64 {
210				funv := exprfun(env)
211				argv := []r.Value{
212					argfun(env),
213				}
214				retv := callslicexr(funv, argv)[0]
215				return retv.Float()
216			}
217		case r.Complex64:
218			call = func(env *Env) complex64 {
219				funv := exprfun(env)
220				argv := []r.Value{
221					argfun(env),
222				}
223				retv := callslicexr(funv, argv)[0]
224				return complex64(retv.Complex())
225			}
226		case r.Complex128:
227			call = func(env *Env) complex128 {
228				funv := exprfun(env)
229				argv := []r.Value{
230					argfun(env),
231				}
232				retv := callslicexr(funv, argv)[0]
233				return retv.Complex()
234			}
235		case r.String:
236			call = func(env *Env) string {
237				funv := exprfun(env)
238				argv := []r.Value{
239					argfun(env),
240				}
241				retv := callslicexr(funv, argv)[0]
242				return retv.String()
243			}
244		default:
245			call = func(env *Env) r.Value {
246				funv := exprfun(env)
247				argv := []r.Value{
248					argfun(env),
249				}
250				return callslicexr(funv, argv)[0]
251			}
252		}
253	case 2:
254		argfuns := [2]func(*Env) r.Value{
255			argfunsX1[0],
256			argfunsX1[1],
257		}
258		switch kout {
259		case r.Bool:
260			call = func(env *Env) bool {
261				funv := exprfun(env)
262				argv := []r.Value{
263					argfuns[0](env),
264					argfuns[1](env),
265				}
266				retv := callslicexr(funv, argv)[0]
267				return retv.Bool()
268			}
269		case r.Int:
270			call = func(env *Env) int {
271				funv := exprfun(env)
272				argv := []r.Value{
273					argfuns[0](env),
274					argfuns[1](env),
275				}
276				retv := callslicexr(funv, argv)[0]
277				return int(retv.Int())
278			}
279		case r.Int8:
280			call = func(env *Env) int8 {
281				funv := exprfun(env)
282				argv := []r.Value{
283					argfuns[0](env),
284					argfuns[1](env),
285				}
286				retv := callslicexr(funv, argv)[0]
287				return int8(retv.Int())
288			}
289		case r.Int16:
290			call = func(env *Env) int16 {
291				funv := exprfun(env)
292				argv := []r.Value{
293					argfuns[0](env),
294					argfuns[1](env),
295				}
296				retv := callslicexr(funv, argv)[0]
297				return int16(retv.Int())
298			}
299		case r.Int32:
300			call = func(env *Env) int32 {
301				funv := exprfun(env)
302				argv := []r.Value{
303					argfuns[0](env),
304					argfuns[1](env),
305				}
306				retv := callslicexr(funv, argv)[0]
307				return int32(retv.Int())
308			}
309		case r.Int64:
310			call = func(env *Env) int64 {
311				funv := exprfun(env)
312				argv := []r.Value{
313					argfuns[0](env),
314					argfuns[1](env),
315				}
316				retv := callslicexr(funv, argv)[0]
317				return retv.Int()
318			}
319		case r.Uint:
320			call = func(env *Env) uint {
321				funv := exprfun(env)
322				argv := []r.Value{
323					argfuns[0](env),
324					argfuns[1](env),
325				}
326				retv := callslicexr(funv, argv)[0]
327				return uint(retv.Uint())
328			}
329		case r.Uint8:
330			call = func(env *Env) uint8 {
331				funv := exprfun(env)
332				argv := []r.Value{
333					argfuns[0](env),
334					argfuns[1](env),
335				}
336				retv := callslicexr(funv, argv)[0]
337				return uint8(retv.Uint())
338			}
339		case r.Uint16:
340			call = func(env *Env) uint16 {
341				funv := exprfun(env)
342				argv := []r.Value{
343					argfuns[0](env),
344					argfuns[1](env),
345				}
346				retv := callslicexr(funv, argv)[0]
347				return uint16(retv.Uint())
348			}
349		case r.Uint32:
350			call = func(env *Env) uint32 {
351				funv := exprfun(env)
352				argv := []r.Value{
353					argfuns[0](env),
354					argfuns[1](env),
355				}
356				retv := callslicexr(funv, argv)[0]
357				return uint32(retv.Uint())
358			}
359		case r.Uint64:
360			call = func(env *Env) uint64 {
361				funv := exprfun(env)
362				argv := []r.Value{
363					argfuns[0](env),
364					argfuns[1](env),
365				}
366				retv := callslicexr(funv, argv)[0]
367				return retv.Uint()
368			}
369		case r.Uintptr:
370			call = func(env *Env) uintptr {
371				funv := exprfun(env)
372				argv := []r.Value{
373					argfuns[0](env),
374					argfuns[1](env),
375				}
376				retv := callslicexr(funv, argv)[0]
377				return uintptr(retv.Uint())
378			}
379		case r.Float32:
380			call = func(env *Env) float32 {
381				funv := exprfun(env)
382				argv := []r.Value{
383					argfuns[0](env),
384					argfuns[1](env),
385				}
386				retv := callslicexr(funv, argv)[0]
387				return float32(retv.Float())
388			}
389		case r.Float64:
390			call = func(env *Env) float64 {
391				funv := exprfun(env)
392				argv := []r.Value{
393					argfuns[0](env),
394					argfuns[1](env),
395				}
396				retv := callslicexr(funv, argv)[0]
397				return retv.Float()
398			}
399		case r.Complex64:
400			call = func(env *Env) complex64 {
401				funv := exprfun(env)
402				argv := []r.Value{
403					argfuns[0](env),
404					argfuns[1](env),
405				}
406				retv := callslicexr(funv, argv)[0]
407				return complex64(retv.Complex())
408			}
409		case r.Complex128:
410			call = func(env *Env) complex128 {
411				funv := exprfun(env)
412				argv := []r.Value{
413					argfuns[0](env),
414					argfuns[1](env),
415				}
416				retv := callslicexr(funv, argv)[0]
417				return retv.Complex()
418			}
419		case r.String:
420			call = func(env *Env) string {
421				funv := exprfun(env)
422				argv := []r.Value{
423					argfuns[0](env),
424					argfuns[1](env),
425				}
426				retv := callslicexr(funv, argv)[0]
427				return retv.String()
428			}
429		default:
430			call = func(env *Env) r.Value {
431				funv := exprfun(env)
432				argv := []r.Value{
433					argfuns[0](env),
434					argfuns[1](env),
435				}
436				return callslicexr(funv, argv)[0]
437			}
438		}
439	default:
440		switch kout {
441		case r.Bool:
442			call = func(env *Env) bool {
443				funv := exprfun(env)
444				argv := make([]r.Value, len(argfunsX1))
445				for i, argfun := range argfunsX1 {
446					argv[i] = argfun(env)
447				}
448				retv := callslicexr(funv, argv)[0]
449				return retv.Bool()
450			}
451		case r.Int:
452			call = func(env *Env) int {
453				funv := exprfun(env)
454				argv := make([]r.Value, len(argfunsX1))
455				for i, argfun := range argfunsX1 {
456					argv[i] = argfun(env)
457				}
458				retv := callslicexr(funv, argv)[0]
459				return int(retv.Int())
460			}
461		case r.Int8:
462			call = func(env *Env) int8 {
463				funv := exprfun(env)
464				argv := make([]r.Value, len(argfunsX1))
465				for i, argfun := range argfunsX1 {
466					argv[i] = argfun(env)
467				}
468				retv := callslicexr(funv, argv)[0]
469				return int8(retv.Int())
470			}
471		case r.Int16:
472			call = func(env *Env) int16 {
473				funv := exprfun(env)
474				argv := make([]r.Value, len(argfunsX1))
475				for i, argfun := range argfunsX1 {
476					argv[i] = argfun(env)
477				}
478				retv := callslicexr(funv, argv)[0]
479				return int16(retv.Int())
480			}
481		case r.Int32:
482			call = func(env *Env) int32 {
483				funv := exprfun(env)
484				argv := make([]r.Value, len(argfunsX1))
485				for i, argfun := range argfunsX1 {
486					argv[i] = argfun(env)
487				}
488				retv := callslicexr(funv, argv)[0]
489				return int32(retv.Int())
490			}
491		case r.Int64:
492			call = func(env *Env) int64 {
493				funv := exprfun(env)
494				argv := make([]r.Value, len(argfunsX1))
495				for i, argfun := range argfunsX1 {
496					argv[i] = argfun(env)
497				}
498				retv := callslicexr(funv, argv)[0]
499				return retv.Int()
500			}
501		case r.Uint:
502			call = func(env *Env) uint {
503				funv := exprfun(env)
504				argv := make([]r.Value, len(argfunsX1))
505				for i, argfun := range argfunsX1 {
506					argv[i] = argfun(env)
507				}
508				retv := callslicexr(funv, argv)[0]
509				return uint(retv.Uint())
510			}
511		case r.Uint8:
512			call = func(env *Env) uint8 {
513				funv := exprfun(env)
514				argv := make([]r.Value, len(argfunsX1))
515				for i, argfun := range argfunsX1 {
516					argv[i] = argfun(env)
517				}
518				retv := callslicexr(funv, argv)[0]
519				return uint8(retv.Uint())
520			}
521		case r.Uint16:
522			call = func(env *Env) uint16 {
523				funv := exprfun(env)
524				argv := make([]r.Value, len(argfunsX1))
525				for i, argfun := range argfunsX1 {
526					argv[i] = argfun(env)
527				}
528				retv := callslicexr(funv, argv)[0]
529				return uint16(retv.Uint())
530			}
531		case r.Uint32:
532			call = func(env *Env) uint32 {
533				funv := exprfun(env)
534				argv := make([]r.Value, len(argfunsX1))
535				for i, argfun := range argfunsX1 {
536					argv[i] = argfun(env)
537				}
538				retv := callslicexr(funv, argv)[0]
539				return uint32(retv.Uint())
540			}
541		case r.Uint64:
542			call = func(env *Env) uint64 {
543				funv := exprfun(env)
544				argv := make([]r.Value, len(argfunsX1))
545				for i, argfun := range argfunsX1 {
546					argv[i] = argfun(env)
547				}
548				retv := callslicexr(funv, argv)[0]
549				return retv.Uint()
550			}
551		case r.Uintptr:
552			call = func(env *Env) uintptr {
553				funv := exprfun(env)
554				argv := make([]r.Value, len(argfunsX1))
555				for i, argfun := range argfunsX1 {
556					argv[i] = argfun(env)
557				}
558				retv := callslicexr(funv, argv)[0]
559				return uintptr(retv.Uint())
560			}
561		case r.Float32:
562			call = func(env *Env) float32 {
563				funv := exprfun(env)
564				argv := make([]r.Value, len(argfunsX1))
565				for i, argfun := range argfunsX1 {
566					argv[i] = argfun(env)
567				}
568				retv := callslicexr(funv, argv)[0]
569				return float32(retv.Float())
570			}
571		case r.Float64:
572			call = func(env *Env) float64 {
573				funv := exprfun(env)
574				argv := make([]r.Value, len(argfunsX1))
575				for i, argfun := range argfunsX1 {
576					argv[i] = argfun(env)
577				}
578				retv := callslicexr(funv, argv)[0]
579				return retv.Float()
580			}
581		case r.Complex64:
582			call = func(env *Env) complex64 {
583				funv := exprfun(env)
584				argv := make([]r.Value, len(argfunsX1))
585				for i, argfun := range argfunsX1 {
586					argv[i] = argfun(env)
587				}
588				retv := callslicexr(funv, argv)[0]
589				return complex64(retv.Complex())
590			}
591		case r.Complex128:
592			call = func(env *Env) complex128 {
593				funv := exprfun(env)
594				argv := make([]r.Value, len(argfunsX1))
595				for i, argfun := range argfunsX1 {
596					argv[i] = argfun(env)
597				}
598				retv := callslicexr(funv, argv)[0]
599				return retv.Complex()
600			}
601		case r.String:
602			call = func(env *Env) string {
603				funv := exprfun(env)
604				argv := make([]r.Value, len(argfunsX1))
605				for i, argfun := range argfunsX1 {
606					argv[i] = argfun(env)
607				}
608				retv := callslicexr(funv, argv)[0]
609				return retv.String()
610			}
611		default:
612			call = func(env *Env) r.Value {
613				funv := exprfun(env)
614				argv := make([]r.Value, len(argfunsX1))
615				for i, argfun := range argfunsX1 {
616					argv[i] = argfun(env)
617				}
618				return callslicexr(funv, argv)[0]
619			}
620		}
621
622	}
623	return call
624}
625
626// cannot optimize much here... fast_interpreter ASSUMES that expressions
627// returning multiple values actually return (reflect.Value, []reflect.Value)
628func call_ellipsis_ret2plus(callexpr *Call, maxdepth int) func(env *Env) (r.Value, []r.Value) {
629	expr := callexpr.Fun
630	exprfun := expr.AsX1()
631	argfunsX1 := callexpr.MakeArgfunsX1()
632	var call func(*Env) (r.Value, []r.Value)
633
634	switch expr.Type.NumIn() {
635	case 1:
636		argfun := argfunsX1[0]
637		call = func(env *Env) (r.Value, []r.Value) {
638			funv := exprfun(env)
639			argv := []r.Value{
640				argfun(env),
641			}
642			retv := callslicexr(funv, argv)
643			return retv[0], retv
644		}
645	case 2:
646		argfuns := [2]func(*Env) r.Value{
647			argfunsX1[0],
648			argfunsX1[1],
649		}
650		call = func(env *Env) (r.Value, []r.Value) {
651			funv := exprfun(env)
652			argv := []r.Value{
653				argfuns[0](env),
654				argfuns[1](env),
655			}
656			retv := callslicexr(funv, argv)
657			return retv[0], retv
658		}
659	case 3:
660		argfuns := [3]func(*Env) r.Value{
661			argfunsX1[0],
662			argfunsX1[1],
663			argfunsX1[2],
664		}
665		call = func(env *Env) (r.Value, []r.Value) {
666			funv := exprfun(env)
667			argv := []r.Value{
668				argfuns[0](env),
669				argfuns[1](env),
670				argfuns[2](env),
671			}
672			retv := callslicexr(funv, argv)
673			return retv[0], retv
674		}
675	default:
676		// general case
677		call = func(env *Env) (r.Value, []r.Value) {
678			funv := exprfun(env)
679			argv := make([]r.Value, len(argfunsX1))
680			for i, argfun := range argfunsX1 {
681				argv[i] = argfun(env)
682			}
683			retv := callslicexr(funv, argv)
684			return retv[0], retv
685		}
686	}
687	return call
688}
689