forked from cosmos72/gomacro
/
place_set_value.go
79 lines (75 loc) · 1.96 KB
/
place_set_value.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
/*
* gomacro - A Go interpreter with Lisp-like macros
*
* Copyright (C) 2017-2019 Massimiliano Ghilardi
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*
* place_set_value.go
*
* Created on May 29, 2017
* Author Massimiliano Ghilardi
*/
package fast
import (
"github.com/lifepod-solutions/gomacro/base/reflect"
xr "github.com/lifepod-solutions/gomacro/xreflect"
)
// placeSetValue compiles 'place = value' where value is a reflect.Value passed at runtime.
// Used to assign places with the result of multi-valued expressions,
// and to implement multiple assignment place1, place2... = expr1, expr2...
func (c *Comp) placeSetValue(place *Place) func(lhs, key, val xr.Value) {
rtype := place.Type.ReflectType()
if place.MapKey != nil {
zero := xr.ZeroR(rtype)
return func(lhs, key, val xr.Value) {
if !val.IsValid() || val == None {
val = zero
} else if val.Type() != rtype {
val = val.Convert(rtype)
}
lhs.SetMapIndex(key, val)
}
}
var ret func(xr.Value, xr.Value, xr.Value)
switch reflect.Category(rtype.Kind()) {
case xr.Bool:
ret = func(lhs, key, val xr.Value) {
lhs.SetBool(val.Bool())
}
case xr.Int:
ret = func(lhs, key, val xr.Value) {
lhs.SetInt(val.Int())
}
case xr.Uint:
ret = func(lhs, key, val xr.Value) {
lhs.SetUint(val.Uint())
}
case xr.Float64:
ret = func(lhs, key, val xr.Value) {
lhs.SetFloat(val.Float())
}
case xr.Complex128:
ret = func(lhs, key, val xr.Value) {
lhs.SetComplex(val.Complex())
}
case xr.String:
ret = func(lhs, key, val xr.Value) {
lhs.SetString(val.String())
}
default:
zero := xr.ZeroR(rtype)
ret = func(lhs, key, val xr.Value) {
if !val.IsValid() || val == None {
val = zero
} else if val.Type() != rtype {
val = val.Convert(rtype)
}
lhs.Set(val)
}
}
return ret
}