Esempio n. 1
0
        public override string VisitForStmt(AstForStmt stmt, int data = 0)
        {
            var result = "";

            result += "for";

            if (stmt.Arguments != null)
            {
                result += "(";
                result += string.Join(", ", stmt.Arguments.Select(a => a.Accept(this)));
                result += ")";
            }

            result += " ";

            if (stmt.VarName != null)
            {
                result += stmt.VarName.Accept(this);
                if (stmt.IndexName != null)
                {
                    result += $", {stmt.IndexName.Accept(this)} ";
                }
                else
                {
                    result += " ";
                }
            }

            result += ": ";
            result += stmt.Collection.Accept(this);
            result += " ";
            result += stmt.Body.Accept(this);

            return(result);
        }
Esempio n. 2
0
    protected void ResolveForStmt(AstForStmt stmt)
    {
        bool scopePushed = false;

        if (stmt.m_preDecl != null)
        {
            PushScope();
            scopePushed = true;
            ResolveVarDeclStmt(stmt.m_preDecl);
        }
        else if (stmt.m_preExpr != null)
        {
            ResolveExpr(stmt.m_preExpr);
        }

        if (stmt.m_condition != null)
        {
            ResolveExpr(stmt.m_condition);
        }

        if (stmt.m_post != null)
        {
            ResolveExpr(stmt.m_post);
        }

        ResolveStmt(stmt.m_body);

        if (scopePushed)
        {
            PopScope();
        }
    }
Esempio n. 3
0
    protected void ExecuteForStmt(AstForStmt stmt)
    {
        if (HadErrorOrReturn())
        {
            return;
        }

        // NOTE (andrews) This pushes an environment before opening the scope, which is where any declared iterator lives

        bool isEnvPushed = false;

        if (stmt.m_preDecl != null)
        {
            Debug.Assert(stmt.m_preExpr == null);

            PushEnvironment();
            isEnvPushed = true;

            ExecuteVarDeclStmt(stmt.m_preDecl);
        }
        else if (stmt.m_preExpr != null)
        {
            EvaluateExpr(stmt.m_preExpr);
        }

        while (!m_runtimeError)
        {
            m_blockexitk = BLOCKEXITK.Normal;

            object conditionVal = true;

            if (stmt.m_condition != null)
            {
                conditionVal = EvaluateExpr(stmt.m_condition);

                if (!IsTruthy(conditionVal))
                {
                    break;
                }
            }

            ExecuteStmt(stmt.m_body);

            if (m_blockexitk == BLOCKEXITK.Break)
            {
                break;
            }

            if (stmt.m_post != null)
            {
                EvaluateExpr(stmt.m_post);
            }
        }

        if (isEnvPushed)
        {
            PopEnvironment();
        }
    }
Esempio n. 4
0
 public virtual ReturnType VisitForStmt(AstForStmt stmt, DataType data       = default) => default;
Esempio n. 5
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);
            }
        }