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());
        }
Beispiel #2
0
        public override NodeFinderResult VisitVariableDecl(AstVariableDecl variable, int index = 0)
        {
            if (GetRelativeLocation(variable.Initializer?.Location, index) == RelativeLocation.Same)
            {
                return(variable.Initializer.Accept(this, index));
            }

            if (GetRelativeLocation(variable.TypeExpr.Location, index) == RelativeLocation.Same)
            {
                return(new NodeFinderResult(variable.Scope, type: variable.Type));
            }

            return(new NodeFinderResult(variable.Scope, stmt: variable));
        }
        private void GenerateVariableDecl(AstVariableDecl decl)
        {
            if (decl.Type.IsComptimeOnly)
            {
                return;
            }

            var varPtr = CreateLocalVariable(decl.Type, decl.Name.Name);

            valueMap[decl] = varPtr;

            if (decl.Initializer != null)
            {
                var x = GenerateExpression(decl.Initializer, true);
                builder.CreateStore(x, varPtr);
            }
        }
        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 #5
0
        public override string VisitVariableDecl(AstVariableDecl variable, int indentLevel = 0)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(variable.Pattern.Accept(this));

            if (variable.TypeExpr != null)
            {
                sb.Append($" : {variable.TypeExpr.Accept(this)} ");
            }
            else
            {
                sb.Append(" :");
            }

            if (variable.Initializer != null)
            {
                sb.Append("= ");
                sb.Append(variable.Initializer.Accept(this));
            }
            return(sb.ToString());
        }
Beispiel #6
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}");
            //}
        }
Beispiel #7
0
        private IEnumerable <AstVariableDecl> SplitVariableDeclaration(AstVariableDecl v)
        {
            v.Pattern.SetFlag(ExprFlags.IsDeclarationPattern, true);
            switch (v.Pattern)
            {
            case AstCompCallExpr cc when cc.Name.Name == "id":
                cc.AttachTo(v);
                v.Name = InferType(cc, null) as AstIdExpr;
                break;

            case AstIdExpr name:
                // ok, do nothing
                v.Name = name;
                break;

            case AstTupleExpr t:
            {
                v.Name    = new AstIdExpr(GetUniqueName(t.ToString()), false, t);
                v.Pattern = v.Name;

                //var initClone = v.Initializer.Clone();
                //initClone.AttachTo(v);
                //initClone.SetFlag(ExprFlags.ValueRequired, true);
                //initClone = InferType(initClone, null);

                //AstVariableDecl CreateSub(int index, string name)
                //{
                //    var init = mCompiler.ParseExpression(
                //        $"@{name}(§init)",
                //        new Dictionary<string, AstExpression>
                //        {
                //                { "init", new AstVariableRef(v, v.Initializer) }
                //        });
                //    var sub = new AstVariableDecl(t.Values[index], null, init, Location: v);
                //    sub.Scope = v.Scope;
                //    sub.SetFlags(v.GetFlags());
                //    return sub;
                //}
                //if (initClone.Type is PointerType pt1 && pt1.TargetType is AnyType)
                //{
                //    // create new declarations for sub patterns
                //    yield return CreateSub(0, "ptr_of_any");
                //    yield return CreateSub(1, "type_info_of_any");
                //    break;
                //}
                //else if (initClone.Type is PointerType pt2 && pt2.TargetType is TraitType)
                //{
                //    // create new declarations for sub patterns
                //    yield return CreateSub(0, "ptr_of_trait");
                //    yield return CreateSub(1, "vtable_of_trait");
                //    break;
                //}
                //else
                //{
                // create new declarations for sub patterns
                var index = 0;
                foreach (var subPattern in t.Values)
                {
                    var init = new AstArrayAccessExpr(
                        new AstVariableRef(v, v.Initializer),
                        new AstNumberExpr(NumberData.FromBigInt(index), Location: v.Initializer));
                    var sub = new AstVariableDecl(subPattern, null, init, v.Mutable, v.Documentation, Location: v);
                    sub.Scope = v.Scope;
                    sub.SetFlags(v.GetFlags());

                    yield return(sub);

                    index += 1;
                }
                break;
                //}
            }

            default:
                ReportError(v.Pattern, $"Invalid pattern in variable declaration");
                break;
            }
        }
Beispiel #8
0
 public virtual ReturnType VisitVariableDecl(AstVariableDecl decl, DataType data = default) => default;
 public AstVariableRef(AstVariableDecl let, ILocation Location = null)
     : base(Location)
 {
     Declaration = let;
     Type        = let.Type;
 }
Beispiel #10
0
 public VarDeclType(AstVariableDecl decl)
 {
     Declaration = decl;
 }
        private void InitGlobalVariable(AstVariableDecl decl, HashSet <AstVariableDecl> visited)
        {
            if (visited.Contains(decl))
            {
                return;
            }

            if (decl.Dependencies != null)
            {
                foreach (var dep in decl.Dependencies)
                {
                    if (dep is AstVariableDecl v)
                    {
                        InitGlobalVariable(v, visited);
                    }
                }
            }
            visited.Add(decl);

            // Don't emit global variables that aren't even used
            if (dontEmitUnusedDeclarations && !decl.IsUsed)
            {
                return;
            }

            // create vars
            var type = CheezTypeToLLVMType(decl.Type);

            var name = decl.Name.Name;

            if (decl.TryGetDirective("linkname", out var linkname))
            {
                name = linkname.Arguments[0].Value as string;
            }


            var varPtr = module.AddGlobal(type, name);

            varPtr.SetLinkage(LLVMLinkage.LLVMInternalLinkage);
            if (decl.HasDirective("thread_local"))
            {
                varPtr.SetThreadLocal(true);
            }
            //varPtr.SetLinkage(LLVMLinkage.LLVMExternalLinkage);// TODO?

            if (decl.HasDirective("extern"))
            {
                varPtr.SetLinkage(LLVMLinkage.LLVMExternalLinkage);
            }
            else
            {
                LLVMValueRef initializer = LLVM.ConstNull(CheezTypeToLLVMType(decl.Type));
                varPtr.SetInitializer(initializer);
            }

            valueMap[decl] = varPtr;

            // do initialization TODO: other patterns
            if (decl.Initializer != null)
            {
                var x = GenerateExpression(decl.Initializer, true);
                builder.CreateStore(x, varPtr);
            }
        }
Beispiel #12
0
        private AstStatement AnalyseForStatement(AstForStmt fo)
        {
            fo.SubScope = new Scope("for", fo.Scope);

            fo.Collection.SetFlag(ExprFlags.ValueRequired, true);
            fo.Collection.AttachTo(fo);
            fo.Collection = InferType(fo.Collection, null);
            ConvertLiteralTypeToDefaultType(fo.Collection, null);

            if (fo.Collection.Type.IsErrorType)
            {
                return(fo);
            }

            fo.Body.AttachTo(fo);
            fo.Body.Scope = fo.SubScope;
            fo.Body       = InferType(fo.Body, CheezType.Code);

            var fors = fo.Scope.GetForExtensions(fo.Collection.Type);


            var matches = fors.Select(func =>
            {
                var args = new List <AstArgument>
                {
                    new AstArgument(fo.Collection, Location: fo.Collection),
                    new AstArgument(fo.Body, Location: fo.Body)
                };
                if (fo.Arguments != null)
                {
                    args.AddRange(fo.Arguments);
                }

                var par = func.Parameters.Select(p => (p.Name?.Name, p.Type, p.DefaultValue)).ToArray();
                if (CheckAndMatchArgsToParams(args, par, false))
                {
                    return(func, args);
                }
                return(null, null);
            }).Where(a => a.func != null).ToList();

            if (matches.Count == 0)
            {
                var candidates = fors.Select(f => ("Tried this candidate:", f.ParameterLocation));
                ReportError(fo.Collection, $"No for extension matches type '{fo.Collection.Type}'", candidates);
                return(fo);
            }
            else if (matches.Count > 1)
            {
                var candidates = matches.Select(f => ("This matches:", f.func.ParameterLocation));
                ReportError(fo.Collection, $"Multiple for extensions match type '{fo.Collection.Type}'", candidates);
                return(fo);
            }
            else
            {
                AstVariableDecl CreateLink(AstIdExpr name, AstExpression expr, ILocation location)
                {
                    var link = new AstCompCallExpr(
                        new AstIdExpr("link", false, location),
                        new List <AstArgument> {
                        new AstArgument(expr, Location: expr.Location)
                    },
                        location);

                    var type = mCompiler.ParseExpression($"@typeof(@link({expr}))", new Dictionary <string, AstExpression>
                    {
                        { "it", name }
                    });

                    var varDecl = new AstVariableDecl(name, type, link, true, Location: location);

                    return(varDecl);
                }

                var(func, args) = matches[0];
                var code  = args[1].Expr;
                var links = new List <AstStatement>();

                var it       = new AstIdExpr("it", false, fo.Location);
                var it_index = new AstIdExpr("it_index", false, fo.Location);

                // create links for it and it_index
                if (fo.VarName != null)
                {
                    links.Add(CreateLink(fo.VarName, it, fo.VarName.Location));
                }
                else
                {
                    links.Add(CreateLink(it, it.Clone(), it.Location));
                }

                if (fo.IndexName != null)
                {
                    links.Add(CreateLink(fo.IndexName, it_index, fo.IndexName.Location));
                }
                else
                {
                    links.Add(CreateLink(it_index, it_index.Clone(), it_index.Location));
                }

                // set break and continue
                if (fo.Label != null)
                {
                    var setBreakAndContinue = mCompiler.ParseStatement($"@set_break_and_continue({fo.Label.Name})");
                    links.Add(setBreakAndContinue);
                }

                // set value to null because it is not a code anymore
                code.TypeInferred = false;
                code.Value        = null;
                links.Add(new AstExprStmt(code, code.Location));
                args[1].Expr = new AstBlockExpr(links, Location: fo.Body.Location);

                var call     = new AstCallExpr(new AstFunctionRef(func, null, fo.Location), args, fo.Location);
                var exprStmt = new AstExprStmt(call, fo.Body.Location);
                exprStmt.Parent = fo.Parent;
                exprStmt.Scope  = fo.SubScope;
                var result = AnalyseStatement(exprStmt, out var ns);
                Debug.Assert(ns == null);
                return(result);
            }
        }