Пример #1
0
 public abstract Template Visit(StmtForEach stmt_for_each);
Пример #2
0
 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"));
     }
 }
Пример #3
0
 public abstract Template Visit(StmtForEach stmt_for_each);