public abstract Template Visit(StmtForEach stmt_for_each);
public override Template Visit(StmtForEach stmt_for_each) { if (stmt_for_each.Var is ExprConst) { ExprConst expr = (ExprConst) stmt_for_each.Var; Template template = new Template("for (auto <var> : <expr>) {\n <body>\n}"); template.Add("var", expr.Text); template.Add("expr", stmt_for_each.Target.Accept(this)); template.Add("body", stmt_for_each.Body.Accept(this)); return template; } else if (stmt_for_each.Var is ExprCall) { ExprCall expr = (ExprCall)stmt_for_each.Var; List<Stmt> stmt_list = new List<Stmt>(); List<Expr> condition_list = new List<Expr>(); int i = 0; foreach (var argument in expr.Args) { ExprCall get = new ExprCall(new ExprConst("std::get", ConstType.Ident), new List<string> {i.ToString()}, new List<Expr> {new ExprConst("_t_match", ConstType.Ident)}); i++; if (argument is ExprConst && ((ExprConst)argument).Type == ConstType.Ident && !((ExprConst)argument).Text.StartsWith("@")) { ExprConst const_expr = (ExprConst)argument; if (const_expr.Text == "_") { continue; } stmt_list.Add(new StmtExpr(new ExprAlloc("auto", new List<string> { const_expr.Text }, new List<Expr>{ get }, true))); } else { if (((ExprConst)argument).Text.StartsWith("@")) { ((ExprConst)argument).Text = ((ExprConst)argument).Text.Substring(1); } condition_list.Add(new ExprBin("==", get, argument)); } } StmtBlock block = new StmtBlock(); foreach (var item in stmt_list) { block.StmtList.Add(item); } foreach (var item in stmt_for_each.Body.StmtList) { block.StmtList.Add(item); } if (condition_list.Count() > 0) { StmtBlock if_body = new StmtBlock(); if_body.StmtList.Add(new StmtExpr(new ExprAlloc("auto&&", new List<string> { "_t_match" }, new List<Expr> { new ExprCall(new ExprAccess(new ExprConst("_t_iterator", ConstType.Ident), ".", "Unapply"), null, null) }, true))); Expr condition = null; foreach (var item in condition_list) { if (condition == null) { condition = item; if (condition_list.Count() > 1) { condition = new ExprBracket(condition); } } else { condition = new ExprBin("&&", condition, new ExprBracket(item)); } } StmtIf stmt_if = new StmtIf(condition, block, null); if_body.StmtList.Add(stmt_if); block = if_body; } else { block.StmtList.Insert(0, new StmtExpr(new ExprAlloc("auto&&", new List<string> { "_t_match" }, new List<Expr> { new ExprCall(new ExprAccess(new ExprConst("_t_iterator", ConstType.Ident), ".", "Unapply"), null, null) }, true))); } StmtForEach for_each = new StmtForEach(new ExprConst("_t_iterator", ConstType.Ident), stmt_for_each.Target, block); return for_each.Accept(this); } else if (stmt_for_each.Var is ExprTuple) { ExprTuple expr = (ExprTuple)stmt_for_each.Var; List<Stmt> stmt_list = new List<Stmt>(); List<Expr> condition_list = new List<Expr>(); int i = 0; foreach (var argument in expr.ExprList) { ExprCall get = new ExprCall(new ExprConst("get", ConstType.Ident), new List<string> { i.ToString() }, new List<Expr> { new ExprConst("_t_match", ConstType.Ident) }); i++; if (argument is ExprConst && ((ExprConst)argument).Type == ConstType.Ident) { ExprConst const_expr = (ExprConst)argument; if (const_expr.Text == "_") { continue; } stmt_list.Add(new StmtExpr(new ExprAlloc("auto", new List<string> { const_expr.Text }, new List<Expr> { get }, true))); } else { condition_list.Add(new ExprBin("==", get, argument)); } } StmtBlock block = new StmtBlock(); foreach (var item in stmt_list) { block.StmtList.Add(item); } foreach (var item in stmt_for_each.Body.StmtList) { block.StmtList.Add(item); } if (condition_list.Count() > 0) { StmtBlock if_body = new StmtBlock(); Expr condition = null; foreach (var item in condition_list) { if (condition == null) { condition = item; if (condition_list.Count() > 1) { condition = new ExprBracket(condition); } } else { condition = new ExprBin("&&", condition, new ExprBracket(item)); } } StmtIf stmt_if = new StmtIf(condition, block, null); if_body.StmtList.Add(stmt_if); block = if_body; } StmtForEach for_each = new StmtForEach(new ExprConst("_t_match", ConstType.Ident), stmt_for_each.Target, block); return for_each.Accept(this); } else { throw new Exception(string.Format("Iterators in foreach must be either variable or pattern matching")); } }
public abstract Template Visit(StmtForEach stmt_for_each);