github.com/neugram/ng@v0.0.0-20180309130942-d472ff93d872/syntax/tipe/tipe.go (about) 1 // Copyright 2015 The Neugram Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package tipe defines data structures representing Neugram types. 6 // 7 // Go took the usual spelling of type. 8 package tipe 9 10 import ( 11 "fmt" 12 "reflect" 13 "sort" 14 ) 15 16 type Type interface { 17 tipe() 18 } 19 20 type Func struct { 21 Spec Specialization 22 Params *Tuple 23 Results *Tuple 24 Variadic bool // last value of Params is a slice 25 FreeVars []string 26 FreeMdik []*Named 27 } 28 29 type Struct struct { 30 Spec Specialization 31 Fields []StructField 32 } 33 34 // StructField is a field of a Struct. It is not an ng type. 35 type StructField struct { 36 Name string 37 Type Type 38 Tag StructTag 39 Embedded bool 40 } 41 42 // StructTag is the tag string in a struct field. 43 type StructTag string 44 45 // Named is a named type. 46 // A named type is declared either using a type declaration: 47 // 48 // type S struct{} 49 // 50 // or the methodik declaration: 51 // 52 // methodik S struct{} {} 53 // 54 // As in Go, a named type has an underlying type. 55 // A named type can also have methods associated with it. 56 type Named struct { 57 // TODO: need to track the definition package so the evaluator can 58 // extract the mscope from the right place. Is this the only 59 // instance of needing the source package? What about debug printing? 60 Spec Specialization 61 Type Type 62 63 PkgName string 64 PkgPath string 65 Name string 66 67 MethodNames []string 68 Methods []*Func 69 } 70 71 type Ellipsis struct { 72 Elem Type 73 } 74 75 type Array struct { 76 Len int64 77 Elem Type 78 Ellipsis bool // array was defined as [...]T 79 } 80 81 type Slice struct { 82 Elem Type 83 } 84 85 type Table struct { 86 Type Type 87 } 88 89 type Tuple struct { 90 Elems []Type 91 } 92 93 type Pointer struct { 94 Elem Type 95 } 96 97 type ChanDirection int 98 99 const ( 100 ChanBoth ChanDirection = iota 101 ChanSend 102 ChanRecv 103 ) 104 105 type Chan struct { 106 Direction ChanDirection 107 Elem Type 108 } 109 110 type Map struct { 111 Key Type 112 Value Type 113 } 114 115 type Package struct { 116 GoPkg interface{} // *gotypes.Package 117 Path string 118 Exports map[string]Type 119 } 120 121 type Interface struct { 122 Methods map[string]*Func 123 } 124 125 type Alias struct { 126 Name string 127 Type Type 128 } 129 130 var ( 131 Byte = &Alias{Name: "byte", Type: Uint8} 132 Rune = &Alias{Name: "rune", Type: Int32} 133 ) 134 135 // Specialization carries any type specialization data particular to this type. 136 // 137 // *Func, *Struct, *Named can be parameterized over the name num, which can 138 // take any of: 139 // 140 // integer, int64, float, float32, float64, complex, complex128 141 // 142 // At the defnition of a class or function, the matching Type will have the 143 // Num filed set to Invalid if it is not parameterized, or Num if it is. 144 // 145 // On a value of a parameterized class or a Call of a parameterized function, 146 // Num will either Num or one of the basic numeric types (if specialized). 147 type Specialization struct { 148 // Num is the specialization of the type parameter num in 149 Num Basic 150 } 151 152 type Basic string 153 154 const ( 155 Invalid Basic = "invalid" 156 Num Basic = "num" // type parameter 157 Bool Basic = "bool" 158 Integer Basic = "integer" 159 Float Basic = "float" 160 Complex Basic = "cmplx" 161 String Basic = "string" 162 163 Int Basic = "int" 164 Int8 Basic = "int8" 165 Int16 Basic = "int16" 166 Int32 Basic = "int32" 167 Int64 Basic = "int64" 168 169 Uint Basic = "uint" 170 Uint8 Basic = "uint8" 171 Uint16 Basic = "uint16" 172 Uint32 Basic = "uint32" 173 Uint64 Basic = "uint64" 174 Uintptr Basic = "uintptr" 175 176 Float32 Basic = "float32" 177 Float64 Basic = "float64" 178 179 Complex64 Basic = "complex64" 180 Complex128 Basic = "complex128" 181 182 UnsafePointer Basic = "unsafe pointer" 183 184 UntypedNil Basic = "untyped nil" // nil pointer or nil interface 185 UntypedString Basic = "untyped string" 186 UntypedBool Basic = "untyped bool" 187 UntypedInteger Basic = "untyped integer" 188 UntypedFloat Basic = "untyped float" 189 UntypedRune Basic = "untyped rune" 190 UntypedComplex Basic = "untyped complex" 191 ) 192 193 type Builtin string 194 195 const ( 196 Append Builtin = "builtin append" 197 Cap Builtin = "builtin cap" 198 Close Builtin = "builtin close" 199 ComplexFunc Builtin = "builtin complex" 200 Copy Builtin = "builtin copy" 201 Delete Builtin = "builtin delete" 202 Imag Builtin = "builtin imag" 203 Len Builtin = "builtin len" 204 Make Builtin = "builtin make" 205 New Builtin = "builtin new" 206 Panic Builtin = "builtin panic" 207 Real Builtin = "builtin real" 208 Recover Builtin = "builtin recover" 209 // TODO Print 210 ) 211 212 type Unresolved struct { 213 Package string 214 Name string 215 } 216 217 var ( 218 _ = Type(Basic("")) 219 _ = Type(Builtin("")) 220 _ = Type((*Func)(nil)) 221 _ = Type((*Struct)(nil)) 222 _ = Type((*Named)(nil)) 223 _ = Type((*Ellipsis)(nil)) 224 _ = Type((*Array)(nil)) 225 _ = Type((*Slice)(nil)) 226 _ = Type((*Table)(nil)) 227 _ = Type((*Tuple)(nil)) 228 _ = Type((*Pointer)(nil)) 229 _ = Type((*Chan)(nil)) 230 _ = Type((*Map)(nil)) 231 _ = Type((*Package)(nil)) 232 _ = Type((*Interface)(nil)) 233 _ = Type((*Alias)(nil)) 234 _ = Type((*Unresolved)(nil)) 235 ) 236 237 func (t Basic) tipe() {} 238 func (t Builtin) tipe() {} 239 func (t *Func) tipe() {} 240 func (t *Struct) tipe() {} 241 func (t *Named) tipe() {} 242 func (t *Ellipsis) tipe() {} 243 func (t *Array) tipe() {} 244 func (t *Slice) tipe() {} 245 func (t *Table) tipe() {} 246 func (t *Tuple) tipe() {} 247 func (t *Pointer) tipe() {} 248 func (t *Chan) tipe() {} 249 func (t *Map) tipe() {} 250 func (t *Package) tipe() {} 251 func (t *Interface) tipe() {} 252 func (t *Alias) tipe() {} 253 func (t *Unresolved) tipe() {} 254 255 func IsNumeric(t Type) bool { 256 t = Unalias(t) 257 b, ok := Underlying(t).(Basic) 258 if !ok { 259 return false 260 } 261 switch b { 262 case Num, Integer, Float, Complex, 263 Int, Int8, Int16, Int32, Int64, 264 Uint, Uint8, Uint16, Uint32, Uint64, 265 Float32, Float64, Complex64, Complex128, 266 UntypedInteger, UntypedFloat, UntypedComplex: 267 return true 268 } 269 return false 270 } 271 272 func IsUntypedNil(t Type) bool { 273 b, _ := Underlying(t).(Basic) 274 return b == UntypedNil 275 } 276 277 func UsesNum(t Type) bool { 278 return usesNum(t, make(map[Type]bool)) 279 } 280 281 func usesNum(t Type, path map[Type]bool) bool { 282 t = Unalias(t) 283 if path[t] { 284 return false 285 } 286 path[t] = true 287 288 switch t := t.(type) { 289 case *Func: 290 if t.Params != nil { 291 for _, t := range t.Params.Elems { 292 if usesNum(t, path) { 293 return true 294 } 295 } 296 } 297 if t.Results != nil { 298 for _, t := range t.Results.Elems { 299 if usesNum(t, path) { 300 return true 301 } 302 } 303 } 304 case *Struct: 305 for _, sf := range t.Fields { 306 if usesNum(sf.Type, path) { 307 return true 308 } 309 } 310 case *Named: 311 for _, t := range t.Methods { 312 if usesNum(t, path) { 313 return true 314 } 315 } 316 case *Array: 317 if usesNum(t.Elem, path) { 318 return true 319 } 320 case *Slice: 321 if usesNum(t.Elem, path) { 322 return true 323 } 324 case *Table: 325 if usesNum(t.Type, path) { 326 return true 327 } 328 case Basic: 329 return t == Num 330 case Builtin: 331 return false 332 } 333 return false 334 } 335 336 func Unalias(t Type) Type { 337 for { 338 if u, ok := t.(*Alias); ok { 339 t = u.Type 340 } else { 341 break 342 } 343 } 344 return t 345 } 346 347 func Equal(x, y Type) bool { 348 eq := equaler{} 349 return eq.equal(x, y) 350 } 351 352 func EqualUnresolved(x, y Type) bool { 353 eq := equaler{matchUnresolved: true} 354 return eq.equal(x, y) 355 } 356 357 type equaler struct { 358 matchUnresolved bool 359 } 360 361 func (eq *equaler) equal(x, y Type) bool { 362 x, y = Unalias(x), Unalias(y) 363 if x == y { 364 return true 365 } 366 switch x := x.(type) { 367 case Basic: 368 y, ok := y.(Basic) 369 if !ok { 370 return false 371 } 372 switch { 373 case x == Float && (y == Float32 || y == Float64): 374 // handle floatXX <- float 375 return true 376 case x == Complex && (y == Complex64 || y == Complex128): 377 return true 378 default: 379 return x == y 380 } 381 case Builtin: 382 y, ok := y.(Builtin) 383 if !ok { 384 return false 385 } 386 return x == y 387 case *Func: 388 y, ok := y.(*Func) 389 if !ok { 390 return false 391 } 392 if x == nil || y == nil { 393 return false 394 } 395 if x.Spec != y.Spec { 396 return false 397 } 398 if !eq.equal(x.Params, y.Params) { 399 return false 400 } 401 if !eq.equal(x.Results, y.Results) { 402 return false 403 } 404 return true 405 case *Struct: 406 y, ok := y.(*Struct) 407 if !ok { 408 return false 409 } 410 if x == nil || y == nil { 411 return false 412 } 413 if x.Spec != y.Spec { 414 return false 415 } 416 if len(x.Fields) != len(y.Fields) { 417 return false 418 } 419 for i := range x.Fields { 420 if x.Fields[i].Name != y.Fields[i].Name { 421 return false 422 } 423 if x.Fields[i].Embedded != y.Fields[i].Embedded { 424 return false 425 } 426 if !eq.equal(x.Fields[i].Type, y.Fields[i].Type) { 427 return false 428 } 429 if x.Fields[i].Tag != y.Fields[i].Tag { 430 return false 431 } 432 } 433 return true 434 case *Named: 435 y, ok := y.(*Named) 436 if !ok { 437 return false 438 } 439 if x == nil || y == nil { 440 return false 441 } 442 if x.Spec != y.Spec { 443 return false 444 } 445 if !eq.equal(x.Type, y.Type) { 446 return false 447 } 448 if !reflect.DeepEqual(x.MethodNames, y.MethodNames) { 449 return false 450 } 451 if len(x.Methods) != len(y.Methods) { 452 return false 453 } 454 for i := range x.Methods { 455 if !eq.equal(x.Methods[i], y.Methods[i]) { 456 return false 457 } 458 } 459 return true 460 case *Ellipsis: 461 y, ok := y.(*Ellipsis) 462 if !ok { 463 return false 464 } 465 if x == nil || y == nil { 466 return false 467 } 468 return eq.equal(x.Elem, y.Elem) 469 case *Array: 470 y, ok := y.(*Array) 471 if !ok { 472 return false 473 } 474 if x == nil || y == nil { 475 return false 476 } 477 if x.Len != y.Len { 478 return false 479 } 480 return eq.equal(x.Elem, y.Elem) 481 case *Slice: 482 y, ok := y.(*Slice) 483 if !ok { 484 return false 485 } 486 if x == nil || y == nil { 487 return false 488 } 489 return eq.equal(x.Elem, y.Elem) 490 case *Table: 491 y, ok := y.(*Table) 492 if !ok { 493 return false 494 } 495 if x == nil || y == nil { 496 return false 497 } 498 return eq.equal(x.Type, y.Type) 499 case *Tuple: 500 y, ok := y.(*Tuple) 501 if !ok { 502 return false 503 } 504 if x == nil && y == nil { 505 return true 506 } 507 if x == nil || y == nil { 508 return false 509 } 510 if len(x.Elems) != len(y.Elems) { 511 return false 512 } 513 for i := range x.Elems { 514 if !eq.equal(x.Elems[i], y.Elems[i]) { 515 return false 516 } 517 } 518 return true 519 case *Package: 520 y, ok := y.(*Package) 521 if !ok { 522 return false 523 } 524 if x == nil && y == nil { 525 return true 526 } 527 if x == nil || y == nil { 528 return false 529 } 530 if len(x.Exports) != len(y.Exports) { 531 return false 532 } 533 for xn, xt := range x.Exports { 534 yt, ok := y.Exports[xn] 535 if !ok { 536 return false 537 } 538 if !eq.equal(xt, yt) { 539 return false 540 } 541 } 542 return true 543 case *Interface: 544 y, ok := y.(*Interface) 545 if !ok { 546 return false 547 } 548 if x == nil && y == nil { 549 return true 550 } 551 if x == nil || y == nil { 552 return false 553 } 554 if len(x.Methods) != len(y.Methods) { 555 return false 556 } 557 for xn, xt := range x.Methods { 558 yt, ok := y.Methods[xn] 559 if !ok { 560 return false 561 } 562 if !eq.equal(xt, yt) { 563 return false 564 } 565 } 566 return true 567 case *Pointer: 568 y, ok := y.(*Pointer) 569 if !ok { 570 return false 571 } 572 if x == nil || y == nil { 573 return false 574 } 575 return eq.equal(x.Elem, y.Elem) 576 case *Chan: 577 y, ok := y.(*Chan) 578 if !ok { 579 return false 580 } 581 if x == nil || y == nil { 582 return false 583 } 584 if x.Direction != y.Direction { 585 return false 586 } 587 return eq.equal(x.Elem, y.Elem) 588 case *Map: 589 y, ok := y.(*Map) 590 if !ok { 591 return false 592 } 593 if x == nil || y == nil { 594 return false 595 } 596 if !eq.equal(x.Key, y.Key) { 597 return false 598 } 599 return eq.equal(x.Value, y.Value) 600 case *Unresolved: 601 if !eq.matchUnresolved { 602 return false 603 } 604 y, ok := y.(*Unresolved) 605 if !ok { 606 return false 607 } 608 if x == nil || y == nil { 609 return false 610 } 611 if x.Name != y.Name { 612 return false 613 } 614 return true 615 } 616 panic(fmt.Sprintf("tipe.Equal TODO %T\n", x)) 617 } 618 619 func (t Interface) String() string { 620 if len(t.Methods) == 0 { 621 return "interface{}" 622 } 623 s := "interface{" 624 for name := range t.Methods { 625 s += "\t" + name + "(TODO)" 626 } 627 s += "\n}" 628 return s 629 } 630 631 func Underlying(t Type) Type { 632 if t == nil { 633 return nil 634 } 635 switch t := t.(type) { 636 case *Alias: 637 return Underlying(t.Type) 638 case *Named: 639 return Underlying(t.Type) 640 default: 641 return t 642 } 643 } 644 645 type Memory struct { 646 methodNames map[Type][]string 647 methods map[Type][]Type 648 } 649 650 func NewMemory() *Memory { 651 return &Memory{ 652 methodNames: make(map[Type][]string), 653 methods: make(map[Type][]Type), 654 } 655 } 656 657 func (m *Memory) Methods(t Type) ([]string, []Type) { // TODO: ([]string, []*Func) 658 names := m.methodNames[t] 659 if names != nil { 660 return names, m.methods[t] 661 } 662 methodset := make(map[string]Type) 663 methods(t, methodset, 0) 664 665 for name := range methodset { 666 names = append(names, name) 667 } 668 sort.Strings(names) 669 var methods []Type 670 for _, name := range names { 671 methods = append(methods, methodset[name]) 672 } 673 m.methodNames[t] = names 674 m.methods[t] = methods 675 return names, methods 676 } 677 678 func (m *Memory) Method(t Type, name string) *Func { 679 names, types := m.Methods(t) 680 i := sort.Search(len(names), func(i int) bool { return names[i] >= name }) 681 if i == len(names) { 682 return nil 683 } 684 if names[i] == name { 685 return types[i].(*Func) 686 } 687 return nil 688 } 689 690 func methods(t Type, methodset map[string]Type, pointersRemoved int) { 691 t = Unalias(t) 692 switch t := t.(type) { 693 case *Pointer: 694 if pointersRemoved < 1 { 695 methods(t.Elem, methodset, pointersRemoved+1) 696 } 697 case *Interface: 698 for name, typ := range t.Methods { 699 if methodset[name] != nil { 700 continue 701 } 702 methodset[name] = typ 703 } 704 case *Named: 705 for i, name := range t.MethodNames { 706 if methodset[name] != nil { 707 continue 708 } 709 methodset[name] = t.Methods[i] 710 } 711 methods(t.Type, methodset, pointersRemoved) 712 } 713 }