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  }