Add untested constant access analysis

This commit is contained in:
Sasha Koshka 2024-04-11 22:30:31 -04:00
parent 0fd35343c1
commit 6ba8b5465b
4 changed files with 49 additions and 4 deletions

View File

@ -14,6 +14,8 @@ func (this *Tree) analyzeExpression (
switch expression := expression.(type) {
case *entity.Assignment:
return this.analyzeAssignment(expression)
case *entity.Constant:
return this.analyzeConstant(into, mode, expression)
case *entity.Variable:
return this.analyzeVariable(into, mode, expression)
case *entity.Declaration:

View File

@ -33,6 +33,47 @@ func (this *Tree) analyzeAssignment (
return assignment, nil
}
func (this *Tree) analyzeConstant (
into entity.Type,
mode strictness,
constant *entity.Constant,
) (
entity.Expression,
error,
) {
// get typedef
unit, err := this.resolveNickname(constant.Position(), constant.UnitNickname)
if err != nil { return nil, err }
typedef, err := this.analyzeTypedef(constant.Position(), entity.Key {
Unit: unit,
Name: constant.TypeName,
}, false) // TODO perhaps we should accept incomplete ones?
if err != nil { return nil, err }
constant.Unit = typedef.Unit()
constant.Ty = into
// check access permissions
if typedef.Acc == entity.AccessPrivate && typedef.Unit() != this.unit {
return nil, errors.Errorf (
constant.Position(), "type %v::%v is private",
constant.UnitNickname, constant.TypeName)
}
// get declaration
declaration, ok := typedef.ConstantMap[constant.Name]
if !ok {
return nil, errors.Errorf (
constant.Position(), "no constant %v",
constant)
}
constant.Declaration = declaration
err = this.canAssign(constant.Position(), into, mode, declaration.Type())
if err != nil { return nil, err }
return constant, nil
}
func (this *Tree) analyzeVariable (
into entity.Type,
mode strictness,

View File

@ -59,8 +59,9 @@ func (this *Tree) analyzeTypedef (
if constant.Value == nil {
if !isNumeric(definition.Type) {
return nil, errors.Errorf (
pos, "cannot fill in constant values for non-numeric type %v",
definition.Type)
constant.Position(),
"cannot fill in constant value for non-numeric type %v",
definition.Name)
}
constant.Value = &entity.LiteralInt {
Pos: pos,

View File

@ -719,8 +719,9 @@ type Constant struct {
Name string
// Semantics
Ty Type
Unit uuid.UUID
Ty Type
Unit uuid.UUID
Declaration *ConstantDeclaration
}
func (*Constant) expression(){}
func (this *Constant) Position () errors.Position { return this.Pos }