163 lines
4.0 KiB
Go
163 lines
4.0 KiB
Go
package entity
|
|
|
|
import "fmt"
|
|
import "encoding/base64"
|
|
import "github.com/google/uuid"
|
|
import "git.tebibyte.media/fspl/fspl/errors"
|
|
|
|
// Key globally indexes top level entities in contexts where modules matter.
|
|
type Key struct {
|
|
Unit uuid.UUID
|
|
Name string
|
|
Method string
|
|
}
|
|
|
|
func (key Key) String () string {
|
|
out := fmt.Sprintf("%v::%v", key.Unit, key.Name)
|
|
if key.Method != "" {
|
|
out = fmt.Sprintf("%s.%s", out, key.Method)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// LinkName returns the name that the entity it refers to will be given when
|
|
// compiled.
|
|
func (key Key) LinkName () string {
|
|
data := [16]byte(key.Unit)
|
|
out := fmt.Sprintf(
|
|
"%s::%s",
|
|
base64.StdEncoding.EncodeToString(data[:]),
|
|
key.Name)
|
|
if key.Method != "" {
|
|
out = fmt.Sprintf("%s.%s", out, key.Method)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// StripMethod returns a copy of the key that refers to a type instead of a
|
|
// method.
|
|
func (key Key) StripMethod () Key {
|
|
key.Method = ""
|
|
return key
|
|
}
|
|
|
|
// TopLevel is any construct that is placed at the root of a file.
|
|
type TopLevel interface {
|
|
topLevel ()
|
|
}
|
|
|
|
// Access determines the external access control mode for a top-level entity.
|
|
type Access int; const (
|
|
// AccessPublic allows other modules to access an entity normally.
|
|
AccessPublic Access = iota
|
|
|
|
// AccessRestricted causes a top-level entity to appear opaque to other
|
|
// modules. Values of restricted types can be passed around, assigned
|
|
// to eachother, and their methods can be called, but the implementation
|
|
// of the type is entirely hidden. This access mode cannot be applied to
|
|
// functions.
|
|
AccessRestricted
|
|
|
|
// AccessPrivate disallows other modules from accessing a top-level
|
|
// entity.
|
|
AccessPrivate
|
|
)
|
|
|
|
func (this Access) String () string {
|
|
switch this {
|
|
case AccessPrivate: return "-"
|
|
case AccessRestricted: return "~"
|
|
case AccessPublic: return "+"
|
|
default: return fmt.Sprintf("entity.Access(%d)", this)
|
|
}
|
|
}
|
|
|
|
// Typedef binds a type to a global identifier.
|
|
type Typedef struct {
|
|
// Syntax
|
|
Position errors.Position
|
|
Acc Access
|
|
Name string
|
|
Type Type
|
|
|
|
// Semantics
|
|
Unit uuid.UUID
|
|
Methods map[string] *Method
|
|
}
|
|
func (*Typedef) topLevel(){}
|
|
func (this *Typedef) String () string {
|
|
output := ""
|
|
output += fmt.Sprint(this.Acc, " ")
|
|
output += fmt.Sprint(this.Name, ": ", this.Type)
|
|
if this.Methods != nil {
|
|
for _, method := range this.Methods {
|
|
output += fmt.Sprint("\n", method)
|
|
}
|
|
}
|
|
return output
|
|
}
|
|
|
|
// Function binds a global identifier and argument list to an expression which
|
|
// is evaluated each time the function is called. If no expression is specified,
|
|
// the function is marked as external. Functions have an argument list, where
|
|
// each argument is passed as a separate variable. They return one value. All of
|
|
// these are typed.
|
|
type Function struct {
|
|
// Syntax
|
|
Position errors.Position
|
|
Acc Access
|
|
LinkName string
|
|
Signature *Signature
|
|
Body Expression
|
|
|
|
// Semantics
|
|
Unit uuid.UUID
|
|
Scope
|
|
}
|
|
func (*Function) topLevel(){}
|
|
func (this *Function) String () string {
|
|
output := ""
|
|
output += fmt.Sprint(this.Acc, " ")
|
|
output += this.Signature.String()
|
|
if this.LinkName != "" {
|
|
output += fmt.Sprint(" '", this.LinkName, "'")
|
|
}
|
|
if this.Body != nil {
|
|
output += fmt.Sprint(" = ", this.Body)
|
|
}
|
|
return output
|
|
}
|
|
|
|
// Method is like a function, except localized to a defined type. Methods are
|
|
// called on an instance of that type, and receive a pointer to that instance
|
|
// via the "this" variable when they are run. Method names are not globally
|
|
// unique, but are unique within the type they are defined on.
|
|
type Method struct {
|
|
// Syntax
|
|
Position errors.Position
|
|
Acc Access
|
|
TypeName string
|
|
LinkName string
|
|
Signature *Signature
|
|
Body Expression
|
|
|
|
// Semantics
|
|
Unit uuid.UUID
|
|
Type Type
|
|
This *Declaration
|
|
Scope
|
|
}
|
|
func (*Method) topLevel(){}
|
|
func (this *Method) String () string {
|
|
output := ""
|
|
output += fmt.Sprint(this.Acc, " ")
|
|
output += fmt.Sprint(this.TypeName, ".", this.Signature)
|
|
if this.LinkName != "" {
|
|
output += fmt.Sprint(" '", this.LinkName, "'")
|
|
}
|
|
if this.Body != nil {
|
|
output += fmt.Sprint(" = ", this.Body)
|
|
}
|
|
return output
|
|
}
|