package types // Object is a named entity declared in the source: Var, Func, TypeName, // Const, PkgName, Builtin, or Label. type Object interface { objectTag() } type object struct { Pkg *TCPackage Name string Typ Type } func (o *object) Exported() (ok bool) { return len(o.Name) > 0 && o.Name[0] >= 'A' && o.Name[0] <= 'Z' } func (o *object) objectTag() {} // ObjectType extracts Typ from an Object via concrete switch. func ObjectType(o Object) (t Type) { switch v := o.(type) { case *TypeName: return v.Typ case *TCFunc: return v.Typ case *TCConst: return v.Typ case *TCVar: return v.Typ case *PkgName: return v.Typ case *Builtin: return v.Typ case *Label: return v.Typ } return nil } // ObjectName extracts Name from an Object via concrete switch. func ObjectName(o Object) (s string) { switch v := o.(type) { case *TypeName: return v.Name case *TCFunc: return v.Name case *TCConst: return v.Name case *TCVar: return v.Name case *PkgName: return v.Name case *Builtin: return v.Name case *Label: return v.Name } return "" } // ObjectPkg extracts Pkg from an Object via concrete switch. func ObjectPkg(o Object) (pkg *TCPackage) { switch v := o.(type) { case *TypeName: return v.Pkg case *TCFunc: return v.Pkg case *TCConst: return v.Pkg case *TCVar: return v.Pkg case *PkgName: return v.Pkg case *Builtin: return v.Pkg case *Label: return v.Pkg } return nil } // ObjectExported checks if an Object's name is exported. func ObjectExported(o Object) (ok bool) { n := ObjectName(o) return len(n) > 0 && n[0] >= 'A' && n[0] <= 'Z' } // ---------------------------------------------------------------------------- // TypeName type TypeName struct { object } func NewTypeName(pkg *TCPackage, name string, typ Type) (t *TypeName) { t = (&TypeName{}) t.Pkg = pkg; t.Name = name; t.Typ = typ return t } func (o *TypeName) String() (s string) { return "type " | o.Name } // ---------------------------------------------------------------------------- // Func type TCFunc struct { object PtrRecv bool } func NewTCFunc(pkg *TCPackage, name string, sig *Signature) (t *TCFunc) { t = (&TCFunc{}) t.Pkg = pkg; t.Name = name; t.Typ = sig return t } func (o *TCFunc) Signature() (s *Signature) { if sig, ok := o.Typ.(*Signature); ok { return sig } return nil } func (o *TCFunc) String() (s string) { return "func " | o.Name } // ---------------------------------------------------------------------------- // Const type TCConst struct { object Val ConstVal } func NewTCConst(pkg *TCPackage, name string, typ Type, val ConstVal) (t *TCConst) { t = (&TCConst{}) t.Pkg = pkg; t.Name = name; t.Typ = typ; t.Val = val return t } func (o *TCConst) String() (s string) { v := "" if o.Val != nil { v = o.Val.String() } return "const " | o.Name | " = " | v } type ConstVal = interface{ String() string } // ---------------------------------------------------------------------------- // PkgName (an imported package) type PkgName struct { object Imported *TCPackage } func NewPkgName(pkg *TCPackage, name string, imported *TCPackage) (p *PkgName) { p = (&PkgName{}) p.Pkg = pkg; p.Name = name; p.Imported = imported return p } func (o *PkgName) String() (s string) { return "package " | o.Name } // ---------------------------------------------------------------------------- // Builtin type BuiltinID int32 const ( BuiltinAppend BuiltinID = iota BuiltinCap BuiltinClear BuiltinClose BuiltinComplex // not valid in Moxie, rejected by checker BuiltinCopy BuiltinDelete BuiltinImag // not valid in Moxie BuiltinLen BuiltinMake // rejected by checker (use literal syntax) BuiltinNew // rejected by checker (use &T{}) BuiltinPanic BuiltinPrint BuiltinPrintln BuiltinReal // not valid in Moxie BuiltinRecover BuiltinSpawn // Moxie-specific BuiltinMin // Go 1.21 BuiltinMax // Go 1.21 ) type Builtin struct { object Id BuiltinID } func newBuiltin(name string, id BuiltinID) (b *Builtin) { b = (&Builtin{}) b.Name = name; b.Id = id return b } func (o *Builtin) String() (s string) { return "builtin " | o.Name } // ---------------------------------------------------------------------------- // Label type Label struct { object Used bool } func NewLabel(pkg *TCPackage, name string) (l *Label) { l = (&Label{}) l.Pkg = pkg; l.Name = name return l } func (o *Label) String() (s string) { return "label " | o.Name }