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 * literal.go 12 * 13 * Created on Apr 01, 2017 14 * Author Massimiliano Ghilardi 15 */ 16 17package fast 18 19import ( 20 "go/ast" 21 "go/constant" 22 "go/token" 23 "math/big" 24 r "reflect" 25 26 "github.com/cosmos72/gomacro/base/output" 27 28 "github.com/cosmos72/gomacro/base/reflect" 29 "github.com/cosmos72/gomacro/base/untyped" 30 xr "github.com/cosmos72/gomacro/xreflect" 31) 32 33func (c *Comp) BasicLit(node *ast.BasicLit) *Expr { 34 str := node.Value 35 var kind untyped.Kind 36 var label string 37 switch node.Kind { 38 case token.INT: 39 kind, label = untyped.Int, "integer" 40 case token.FLOAT: 41 kind, label = untyped.Float, "float" 42 case token.IMAG: 43 kind, label = untyped.Complex, "complex" 44 case token.CHAR: 45 kind, label = untyped.Rune, "rune" 46 case token.STRING: 47 kind, label = untyped.String, "string" 48 default: 49 c.Errorf("unsupported basic literal: %v", node) 50 return nil 51 } 52 obj := constant.MakeFromLiteral(str, node.Kind, 0) 53 if obj.Kind() == constant.Unknown { 54 c.Errorf("invalid %s literal: %v", label, str) 55 return nil 56 } 57 return c.exprUntypedLit(kind, obj) 58} 59 60func isLiteral(x interface{}) bool { 61 if x == nil { 62 return true 63 } 64 rtype := r.TypeOf(x) 65 switch reflect.Category(rtype.Kind()) { 66 case r.Bool, r.Int, r.Uint, r.Float64, r.Complex128, r.String: 67 return true 68 } 69 _, ok := x.(UntypedLit) 70 return ok 71} 72 73func isLiteralNumber(x I, n int64) bool { 74 if x == nil { 75 return false 76 } 77 v := r.ValueOf(x) 78 switch reflect.Category(v.Kind()) { 79 case r.Bool: 80 return false 81 case r.Int: 82 return v.Int() == n 83 case r.Uint: 84 // n == -1 means "unsigned integer equals its maximum value" 85 // similarly, n == -2 means "unsigned integer equals its maximum value minus 1" 86 // and so on... 87 return v.Uint() == uint64(n) 88 case r.Float64: 89 return v.Float() == float64(n) 90 case r.Complex128: 91 return v.Complex() == complex(float64(n), 0) 92 case r.String: 93 return false 94 } 95 // no luck yet... try harder 96 switch x := x.(type) { 97 case r.Value: 98 return false 99 case UntypedLit: 100 return x.EqualInt64(n) 101 } 102 output.Errorf("isLiteralNumber: unexpected literal type %v <%v>", x, r.TypeOf(x)) 103 return false 104} 105 106// ================================= ConstTo ================================= 107 108// ConstTo checks that a constant Expr can be used as the given type. 109// panics if not constant, or if Expr is a typed constant of different type 110// actually performs type conversion (and subsequent overflow checks) ONLY on untyped constants. 111func (e *Expr) ConstTo(t xr.Type) I { 112 if !e.Const() { 113 output.Errorf("internal error: expression is not constant, use Expr.To() instead of Expr.ConstTo() to convert from <%v> to <%v>", e.Type, t) 114 } 115 val := e.Lit.ConstTo(t) 116 fun := makeMathBigFun(val) 117 if fun != nil { 118 // no longer a constant 119 e.Lit.Value = nil 120 e.Fun = fun 121 } else { 122 if e.Fun != nil { 123 // e.Fun is no longer valid, recompute it 124 e.WithFun() 125 } 126 } 127 return val 128} 129 130// ConstTo checks that a Lit can be used as the given type. 131// panics if Lit is a typed constant of different type 132// actually performs type conversion (and subsequent overflow checks) ONLY on untyped constants. 133func (lit *Lit) ConstTo(t xr.Type) I { 134 value := lit.Value 135 // output.Debugf("Lit.ConstTo(): converting constant %v <%v> (stored as <%v>) to <%v>", value, TypeOf(value), lit.Type, t) 136 if t == nil { 137 // only literal nil has type nil 138 if value != nil { 139 output.Errorf("cannot convert constant %v <%v> to <nil>", value, lit.Type) 140 } 141 return nil 142 } 143 // stricter than t == lit.Type 144 tfrom := lit.Type 145 if tfrom != nil && t != nil && tfrom.IdenticalTo(t) { 146 return value 147 } 148 switch x := value.(type) { 149 case UntypedLit: 150 val := x.Convert(t) 151 lit.Type = t 152 lit.Value = val 153 // output.Debugf("UntypedLit.Convert(): converted untyped constant %v to %v <%v> (stored as <%v>)", x, val, TypeOf(val), t) 154 return val 155 case nil: 156 // literal nil can only be converted to nillable types 157 if reflect.IsNillableKind(t.Kind()) { 158 lit.Type = t 159 return nil 160 // lit.Value = r.Zero(t).Interface() 161 // return lit.Value 162 } 163 } 164 if tfrom != nil && t != nil && (tfrom.AssignableTo(t) || t.Kind() == r.Interface && tfrom.Implements(t)) { 165 lit.Type = t 166 // FIXME: use (*Comp).Converter(), requires a *Comp parameter 167 lit.Value = convert(r.ValueOf(value), t.ReflectType()).Interface() 168 return lit.Value 169 } 170 output.Errorf("cannot convert typed constant %v <%v> to <%v>%s", value, lit.Type, t, interfaceMissingMethod(lit.Type, t)) 171 return nil 172} 173 174// return a closure that duplicates at each invokation any *big.Int, *big.Rat, *big.Float passed as 'val' 175func makeMathBigFun(val I) func(*Env) r.Value { 176 switch a := val.(type) { 177 case *big.Int: 178 return func(*Env) r.Value { 179 var b big.Int 180 b.Set(a) 181 return r.ValueOf(&b) 182 } 183 case *big.Rat: 184 return func(*Env) r.Value { 185 var b big.Rat 186 b.Set(a) 187 return r.ValueOf(&b) 188 } 189 case *big.Float: 190 return func(*Env) r.Value { 191 var b big.Float 192 b.Set(a) 193 return r.ValueOf(&b) 194 } 195 default: 196 return nil 197 } 198} 199 200// ================================= DefaultType ================================= 201 202// DefaultType returns the default type of an expression. 203func (e *Expr) DefaultType() xr.Type { 204 if e.Untyped() { 205 return e.Lit.DefaultType() 206 } 207 return e.Type 208} 209 210// DefaultType returns the default type of a constant. 211func (lit *Lit) DefaultType() xr.Type { 212 switch x := lit.Value.(type) { 213 case UntypedLit: 214 return x.DefaultType() 215 default: 216 return lit.Type 217 } 218} 219 220// SetTypes sets the expression result types 221func (e *Expr) SetTypes(tout []xr.Type) { 222 switch len(tout) { 223 case 0: 224 e.Type = nil 225 e.Types = tout 226 case 1: 227 e.Type = tout[0] 228 e.Types = nil 229 default: 230 e.Type = tout[0] 231 e.Types = tout 232 } 233} 234 235/* used? 236 237// Set sets the expression value to the given (typed or untyped) constant 238func (e *Expr) Set(x I) { 239 e.Lit.Set(x) 240 e.Types = nil 241 e.Fun = nil 242 e.IsNil = x == nil 243} 244 245// Set sets the Lit to the given typed constant 246func (lit *Lit) Set(x I) { 247 t := TypeOf(x) 248 if !isLiteral(x) { 249 Errorf("cannot set Lit to non-literal value %v <%v>", x, t) 250 } 251 lit.Type = t 252 lit.Value = x 253} 254*/ 255 256// To checks that an Expr can be used as (i.e. is assignable to) the given type, 257// and converts Expr to the given type. 258// panics if Expr has an incompatible type. 259func (e *Expr) To(c *Comp, t xr.Type) { 260 if e.Const() { 261 e.ConstTo(t) 262 return 263 } 264 if e.Type.IdenticalTo(t) { 265 return 266 } 267 if !e.Type.AssignableTo(t) { 268 c.Errorf("cannot use <%v> as <%v>", e.Type, t) 269 } 270 k := e.Type.Kind() 271 if reflect.IsOptimizedKind(k) { 272 if k == t.Kind() { 273 // same optimized representation 274 e.Type = t 275 return 276 } else if t.Kind() == r.Interface { 277 e.Fun = e.AsX1() 278 e.Type = t 279 return 280 } 281 c.Errorf("internal error: cannot use <%v> as <%v> (should not happen, <%v> is assignable to <%v>", e.Type, t, e.Type, t) 282 } 283 fun := e.AsX1() 284 rtype := t.ReflectType() 285 zero := r.Zero(rtype) 286 287 if conv := c.Converter(e.Type, t); conv == nil { 288 e.Fun = func(env *Env) r.Value { 289 v := fun(env) 290 if !v.IsValid() { 291 v = zero 292 } 293 return v 294 } 295 } else { 296 e.Fun = func(env *Env) r.Value { 297 v := fun(env) 298 if !v.IsValid() { 299 v = zero 300 } else { 301 v = conv(v) 302 } 303 return v 304 } 305 } 306 e.Type = t 307} 308 309// WithFun ensures that Expr.Fun is a closure that will return the expression result: 310// 311// if Expr is an untyped constant, WithFun converts the constant to its default type (panics on overflows), 312// then sets Expr.Fun to a closure that will return such constant. 313// if Expr is a typed constant, WithFun sets Expr.Fun to a closure that will return such constant. 314// if Expr is not a constant, WithFun does nothing (Expr.Fun must be set already) 315func (e *Expr) WithFun() I { 316 if !e.Const() { 317 return e.Fun 318 } 319 var fun I 320again: 321 value := e.Value 322 v := r.ValueOf(value) 323 t := e.Type 324 if t == nil { 325 e.Fun = eNil 326 return eNil 327 } 328 if value == nil { 329 if !reflect.IsNillableKind(t.Kind()) { 330 output.Errorf("internal error: constant of type <%v> cannot be nil", t) 331 } 332 zero := r.Zero(t.ReflectType()) 333 fun = func(*Env) r.Value { 334 return zero 335 } 336 e.Fun = fun 337 return fun 338 } 339 rtactual := r.TypeOf(value) 340 rtexpected := t.ReflectType() 341 if rtexpected != rtactual { 342 if rtexpected.Kind() == r.Interface && rtactual.Implements(rtexpected) { 343 v = convert(v, rtexpected) 344 } else { 345 output.Errorf("internal error: constant %v <%v> was assumed to have type <%v>", value, rtactual, rtexpected) 346 } 347 } 348 switch v.Kind() { 349 case r.Invalid: 350 fun = eNil 351 case r.Bool: 352 if v.Bool() { 353 fun = eTrue 354 } else { 355 fun = eFalse 356 } 357 case r.Int: 358 x := int(v.Int()) 359 fun = func(env *Env) int { 360 return x 361 } 362 case r.Int8: 363 x := int8(v.Int()) 364 fun = func(env *Env) int8 { 365 return x 366 } 367 case r.Int16: 368 x := int16(v.Int()) 369 fun = func(env *Env) int16 { 370 return x 371 } 372 case r.Int32: 373 x := int32(v.Int()) 374 fun = func(env *Env) int32 { 375 return x 376 } 377 case r.Int64: 378 x := v.Int() 379 fun = func(env *Env) int64 { 380 return x 381 } 382 case r.Uint: 383 x := uint(v.Uint()) 384 fun = func(env *Env) uint { 385 return x 386 } 387 case r.Uint8: 388 x := uint8(v.Uint()) 389 fun = func(env *Env) uint8 { 390 return x 391 } 392 case r.Uint16: 393 x := uint16(v.Uint()) 394 fun = func(env *Env) uint16 { 395 return x 396 } 397 case r.Uint32: 398 x := uint32(v.Uint()) 399 fun = func(env *Env) uint32 { 400 return x 401 } 402 case r.Uint64: 403 x := v.Uint() 404 fun = func(env *Env) uint64 { 405 return x 406 } 407 case r.Uintptr: 408 x := uintptr(v.Uint()) 409 fun = func(env *Env) uintptr { 410 return x 411 } 412 case r.Float32: 413 x := float32(v.Float()) 414 fun = func(env *Env) float32 { 415 return x 416 } 417 case r.Float64: 418 x := v.Float() 419 fun = func(env *Env) float64 { 420 return x 421 } 422 case r.Complex64: 423 x := complex64(v.Complex()) 424 fun = func(env *Env) complex64 { 425 return x 426 } 427 case r.Complex128: 428 x := v.Complex() 429 fun = func(env *Env) complex128 { 430 return x 431 } 432 case r.String: 433 x := v.String() 434 fun = func(env *Env) string { 435 return x 436 } 437 default: 438 if t.ReflectType() == rtypeOfUntypedLit { 439 e.ConstTo(e.DefaultType()) 440 goto again 441 } 442 fun = func(env *Env) r.Value { 443 return v 444 } 445 } 446 e.Fun = fun 447 return fun 448} 449