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); }
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(); } }
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(); } }
public virtual ReturnType VisitForStmt(AstForStmt stmt, DataType data = default) => default;
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); } }