public override string VisitConstantDeclaration(AstConstantDeclaration decl, int data = 0)
        {
            StringBuilder sb = new StringBuilder();

            if (decl.GetFlag(StmtFlags.IsLocal))
            {
                sb.Append("local ");
            }
            sb.Append(decl.Pattern.Accept(this));

            switch (decl.Type)
            {
            case CheezTypeType _:
            case FunctionType _:
            case GenericType _:
                sb.Append($" :");
                break;

            default:
                sb.Append($" : {decl.Type} ");
                break;
            }

            sb.Append(": ");
            sb.Append(decl.Initializer.Accept(this));

            if (decl.Type == CheezType.Type &&
                !(decl.Initializer is AstStructTypeExpr || decl.Initializer is AstEnumTypeExpr || decl.Initializer is AstTraitTypeExpr))
            {
                sb.Append(" = ");
                sb.Append(decl.Initializer.Value);
            }
            return(sb.ToString());
        }
        private AstStatement AnalyseConstantDeclaration(AstConstantDeclaration c)
        {
            if (c.HasDirective("local"))
            {
                c.SetFlag(StmtFlags.IsLocal, true);
            }

            if (c.TypeExpr != null)
            {
                c.TypeExpr.AttachTo(c);
                c.TypeExpr.SetFlag(ExprFlags.ValueRequired, true);
                c.TypeExpr = ResolveTypeNow(c.TypeExpr, out var t);
                c.Type     = t;
            }

            c.Initializer.AttachTo(c);
            c.Initializer.SetFlag(ExprFlags.ValueRequired, true);
            c.Initializer = InferType(c.Initializer, c.Type);

            if (c.Type == null)
            {
                c.Type = c.Initializer.Type;
            }
            else
            {
                c.Initializer = CheckType(c.Initializer, c.Type);
            }

            if (!c.Initializer.IsCompTimeValue)
            {
                ReportError(c.Initializer, $"Value of constant declaration must be constant");
                return(c);
            }
            c.Value = c.Initializer.Value;

            CheckValueRangeForType(c.Type, c.Value, c.Initializer);

            var(ok, other) = c.GetFlag(StmtFlags.IsLocal) ?
                             c.Scope.DefineLocalSymbol(c) :
                             c.Scope.DefineSymbol(c);
            if (!ok)
            {
                ReportError(c, $"A symbol with name '{c.Name.Name}' already exists in this scope", ("Other declaration here:", other));
            }
            return(c);
        }