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_multivalue.go 12 * 13 * Created on May 29, 2017 14 * Author Massimiliano Ghilardi 15 */ 16 17package fast 18 19import ( 20 r "reflect" 21) 22 23// call_multivalue compiles foo(bar()) where bar() returns multiple values 24func call_multivalue(call *Call, maxdepth int) I { 25 // no need to special case variadic functions here 26 expr := call.Fun 27 exprfun := expr.AsX1() 28 argfun := call.Args[0].AsXV(COptDefaults) 29 nout := len(call.OutTypes) 30 var ret I 31 switch nout { 32 case 0: 33 if call.Ellipsis { 34 ret = func(env *Env) { 35 funv := exprfun(env) 36 _, argv := argfun(env) 37 callslicexr(funv, argv) 38 } 39 } else { 40 ret = func(env *Env) { 41 funv := exprfun(env) 42 _, argv := argfun(env) 43 callxr(funv, argv) 44 } 45 } 46 case 1: 47 if call.Ellipsis { 48 ret = call_multivalue_ellipsis_ret1(call, maxdepth) 49 } else { 50 ret = call_multivalue_ret1(call, maxdepth) 51 } 52 default: 53 if call.Ellipsis { 54 ret = func(env *Env) (r.Value, []r.Value) { 55 funv := exprfun(env) 56 _, argv := argfun(env) 57 rets := callslicexr(funv, argv) 58 return rets[0], rets 59 } 60 } else { 61 ret = func(env *Env) (r.Value, []r.Value) { 62 funv := exprfun(env) 63 _, argv := argfun(env) 64 rets := callxr(funv, argv) 65 return rets[0], rets 66 } 67 } 68 } 69 return ret 70} 71 72// mandatory optimization: fast_interpreter ASSUMES that expressions 73// returning bool, int, uint, float, complex, string do NOT wrap them in reflect.Value 74func call_multivalue_ret1(call *Call, maxdepth int) I { 75 exprfun := call.Fun.AsX1() 76 argfun := call.Args[0].AsXV(COptDefaults) 77 kout := call.OutTypes[0].Kind() 78 var ret I 79 switch kout { 80 case r.Bool: 81 ret = func(env *Env) bool { 82 funv := exprfun(env) 83 _, argv := argfun(env) 84 retv := callxr(funv, argv)[0] 85 return retv.Bool() 86 } 87 case r.Int: 88 ret = func(env *Env) int { 89 funv := exprfun(env) 90 _, argv := argfun(env) 91 retv := callxr(funv, argv)[0] 92 return int(retv.Int()) 93 } 94 case r.Int8: 95 ret = func(env *Env) int8 { 96 funv := exprfun(env) 97 _, argv := argfun(env) 98 retv := callxr(funv, argv)[0] 99 return int8(retv.Int()) 100 } 101 case r.Int16: 102 ret = func(env *Env) int16 { 103 funv := exprfun(env) 104 _, argv := argfun(env) 105 retv := callxr(funv, argv)[0] 106 return int16(retv.Int()) 107 } 108 case r.Int32: 109 ret = func(env *Env) int32 { 110 funv := exprfun(env) 111 _, argv := argfun(env) 112 retv := callxr(funv, argv)[0] 113 return int32(retv.Int()) 114 } 115 case r.Int64: 116 ret = func(env *Env) int64 { 117 funv := exprfun(env) 118 _, argv := argfun(env) 119 retv := callxr(funv, argv)[0] 120 return retv.Int() 121 } 122 case r.Uint: 123 ret = func(env *Env) uint { 124 funv := exprfun(env) 125 _, argv := argfun(env) 126 retv := callxr(funv, argv)[0] 127 return uint(retv.Uint()) 128 } 129 case r.Uint8: 130 ret = func(env *Env) uint8 { 131 funv := exprfun(env) 132 _, argv := argfun(env) 133 retv := callxr(funv, argv)[0] 134 return uint8(retv.Uint()) 135 } 136 case r.Uint16: 137 ret = func(env *Env) uint16 { 138 funv := exprfun(env) 139 _, argv := argfun(env) 140 retv := callxr(funv, argv)[0] 141 return uint16(retv.Uint()) 142 } 143 case r.Uint32: 144 ret = func(env *Env) uint32 { 145 funv := exprfun(env) 146 _, argv := argfun(env) 147 retv := callxr(funv, argv)[0] 148 return uint32(retv.Uint()) 149 } 150 case r.Uint64: 151 ret = func(env *Env) uint64 { 152 funv := exprfun(env) 153 _, argv := argfun(env) 154 retv := callxr(funv, argv)[0] 155 return retv.Uint() 156 } 157 case r.Uintptr: 158 ret = func(env *Env) uintptr { 159 funv := exprfun(env) 160 _, argv := argfun(env) 161 retv := callxr(funv, argv)[0] 162 return uintptr(retv.Uint()) 163 } 164 case r.Float32: 165 ret = func(env *Env) float32 { 166 funv := exprfun(env) 167 _, argv := argfun(env) 168 retv := callxr(funv, argv)[0] 169 return float32(retv.Float()) 170 } 171 case r.Float64: 172 ret = func(env *Env) float64 { 173 funv := exprfun(env) 174 _, argv := argfun(env) 175 retv := callxr(funv, argv)[0] 176 return retv.Float() 177 } 178 case r.Complex64: 179 ret = func(env *Env) complex64 { 180 funv := exprfun(env) 181 _, argv := argfun(env) 182 retv := callxr(funv, argv)[0] 183 return complex64(retv.Complex()) 184 } 185 case r.Complex128: 186 ret = func(env *Env) complex128 { 187 funv := exprfun(env) 188 _, argv := argfun(env) 189 retv := callxr(funv, argv)[0] 190 return retv.Complex() 191 } 192 case r.String: 193 ret = func(env *Env) string { 194 funv := exprfun(env) 195 _, argv := argfun(env) 196 retv := callxr(funv, argv)[0] 197 return retv.String() 198 } 199 default: 200 ret = func(env *Env) r.Value { 201 funv := exprfun(env) 202 _, argv := argfun(env) 203 return callxr(funv, argv)[0] 204 } 205 } 206 return ret 207} 208 209// mandatory optimization: fast_interpreter ASSUMES that expressions 210// returning bool, int, uint, float, complex, string do NOT wrap them in reflect.Value 211func call_multivalue_ellipsis_ret1(call *Call, maxdepth int) I { 212 exprfun := call.Fun.AsX1() 213 argfun := call.Args[0].AsXV(COptDefaults) 214 kout := call.OutTypes[0].Kind() 215 var ret I 216 switch kout { 217 case r.Bool: 218 ret = func(env *Env) bool { 219 funv := exprfun(env) 220 _, argv := argfun(env) 221 retv := callslicexr(funv, argv)[0] 222 return retv.Bool() 223 } 224 case r.Int: 225 ret = func(env *Env) int { 226 funv := exprfun(env) 227 _, argv := argfun(env) 228 retv := callslicexr(funv, argv)[0] 229 return int(retv.Int()) 230 } 231 case r.Int8: 232 ret = func(env *Env) int8 { 233 funv := exprfun(env) 234 _, argv := argfun(env) 235 retv := callslicexr(funv, argv)[0] 236 return int8(retv.Int()) 237 } 238 case r.Int16: 239 ret = func(env *Env) int16 { 240 funv := exprfun(env) 241 _, argv := argfun(env) 242 retv := callslicexr(funv, argv)[0] 243 return int16(retv.Int()) 244 } 245 case r.Int32: 246 ret = func(env *Env) int32 { 247 funv := exprfun(env) 248 _, argv := argfun(env) 249 retv := callslicexr(funv, argv)[0] 250 return int32(retv.Int()) 251 } 252 case r.Int64: 253 ret = func(env *Env) int64 { 254 funv := exprfun(env) 255 _, argv := argfun(env) 256 retv := callslicexr(funv, argv)[0] 257 return retv.Int() 258 } 259 case r.Uint: 260 ret = func(env *Env) uint { 261 funv := exprfun(env) 262 _, argv := argfun(env) 263 retv := callslicexr(funv, argv)[0] 264 return uint(retv.Uint()) 265 } 266 case r.Uint8: 267 ret = func(env *Env) uint8 { 268 funv := exprfun(env) 269 _, argv := argfun(env) 270 retv := callslicexr(funv, argv)[0] 271 return uint8(retv.Uint()) 272 } 273 case r.Uint16: 274 ret = func(env *Env) uint16 { 275 funv := exprfun(env) 276 _, argv := argfun(env) 277 retv := callslicexr(funv, argv)[0] 278 return uint16(retv.Uint()) 279 } 280 case r.Uint32: 281 ret = func(env *Env) uint32 { 282 funv := exprfun(env) 283 _, argv := argfun(env) 284 retv := callslicexr(funv, argv)[0] 285 return uint32(retv.Uint()) 286 } 287 case r.Uint64: 288 ret = func(env *Env) uint64 { 289 funv := exprfun(env) 290 _, argv := argfun(env) 291 retv := callslicexr(funv, argv)[0] 292 return retv.Uint() 293 } 294 case r.Uintptr: 295 ret = func(env *Env) uintptr { 296 funv := exprfun(env) 297 _, argv := argfun(env) 298 retv := callslicexr(funv, argv)[0] 299 return uintptr(retv.Uint()) 300 } 301 case r.Float32: 302 ret = func(env *Env) float32 { 303 funv := exprfun(env) 304 _, argv := argfun(env) 305 retv := callslicexr(funv, argv)[0] 306 return float32(retv.Float()) 307 } 308 case r.Float64: 309 ret = func(env *Env) float64 { 310 funv := exprfun(env) 311 _, argv := argfun(env) 312 retv := callslicexr(funv, argv)[0] 313 return retv.Float() 314 } 315 case r.Complex64: 316 ret = func(env *Env) complex64 { 317 funv := exprfun(env) 318 _, argv := argfun(env) 319 retv := callslicexr(funv, argv)[0] 320 return complex64(retv.Complex()) 321 } 322 case r.Complex128: 323 ret = func(env *Env) complex128 { 324 funv := exprfun(env) 325 _, argv := argfun(env) 326 retv := callslicexr(funv, argv)[0] 327 return retv.Complex() 328 } 329 case r.String: 330 ret = func(env *Env) string { 331 funv := exprfun(env) 332 _, argv := argfun(env) 333 retv := callslicexr(funv, argv)[0] 334 return retv.String() 335 } 336 default: 337 ret = func(env *Env) r.Value { 338 funv := exprfun(env) 339 _, argv := argfun(env) 340 return callslicexr(funv, argv)[0] 341 } 342 } 343 return ret 344} 345