fspl/entity/type.go

133 lines
3.5 KiB
Go

package entity
import "fmt"
import "github.com/alecthomas/participle/v2/lexer"
// Type is any type notation.
type Type interface {
ty ()
}
type void struct { }
func (void) ty(){}
// Void returns the absence of a type. It can be compared to a Type to find out
// if it is filled in, but has no type.
func Void () Type {
return void { }
}
// TypeNamed refers to a user-defined or built in named type.
type TypeNamed struct {
Pos lexer.Position
Name string `parser:" @Ident "`
Type Type
}
func (*TypeNamed) ty(){}
func (this *TypeNamed) String () string { return this.Name }
// TypePointer is a pointer to another type.
type TypePointer struct {
Pos lexer.Position
Referenced Type `parser:" '*' @@ "`
}
func (*TypePointer) ty(){}
func (this *TypePointer) String () string {
return fmt.Sprint("*", this.Referenced)
}
// TypeSlice is a pointer to several values of a given type stored next to
// eachother. Its length is not built into its type and can be changed at
// runtime.
type TypeSlice struct {
Pos lexer.Position
Element Type `parser:" '*' ':' @@ "`
}
func (*TypeSlice) ty(){}
func (this *TypeSlice) String () string {
return fmt.Sprint("*:", this.Element)
}
// TypeArray is a group of values of a given type stored next to eachother. The
// length of an array is fixed and is part of its type. Arrays are passed by
// value unless a pointer is used.
type TypeArray struct {
Pos lexer.Position
Length int `parser:" @Int "`
Element Type `parser:" ':' @@ "`
}
func (*TypeArray) ty(){}
func (this *TypeArray) String () string {
return fmt.Sprint(this.Length, ":", this.Element)
}
// TypeStruct is a composite type that stores keyed values. The positions of the
// values within the struct are decided at compile time, based on the order they
// are specified in. Structs are passed by value unless a pointer is used.
type TypeStruct struct {
// Syntax
Pos lexer.Position
Members []*Declaration `parser:" '(' @@+ ')' "`
// Semantics
MemberOrder []string
MemberMap map[string] *Declaration
}
func (*TypeStruct) ty(){}
func (this *TypeStruct) String () string {
out := "("
for index, member := range this.Members {
if index > 0 { out += " " }
out += fmt.Sprint(member)
}
return out + ")"
}
// TypeInterface is a polymorphic pointer that allows any value of any type
// through, except it must have at least the methods defined within the
// interface. Interfaces are always passed by reference. When assigning a value
// to an interface, it will be referenced automatically. When assigning a
// pointer to an interface, the pointer's reference will be used instead.
type TypeInterface struct {
// Syntax
Pos lexer.Position
Behaviors []*Signature `parser:" '(' @@+ ')' "`
// Semantics
BehaviorOrder []string
BehaviorMap map[string] *Signature
}
func (*TypeInterface) ty(){}
func (this *TypeInterface) String () string {
out := "("
for index, behavior := range this.Behaviors {
if index > 0 { out += " " }
out += fmt.Sprint(behavior)
}
return out + ")"
}
// TypeInt represents any signed or unsigned integer type.
type TypeInt struct {
Pos lexer.Position
Width int
Signed bool
}
func (*TypeInt) ty(){}
// TypeFloat represents any floating point type.
type TypeFloat struct {
Pos lexer.Position
Width int
}
func (*TypeFloat) ty(){}
// TypeWord represents an integer type of unspecified width. The optimal width
// is chosen based on the machine word size (32 on 32 bit systems, 64 on 64 bit
// systems, etc)
type TypeWord struct {
Pos lexer.Position
Signed bool
}
func (*TypeWord) ty(){}