diff --git a/analyzer/expression-multiplex.go b/analyzer/expression-multiplex.go index c346f28..249aedd 100644 --- a/analyzer/expression-multiplex.go +++ b/analyzer/expression-multiplex.go @@ -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: diff --git a/analyzer/expression.go b/analyzer/expression.go index 2b4eeaf..f09b052 100644 --- a/analyzer/expression.go +++ b/analyzer/expression.go @@ -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, diff --git a/analyzer/type.go b/analyzer/type.go index 0269983..d873c2a 100644 --- a/analyzer/type.go +++ b/analyzer/type.go @@ -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, diff --git a/entity/expression.go b/entity/expression.go index f4c36a9..51a84df 100644 --- a/entity/expression.go +++ b/entity/expression.go @@ -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 }