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