Ejemplo n.º 1
0
        public override NodeFinderResult VisitDotExpr(AstDotExpr dot, int i = 0)
        {
            if (GetRelativeLocation(dot.Left.Location, i) == RelativeLocation.Same)
            {
                return(dot.Left.Accept(this, i));
            }

            return(new NodeFinderResult(dot.Scope, expr: dot));
        }
Ejemplo n.º 2
0
        private AstUsingStmt AnalyseUseStatement(AstUsingStmt use)
        {
            use.Value.SetFlag(ExprFlags.ValueRequired, true);
            use.Value.AttachTo(use);
            use.Value = InferType(use.Value, null);

            if (use.Value.Type.IsErrorType)
            {
                return(use);
            }

            switch (use.Value.Type)
            {
            case CheezTypeType type:
                HandleUseType(use);
                break;

            case StructType str:
            {
                var tempVar = use.Value;
                //if (!tempVar.GetFlag(ExprFlags.IsLValue))
                {
                    tempVar = new AstTempVarExpr(use.Value, use.Value.GetFlag(ExprFlags.IsLValue));
                    tempVar.Replace(use.Value);
                    tempVar.SetFlag(ExprFlags.IsLValue, true);
                    tempVar   = InferType(tempVar, use.Value.Type);
                    use.Value = tempVar;
                }
                ComputeStructMembers(str.Declaration);
                foreach (var mem in str.Declaration.Members)
                {
                    AstExpression expr = new AstDotExpr(tempVar, new AstIdExpr(mem.Name, false, use.Location), use.Location);
                    //expr = InferType(expr, null);
                    use.Scope.DefineUse(mem.Name, expr, true, out var u);
                }
            }
            break;

            default:
                ReportError(use, $"Can't use value of type '{use.Value.Type}'");
                break;
            }

            return(use);
        }
Ejemplo n.º 3
0
 public virtual ReturnType VisitDotExpr(AstDotExpr expr, DataType data                 = default) => default;
Ejemplo n.º 4
0
        private void AnalyseFunction(AstFuncExpr func)
        {
            if (func.IsAnalysed)
            {
                return;
            }
            func.IsAnalysed = true;

            Log($"Analysing function {func.Name}", $"impl = {func.ImplBlock?.Accept(new SignatureAstPrinter())}", $"poly = {func.IsGeneric}");
            PushLogScope();

            var prevCurrentFunction = currentFunction;

            currentFunction = func;
            try
            {
                if (func.SelfType != SelfParamType.None)
                {
                    var p = func.Parameters[0];
                    if (p.Name == null)
                    {
                        p.Name = new AstIdExpr("self", false, p.Location);
                    }

                    if (func.ImplBlock.TargetType is StructType @struct)
                    {
                        ComputeStructMembers(@struct.Declaration);
                        foreach (var m in @struct.Declaration.Members)
                        {
                            AstExpression expr = new AstDotExpr(new AstSymbolExpr(p), new AstIdExpr(m.Name, false, p.Location), p.Location);
                            expr.AttachTo(func, func.SubScope);
                            expr = InferType(expr, m.Type);

                            // define use if no parameter has the same name
                            if (!func.Parameters.Any(pa => pa.Name?.Name == m.Name))
                            {
                                var(ok, other) = func.SubScope.DefineUse(m.Name, expr, false, out var use);

                                if (!ok)
                                {
                                    ReportError(p, $"A symbol with name '{m.Name}' already exists", ("Other here:", other));
                                }
                            }
                        }
                    }
                }

                if (func.IsGeneric)
                {
                    return;
                }

                if (func.TryGetDirective("linkname", out var ln))
                {
                    if (ln.Arguments.Count != 1)
                    {
                        ReportError(ln, $"#linkname requires exactly one argument!");
                    }
                    else
                    {
                        var arg = ln.Arguments[0];
                        arg.SetFlag(ExprFlags.ValueRequired, true);
                        arg = ln.Arguments[0] = InferType(arg, null);
                        if (!(arg.Value is string))
                        {
                            ReportError(arg, $"Argument to #linkname must be a constant string!");
                        }
                    }
                }

                // define parameters
                foreach (var p in func.Parameters)
                {
                    p.ContainingFunction = func;
                    if (p.Name != null)
                    {
                        var(ok, other) = func.SubScope.DefineSymbol(p);
                        if (!ok)
                        {
                            ReportError(p, $"Duplicate parameter '{p.Name}'", ("Other parameter here:", other));
                        }
                    }

                    if (p.DefaultValue != null)
                    {
                        p.DefaultValue.Scope = func.Scope;
                        p.DefaultValue       = InferTypeHelper(p.DefaultValue, p.Type, new TypeInferenceContext {
                            TypeOfExprContext = p.Type
                        });
                        ConvertLiteralTypeToDefaultType(p.DefaultValue, p.Type);
                        p.DefaultValue = CheckType(p.DefaultValue, p.Type);
                        if (p.DefaultValue.Type != p.Type && !p.DefaultValue.Type.IsErrorType)
                        {
                            ReportError(p.DefaultValue,
                                        $"The type of the default value ({p.DefaultValue.Type}) does not match the type of the parameter ({p.Type})");
                        }
                    }
                }

                if (func.ReturnTypeExpr != null)
                {
                    func.ReturnTypeExpr.Mutable = true;
                }

                if (func.ReturnTypeExpr?.Name != null)
                {
                    func.ReturnTypeExpr.ContainingFunction = func;
                    func.ReturnTypeExpr.IsReturnParam      = true;
                    var(ok, other) = func.SubScope.DefineSymbol(func.ReturnTypeExpr);
                    if (!ok)
                    {
                        ReportError(func.ReturnTypeExpr, $"A symbol with name '{func.ReturnTypeExpr.Name.Name}' already exists in current scope", ("Other symbol here:", other));
                    }
                }
                else if (func.ReturnTypeExpr != null)
                {
                    func.SubScope.DefineSymbol(func.ReturnTypeExpr, ".ret");
                }
                if (func.ReturnTypeExpr?.TypeExpr is AstTupleExpr t)
                {
                    int index = 0;
                    foreach (var m in t.Types)
                    {
                        if (m.Name == null)
                        {
                            continue;
                        }
                        m.Mutable = true;
                        AstExpression access = new AstArrayAccessExpr(new AstSymbolExpr(func.ReturnTypeExpr), new AstNumberExpr(index, Location: func.ReturnTypeExpr.Location), func.ReturnTypeExpr.Location);
                        access         = InferType(access, null);
                        var(ok, other) = func.SubScope.DefineUse(m.Name.Name, access, false, out var use);
                        if (!ok)
                        {
                            ReportError(m, $"A symbol with name '{m.Name.Name}' already exists in current scope", ("Other symbol here:", other));
                        }
                        m.Symbol = use;
                        ++index;
                    }
                }

                if (func.FunctionType.IsErrorType || func.FunctionType.IsPolyType)
                {
                    return;
                }

                if (func.Body != null && !func.IsMacroFunction)
                {
                    var errs = PushSilentErrorHandler();
                    func.Body.AttachTo(func, func.SubScope);
                    InferType(func.Body, null);

                    if (func.ReturnTypeExpr != null && !func.Body.GetFlag(ExprFlags.Returns))
                    {
                        // TODO: check that all return values are set
                        var ret = new AstReturnStmt(null, new Location(func.Body.End));
                        ret.Scope = func.Body.SubScope;
                        ret       = AnalyseReturnStatement(ret);
                        func.Body.Statements.Add(ret);
                        func.Body.SetFlag(ExprFlags.Returns, true);
                    }

                    PopErrorHandler();

                    if (errs.HasErrors)
                    {
                        if (func.IsPolyInstance && func.InstantiatedAt != null)
                        {
                            ReportError($"Errors in polymorphic function '{func.Name}':");
                            errs.ForwardErrors(CurrentErrorHandler);

                            void ReportSources(AstFuncExpr func, string indent = "")
                            {
                                if (func.InstantiatedAt == null)
                                {
                                    return;
                                }
                                foreach (var loc in func.InstantiatedAt)
                                {
                                    ReportError(loc, indent + $"Failed to instantiate function '{func.Name}'");
                                }
                                foreach (var loc in func.InstantiatedBy)
                                {
                                    ReportError(loc, indent + $"Failed to instantiate function '{func.Name}'");
                                    ReportSources(loc, indent + "  ");
                                }
                            }

                            ReportError($"Caused from invocations here:");
                            ReportSources(func);
                        }
                        else
                        {
                            errs.ForwardErrors(CurrentErrorHandler);
                        }
                    }
                    else
                    {
                        PassVariableLifetimes(func);
                    }
                }
            }
            finally
            {
                currentFunction = prevCurrentFunction;
                PopLogScope();
                Log($"Finished function {func.Name}");
            }
        }
Ejemplo n.º 5
0
 public override string VisitDotExpr(AstDotExpr dot, int data = 0)
 {
     return($"{dot.Left?.Accept(this, 0)}.{dot.Right.Accept(this)}");
 }