tc_object.mx raw

   1  package types
   2  
   3  
   4  // Object is a named entity declared in the source: Var, Func, TypeName,
   5  // Const, PkgName, Builtin, or Label.
   6  type Object interface {
   7  	objectTag()
   8  }
   9  
  10  type object struct {
  11  	Pkg  *TCPackage
  12  	Name string
  13  	Typ  Type
  14  }
  15  
  16  func (o *object) Exported() (ok bool) { return len(o.Name) > 0 && o.Name[0] >= 'A' && o.Name[0] <= 'Z' }
  17  func (o *object) objectTag()      {}
  18  
  19  // ObjectType extracts Typ from an Object via concrete switch.
  20  func ObjectType(o Object) (t Type) {
  21  	switch v := o.(type) {
  22  	case *TypeName:
  23  		return v.Typ
  24  	case *TCFunc:
  25  		return v.Typ
  26  	case *TCConst:
  27  		return v.Typ
  28  	case *TCVar:
  29  		return v.Typ
  30  	case *PkgName:
  31  		return v.Typ
  32  	case *Builtin:
  33  		return v.Typ
  34  	case *Label:
  35  		return v.Typ
  36  	}
  37  	return nil
  38  }
  39  
  40  // ObjectName extracts Name from an Object via concrete switch.
  41  func ObjectName(o Object) (s string) {
  42  	switch v := o.(type) {
  43  	case *TypeName:
  44  		return v.Name
  45  	case *TCFunc:
  46  		return v.Name
  47  	case *TCConst:
  48  		return v.Name
  49  	case *TCVar:
  50  		return v.Name
  51  	case *PkgName:
  52  		return v.Name
  53  	case *Builtin:
  54  		return v.Name
  55  	case *Label:
  56  		return v.Name
  57  	}
  58  	return ""
  59  }
  60  
  61  // ObjectPkg extracts Pkg from an Object via concrete switch.
  62  func ObjectPkg(o Object) (pkg *TCPackage) {
  63  	switch v := o.(type) {
  64  	case *TypeName:
  65  		return v.Pkg
  66  	case *TCFunc:
  67  		return v.Pkg
  68  	case *TCConst:
  69  		return v.Pkg
  70  	case *TCVar:
  71  		return v.Pkg
  72  	case *PkgName:
  73  		return v.Pkg
  74  	case *Builtin:
  75  		return v.Pkg
  76  	case *Label:
  77  		return v.Pkg
  78  	}
  79  	return nil
  80  }
  81  
  82  // ObjectExported checks if an Object's name is exported.
  83  func ObjectExported(o Object) (ok bool) {
  84  	n := ObjectName(o)
  85  	return len(n) > 0 && n[0] >= 'A' && n[0] <= 'Z'
  86  }
  87  
  88  // ----------------------------------------------------------------------------
  89  // TypeName
  90  
  91  type TypeName struct {
  92  	object
  93  }
  94  
  95  func NewTypeName(pkg *TCPackage, name string, typ Type) (t *TypeName) {
  96  	t = (&TypeName{})
  97  	t.Pkg = pkg; t.Name = name; t.Typ = typ
  98  	return t
  99  }
 100  func (o *TypeName) String() (s string) { return "type " | o.Name }
 101  
 102  // ----------------------------------------------------------------------------
 103  // Func
 104  
 105  type TCFunc struct {
 106  	object
 107  	PtrRecv bool
 108  }
 109  
 110  func NewTCFunc(pkg *TCPackage, name string, sig *Signature) (t *TCFunc) {
 111  	t = (&TCFunc{})
 112  	t.Pkg = pkg; t.Name = name; t.Typ = sig
 113  	return t
 114  }
 115  func (o *TCFunc) Signature() (s *Signature) {
 116  	if sig, ok := o.Typ.(*Signature); ok {
 117  		return sig
 118  	}
 119  	return nil
 120  }
 121  func (o *TCFunc) String() (s string) { return "func " | o.Name }
 122  
 123  // ----------------------------------------------------------------------------
 124  // Const
 125  
 126  type TCConst struct {
 127  	object
 128  	Val ConstVal
 129  }
 130  
 131  func NewTCConst(pkg *TCPackage, name string, typ Type, val ConstVal) (t *TCConst) {
 132  	t = (&TCConst{})
 133  	t.Pkg = pkg; t.Name = name; t.Typ = typ; t.Val = val
 134  	return t
 135  }
 136  func (o *TCConst) String() (s string) {
 137  	v := ""
 138  	if o.Val != nil {
 139  		v = o.Val.String()
 140  	}
 141  	return "const " | o.Name | " = " | v
 142  }
 143  
 144  type ConstVal = interface{ String() string }
 145  
 146  // ----------------------------------------------------------------------------
 147  // PkgName (an imported package)
 148  
 149  type PkgName struct {
 150  	object
 151  	Imported *TCPackage
 152  }
 153  
 154  func NewPkgName(pkg *TCPackage, name string, imported *TCPackage) (p *PkgName) {
 155  	p = (&PkgName{})
 156  	p.Pkg = pkg; p.Name = name; p.Imported = imported
 157  	return p
 158  }
 159  func (o *PkgName) String() (s string) { return "package " | o.Name }
 160  
 161  // ----------------------------------------------------------------------------
 162  // Builtin
 163  
 164  type BuiltinID int32
 165  
 166  const (
 167  	BuiltinAppend BuiltinID = iota
 168  	BuiltinCap
 169  	BuiltinClear
 170  	BuiltinClose
 171  	BuiltinComplex // not valid in Moxie, rejected by checker
 172  	BuiltinCopy
 173  	BuiltinDelete
 174  	BuiltinImag   // not valid in Moxie
 175  	BuiltinLen
 176  	BuiltinMake   // rejected by checker (use literal syntax)
 177  	BuiltinNew    // rejected by checker (use &T{})
 178  	BuiltinPanic
 179  	BuiltinPrint
 180  	BuiltinPrintln
 181  	BuiltinReal   // not valid in Moxie
 182  	BuiltinRecover
 183  	BuiltinSpawn // Moxie-specific
 184  	BuiltinMin   // Go 1.21
 185  	BuiltinMax   // Go 1.21
 186  )
 187  
 188  type Builtin struct {
 189  	object
 190  	Id BuiltinID
 191  }
 192  
 193  func newBuiltin(name string, id BuiltinID) (b *Builtin) {
 194  	b = (&Builtin{})
 195  	b.Name = name; b.Id = id
 196  	return b
 197  }
 198  func (o *Builtin) String() (s string) { return "builtin " | o.Name }
 199  
 200  // ----------------------------------------------------------------------------
 201  // Label
 202  
 203  type Label struct {
 204  	object
 205  	Used bool
 206  }
 207  
 208  func NewLabel(pkg *TCPackage, name string) (l *Label) {
 209  	l = (&Label{})
 210  	l.Pkg = pkg; l.Name = name
 211  	return l
 212  }
 213  func (o *Label) String() (s string) { return "label " | o.Name }
 214