Keys now support constants
This commit is contained in:
parent
f4480fe6b1
commit
cc5173dd52
|
@ -47,7 +47,7 @@ func (this *Tree) analyzeConstant (
|
|||
if err != nil { return nil, err }
|
||||
typedef, err := this.analyzeTypedef(constant.Position(), entity.Key {
|
||||
Unit: unit,
|
||||
Name: constant.TypeName,
|
||||
Type: constant.TypeName,
|
||||
}, false) // TODO perhaps we should accept incomplete ones?
|
||||
if err != nil { return nil, err }
|
||||
constant.Unit = typedef.Unit()
|
||||
|
@ -151,8 +151,8 @@ func (this *Tree) analyzeCall (
|
|||
unit, err := this.resolveNickname(call.Position(), call.UnitNickname)
|
||||
if err != nil { return nil, err }
|
||||
function, err := this.analyzeFunction(call.Position(), entity.Key {
|
||||
Unit: unit,
|
||||
Name: call.Name,
|
||||
Unit: unit,
|
||||
Function: call.Name,
|
||||
})
|
||||
if err != nil { return nil, err }
|
||||
call.Function = function
|
||||
|
|
|
@ -20,7 +20,7 @@ func (this *Tree) analyzeFunction (
|
|||
// error if function is missing
|
||||
function, exists := this.rawFunctions[key]
|
||||
if !exists {
|
||||
return nil, errors.Errorf(pos, "no function named %s", key.Name)
|
||||
return nil, errors.Errorf(pos, "no function named %s", key.Function)
|
||||
}
|
||||
|
||||
// set unit
|
||||
|
|
|
@ -14,12 +14,12 @@ func (this *Tree) analyzeMethod (
|
|||
error,
|
||||
) {
|
||||
// get parent typedef
|
||||
typeKey := key.StripMethod()
|
||||
typeKey := key.OnlyType()
|
||||
owner, err := this.analyzeTypedef(pos, typeKey, false)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
// return if exists already
|
||||
if method, exists := owner.Methods[key.Method]; exists {
|
||||
if method, exists := owner.Methods[key.Function]; exists {
|
||||
return method, nil
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ func (this *Tree) analyzeMethod (
|
|||
Referenced: &entity.TypeNamed {
|
||||
Pos: method.Position(),
|
||||
Unt: key.Unit,
|
||||
Name: key.Name,
|
||||
Name: key.Type,
|
||||
Type: owner.Type,
|
||||
},
|
||||
},
|
||||
|
@ -75,7 +75,7 @@ func (this *Tree) analyzeMethod (
|
|||
// add incomplete method to complete methods because there is enough
|
||||
// information for it to be complete from the point of view of other
|
||||
// parts of the code
|
||||
owner.Methods[key.Method] = method
|
||||
owner.Methods[key.Function] = method
|
||||
|
||||
// analyze method body
|
||||
if method.Body != nil {
|
||||
|
@ -93,10 +93,10 @@ func (this *Tree) methodExists (pos errors.Position, key entity.Key) (bool, erro
|
|||
if existsInRaw { return true, nil }
|
||||
|
||||
// check parent typedef
|
||||
typeKey := key.StripMethod()
|
||||
typeKey := key.OnlyType()
|
||||
owner, err := this.analyzeTypedef(pos, typeKey, false)
|
||||
if err != nil { return false, err }
|
||||
_, existsInType := owner.Methods[key.Method]
|
||||
_, existsInType := owner.Methods[key.Function]
|
||||
return existsInType, nil
|
||||
}
|
||||
|
||||
|
@ -126,9 +126,9 @@ func (this *Tree) analyzeMethodOrBehaviorInternal (
|
|||
case *entity.TypeNamed:
|
||||
ty := ty.(*entity.TypeNamed)
|
||||
key := entity.Key {
|
||||
Unit: ty.Type.Unit(),
|
||||
Name: ty.Name,
|
||||
Method: name,
|
||||
Unit: ty.Type.Unit(),
|
||||
Type: ty.Name,
|
||||
Function: name,
|
||||
}
|
||||
exists, err := this.methodExists(pos, key)
|
||||
if err != nil { return nil, err }
|
||||
|
|
|
@ -45,7 +45,7 @@ func (this *Tree) assembleRawMaps () error {
|
|||
case *entity.Typedef:
|
||||
key := entity.Key {
|
||||
Unit: this.unit,
|
||||
Name: declaration.Name,
|
||||
Type: declaration.Name,
|
||||
}
|
||||
err := this.topLevelNameAvailable(declaration.Position(), key)
|
||||
if err != nil { return err }
|
||||
|
@ -54,8 +54,8 @@ func (this *Tree) assembleRawMaps () error {
|
|||
|
||||
case *entity.Function:
|
||||
key := entity.Key {
|
||||
Unit: this.unit,
|
||||
Name: declaration.Signature.Name,
|
||||
Unit: this.unit,
|
||||
Function: declaration.Signature.Name,
|
||||
}
|
||||
err := this.topLevelNameAvailable(declaration.Position(), key)
|
||||
if err != nil { return err }
|
||||
|
@ -63,9 +63,9 @@ func (this *Tree) assembleRawMaps () error {
|
|||
|
||||
case *entity.Method:
|
||||
key := entity.Key {
|
||||
Unit: this.unit,
|
||||
Name: declaration.TypeName,
|
||||
Method: declaration.Signature.Name,
|
||||
Unit: this.unit,
|
||||
Type: declaration.TypeName,
|
||||
Function: declaration.Signature.Name,
|
||||
}
|
||||
err := this.topLevelNameAvailable(declaration.Position(), key)
|
||||
if err != nil { return err }
|
||||
|
@ -76,35 +76,35 @@ func (this *Tree) assembleRawMaps () error {
|
|||
}
|
||||
|
||||
func (this *Tree) topLevelNameAvailable (currentPos errors.Position, key entity.Key) error {
|
||||
if fsplParser.IsReserved(key.Name) {
|
||||
if fsplParser.IsReserved(key.Type) {
|
||||
return errors.Errorf (
|
||||
currentPos, "cannot shadow reserved identifier %s",
|
||||
key.Name)
|
||||
key.Type)
|
||||
}
|
||||
if _, isPrimitive := primitiveTypes[key.Name]; isPrimitive {
|
||||
if _, isPrimitive := primitiveTypes[key.Type]; isPrimitive {
|
||||
return errors.Errorf (
|
||||
currentPos, "cannot shadow primitive %s",
|
||||
key.Name)
|
||||
key.Type)
|
||||
}
|
||||
if _, isBuiltin := builtinTypes[key.Name]; isBuiltin {
|
||||
if _, isBuiltin := builtinTypes[key.Type]; isBuiltin {
|
||||
return errors.Errorf (
|
||||
currentPos, "cannot shadow builtin %s",
|
||||
key.Name)
|
||||
key.Type)
|
||||
}
|
||||
if ty, isType := this.rawTypes[key]; isType {
|
||||
return errors.Errorf (
|
||||
currentPos, "%s already declared at %v",
|
||||
key.Name, ty.Position())
|
||||
key.Type, ty.Position())
|
||||
}
|
||||
if function, isFunction := this.rawFunctions[key]; isFunction {
|
||||
return errors.Errorf (
|
||||
currentPos, "%s already declared at %v",
|
||||
key.Name, function.Position())
|
||||
key.Function, function.Position())
|
||||
}
|
||||
if method, isMethod := this.rawMethods[key]; isMethod {
|
||||
return errors.Errorf (
|
||||
currentPos, "%s.%s already declared at %v",
|
||||
key.Name, key.Method, method.Position())
|
||||
key.Type, key.Function, method.Position())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ func (this *Tree) analyzeDeclarations () error {
|
|||
_, err := this.analyzeMethod (
|
||||
rawMethod.Position(),
|
||||
entity.Key {
|
||||
Unit: this.unit,
|
||||
Name: rawMethod.TypeName,
|
||||
Method: rawMethod.Signature.Name,
|
||||
Unit: this.unit,
|
||||
Type: rawMethod.TypeName,
|
||||
Function: rawMethod.Signature.Name,
|
||||
})
|
||||
if err != nil { return err }
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ func (this *Tree) ensure () {
|
|||
|
||||
for name, ty := range builtinTypes {
|
||||
// builtin types have a zero UUID in their key
|
||||
this.Types[entity.Key { Name: name }] = &entity.Typedef {
|
||||
this.Types[entity.Key { Type: name }] = &entity.Typedef {
|
||||
Acc: entity.AccessPublic,
|
||||
Name: name,
|
||||
Type: ty,
|
||||
|
|
|
@ -14,7 +14,7 @@ func (this *Tree) analyzeTypedef (
|
|||
error,
|
||||
) {
|
||||
// return a builtin if it exists (search types with zero uuid)
|
||||
if definition, exists := this.Types[entity.Key { Name: key.Name }]; exists {
|
||||
if definition, exists := this.Types[entity.Key { Type: key.Type }]; exists {
|
||||
return definition, nil
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,14 @@ func (this *Tree) analyzeTypedef (
|
|||
} else {
|
||||
return nil, errors.Errorf (
|
||||
pos, "type %s cannot be used in this context",
|
||||
key.Name)
|
||||
key.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// check if it is even real
|
||||
definition, exists := this.rawTypes[key]
|
||||
if !exists {
|
||||
return nil, errors.Errorf(pos, "no type named %s", key.Name)
|
||||
return nil, errors.Errorf(pos, "no type named %s", key.Type)
|
||||
}
|
||||
|
||||
// update unit
|
||||
|
@ -148,7 +148,7 @@ func (this *Tree) analyzeTypeInternal (
|
|||
rootKey := func () entity.Key {
|
||||
return entity.Key {
|
||||
Unit: this.unit,
|
||||
Name: root.Name,
|
||||
Type: root.Name,
|
||||
}
|
||||
}
|
||||
updateIncompleteInfo := func () {
|
||||
|
@ -182,7 +182,7 @@ func (this *Tree) analyzeTypeInternal (
|
|||
// analyze the typedef
|
||||
def, err := this.analyzeTypedef(ty.Position(), entity.Key {
|
||||
Unit: unit,
|
||||
Name: ty.Name,
|
||||
Type: ty.Name,
|
||||
}, acceptIncomplete)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
|
|
|
@ -28,16 +28,45 @@ func (hash Hash) Number () uint64 {
|
|||
|
||||
// Key globally indexes top level entities in contexts where modules matter.
|
||||
type Key struct {
|
||||
Unit uuid.UUID
|
||||
Name string
|
||||
Method string
|
||||
Unit uuid.UUID
|
||||
|
||||
// TypeName is the name of the type
|
||||
Type string
|
||||
|
||||
// Constant is the name of the constant
|
||||
Constant string
|
||||
|
||||
// Function is the name of the method or function
|
||||
Function 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 fmt.Sprintf("%v::%s", key.Unit, key.name())
|
||||
}
|
||||
|
||||
// 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)
|
||||
unit := base64.StdEncoding.EncodeToString(data[:])
|
||||
return fmt.Sprintf("%v::%s", unit, key.name())
|
||||
}
|
||||
|
||||
func (key Key) name () string {
|
||||
out := ""
|
||||
switch {
|
||||
case key.Constant != "": out = key.Constant
|
||||
case key.Function != "": out = fmt.Sprintf("[%s]", key.Function)
|
||||
}
|
||||
|
||||
if key.Type != "" {
|
||||
if out == "" {
|
||||
out = key.Type
|
||||
} else {
|
||||
out = fmt.Sprintf("%s.%s", key.Type, out)
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
|
@ -47,24 +76,10 @@ func (key Key) Hash () Hash {
|
|||
return NewHash([]byte("Key:" + key.String()))
|
||||
}
|
||||
|
||||
// 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 = ""
|
||||
// OnlyType returns a copy of the key that refers to a type instead of a method
|
||||
// or constant.
|
||||
func (key Key) OnlyType () Key {
|
||||
key.Constant = ""
|
||||
key.Function = ""
|
||||
return key
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ func (this *TypeNamed) String () string {
|
|||
func (this *TypeNamed) Hash () Hash {
|
||||
return Key {
|
||||
Unit: this.Type.Unit(),
|
||||
Name: this.Name,
|
||||
Type: this.Name,
|
||||
}.Hash()
|
||||
}
|
||||
func (this *TypeNamed) Equals (ty Type) bool {
|
||||
|
|
Loading…
Reference in New Issue