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 * place_set_value.go
12 *
13 *  Created on May 29, 2017
14 *      Author Massimiliano Ghilardi
15 */
16
17package fast
18
19import (
20	r "reflect"
21
22	. "github.com/cosmos72/gomacro/base"
23	"github.com/cosmos72/gomacro/base/reflect"
24)
25
26// placeSetValue compiles 'place = value' where value is a reflect.Value passed at runtime.
27// Used to assign places with the result of multi-valued expressions,
28// and to implement multiple assignment place1, place2... = expr1, expr2...
29func (c *Comp) placeSetValue(place *Place) func(lhs, key, val r.Value) {
30	rtype := place.Type.ReflectType()
31
32	if place.MapKey != nil {
33		zero := r.Zero(rtype)
34		return func(lhs, key, val r.Value) {
35			if val == Nil || val == None {
36				val = zero
37			} else if val.Type() != rtype {
38				val = val.Convert(rtype)
39			}
40			lhs.SetMapIndex(key, val)
41		}
42	}
43	var ret func(r.Value, r.Value, r.Value)
44	switch reflect.Category(rtype.Kind()) {
45	case r.Bool:
46		ret = func(lhs, key, val r.Value) {
47			lhs.SetBool(val.Bool())
48		}
49	case r.Int:
50		ret = func(lhs, key, val r.Value) {
51			lhs.SetInt(val.Int())
52		}
53	case r.Uint:
54		ret = func(lhs, key, val r.Value) {
55			lhs.SetUint(val.Uint())
56		}
57	case r.Float64:
58		ret = func(lhs, key, val r.Value) {
59			lhs.SetFloat(val.Float())
60		}
61	case r.Complex128:
62		ret = func(lhs, key, val r.Value) {
63			lhs.SetComplex(val.Complex())
64		}
65	case r.String:
66		ret = func(lhs, key, val r.Value) {
67			lhs.SetString(val.String())
68		}
69	default:
70		zero := r.Zero(rtype)
71		ret = func(lhs, key, val r.Value) {
72			if val == Nil || val == None {
73				val = zero
74			} else if val.Type() != rtype {
75				val = val.Convert(rtype)
76			}
77			lhs.Set(val)
78		}
79	}
80	return ret
81}
82