public override string VisitVariableDecl(AstVariableDecl variable, int indentLevel = 0)
        {
            StringBuilder sb = new StringBuilder();

            if (variable.Directives != null)
            {
                var dirs = "";
                foreach (var d in variable.Directives)
                {
                    dirs += "#" + d.Name.Name;
                    foreach (var arg in d.Arguments)
                    {
                        dirs += " " + arg.Accept(this);
                    }
                    dirs += "\n";
                }
                sb.Append(dirs);
            }

            if (variable.GetFlag(StmtFlags.IsLocal))
            {
                sb.Append("local ");
            }
            sb.Append(variable.Name.Accept(this));
            sb.Append($" : {variable.Type}");

            if (variable.Initializer != null)
            {
                sb.Append(" = ");
                sb.Append(variable.Initializer.Accept(this));
            }
            return(sb.ToString());
        }
        private IEnumerable <AstVariableDecl> AnalyseVariableDecl(AstVariableDecl decl)
        {
            foreach (var sub in SplitVariableDeclaration(decl))
            {
                yield return(sub);
            }

            decl.ContainingFunction = currentFunction;
            ResolveVariableDecl(decl);

            var(ok, other) = decl.GetFlag(StmtFlags.IsLocal) ?
                             decl.Scope.DefineLocalSymbol(decl) :
                             decl.Scope.DefineSymbol(decl);
            if (!ok)
            {
                ReportError(decl, $"A symbol with name '{decl.Name.Name}' already exists in this scope", ("Other declaration here:", other));
            }
        }
Beispiel #3
0
        private void ResolveVariableDecl(AstVariableDecl v)
        {
            Debug.Assert(v.Name != null);

            if (v.Directives != null)
            {
                foreach (var d in v.Directives)
                {
                    foreach (var arg in d.Arguments)
                    {
                        arg.Scope = v.Scope;
                        InferType(arg, null);
                    }
                }
            }

            if (v.HasDirective("local"))
            {
                v.SetFlag(StmtFlags.IsLocal, true);
            }

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

            // initializer stuff
            if (v.Initializer == null)
            {
                if (v.GetFlag(StmtFlags.GlobalScope) && !v.HasDirective("extern"))
                {
                    ReportError(v, $"Global variables must have an initializer");
                }
            }
            else
            {
                v.Initializer.AttachTo(v);
                v.Initializer.SetFlag(ExprFlags.ValueRequired, true);
                v.Initializer = InferType(v.Initializer, v.Type);
                ConvertLiteralTypeToDefaultType(v.Initializer, v.Type);

                if (v.TypeExpr != null)
                {
                    //v.Initializer = HandleReference(v.Initializer, v.Type, null);
                    v.Initializer = CheckType(v.Initializer, v.Type);
                }
            }

            if (v.TypeExpr == null)
            {
                v.Type = v.Initializer.Type;
            }

            switch (v.Type)
            {
            case IntType _:
            case FloatType _:
            case BoolType _:
            case CharType _:
            case SliceType _:
            case StringType _:
            case ArrayType _:
            case StructType _:
            case EnumType _:
            case PointerType _:
            case ReferenceType _:
            case FunctionType _:
            case TupleType _:
            case RangeType _:
                break;

            case CheezType t when t.IsErrorType:
                break;

            default:
                ReportError(v, $"Variable can't have type {v.Type}");
                break;
            }

            //if (vardecl.Type is SumType)
            //{
            //    ReportError(vardecl.Pattern, $"Invalid type for variable declaration: {vardecl.Type}");
            //}
        }