node_modules/@bigcommerce/node-sass/src/libsass/src/expand.cpp
// For does not create a new env scope
// But iteration vars are reset afterwards
For does not create a new env scope
But iteration vars are reset afterwards
For does not create a new env scope But iteration vars are reset afterwards
Statement* Expand::operator()(For* f)
  {
    std::string variable(f->variable());
    Expression* low = f->lower_bound()->perform(&eval);
    if (low->concrete_type() != Expression::NUMBER) {
      error("lower bound of `@for` directive must be numeric", low->pstate(), backtrace());
    }
    Expression* high = f->upper_bound()->perform(&eval);
    if (high->concrete_type() != Expression::NUMBER) {
      error("upper bound of `@for` directive must be numeric", high->pstate(), backtrace());
    }
    Number* sass_start = static_cast<Number*>(low);
    Number* sass_end = static_cast<Number*>(high);
    if (sass_start->unit() != sass_end->unit()) {
      std::stringstream msg; msg << "Incompatible units: '"
        << sass_start->unit() << "' and '"
        << sass_end->unit() << "'.";
      error(msg.str(), low->pstate(), backtrace());
    }
    double start = sass_start->value();
    double end = sass_end->value();
    Env* env = environment();
    Number* it = SASS_MEMORY_NEW(env->mem, Number, low->pstate(), start, sass_end->unit());
    AST_Node* old_var = env->has_local(variable) ? env->get_local(variable) : 0;
    env->set_local(variable, it);
    Block* body = f->block();
    if (start < end) {
      if (f->is_inclusive()) ++end;
      for (double i = start;
           i < end;
           ++i) {
        it->value(i);
        env->set_local(variable, it);
        append_block(body);
      }
    } else {
      if (f->is_inclusive()) --end;
      for (double i = start;
           i > end;
           --i) {
        it->value(i);
        env->set_local(variable, it);
        append_block(body);
      }
    }
    if (!old_var) env->del_local(variable);
    else env->set_local(variable, old_var);
    return 0;
  }
Statement * Expand :: operator () ( For * f ) { std :: string variable ( f -> variable ( ) ) ; Expression * low = f -> lower_bound ( ) -> perform ( & eval ) ; if ( low -> concrete_type ( ) != Expression :: NUMBER ) { error ( " " , low -> pstate ( ) , backtrace ( ) ) ; } Expression * high = f -> upper_bound ( ) -> perform ( & eval ) ; if ( high -> concrete_type ( ) != Expression :: NUMBER ) { error ( " " , high -> pstate ( ) , backtrace ( ) ) ; } Number * sass_start = static_cast < Number * > ( low ) ; Number * sass_end = static_cast < Number * > ( high ) ; if ( sass_start -> unit ( ) != sass_end -> unit ( ) ) { std :: stringstream msg ; msg << " " << sass_start -> unit ( ) << " " << sass_end -> unit ( ) << " " ; error ( msg . str ( ) , low -> pstate ( ) , backtrace ( ) ) ; } double start = sass_start -> value ( ) ; double end = sass_end -> value ( ) ; Env * env = environment ( ) ; Number * it = SASS_MEMORY_NEW ( env -> mem , Number , low -> pstate ( ) , start , sass_end -> unit ( ) ) ; AST_Node * old_var = env -> has_local ( variable ) ? env -> get_local ( variable ) : 0 ; env -> set_local ( variable , it ) ; Block * body = f -> block ( ) ; if ( start < end ) { if ( f -> is_inclusive ( ) ) ++ end ; for ( double i = start ; i < end ; ++ i ) { it -> value ( i ) ; env -> set_local ( variable , it ) ; append_block ( body ) ; } } else { if ( f -> is_inclusive ( ) ) -- end ; for ( double i = start ; i > end ; -- i ) { it -> value ( i ) ; env -> set_local ( variable , it ) ; append_block ( body ) ; } } if ( ! old_var ) env -> del_local ( variable ) ; else env -> set_local ( variable , old_var ) ; return 0 ; }
For does not create a new env scope
But iteration vars are reset afterwards
For does not create a new env scope But iteration vars are reset afterwards
// check if units are valid for sequence // only create iterator once in this environment // restore original environment