// 式クラス // コンストラクタ // tokarray:トークン配列 index:述部トークンのインデックス Expression::Expression(const TokenArray tokarray, int index) : _value(0) { switch(tokarray[index].type()) { // 述部が演算子なら case TOK_OPERATOR: _expr_type = EXPR_OPERATION; _sub_type = operator_type(tokarray[index].str().c_str()); int op_prev, op_this, op_next; // 前/現在/次の演算子 // 1つ前の演算子があればそれを、なければ0を格納 if(index >= 2) { op_prev = operator_type(tokarray[index-2].str().c_str()); } else { op_prev = 0; } op_this = _sub_type; // 1つ後の演算子があればそれを、なければ0を格納 if(index <= tokarray.size() - 3) { op_next = operator_type(tokarray[index+2].str().c_str()); } else { op_next = 0; } // 前後の演算子と優先度の高低を比較する // 優先度が等しい場合は、前の式と等しいならPREVを、後ろの式と等しいなら即値を引数とする Expression op1, op2; // 左右オペランド // 1つ前の演算子の優先度と比較 if(is_same_priority(op_this, op_prev) > 0) { // 即値を引数に取る op1 = Expression(VAL_NUMBER,icast(tokarray[index-1].str())); } else { // PREV(評価結果)を引数に取る op1 = Expression(VAL_EXPRESSION, PREV); } // 1つ後の演算子の優先度と比較 if(is_same_priority(op_this, op_next) >= 0) { // 即値を引数に取る op2 = Expression(VAL_NUMBER,icast(tokarray[index+1].str())); } else { // NEXT(評価結果)を引数に取る op2 = Expression(VAL_EXPRESSION, NEXT); } // 左右オペランドを引数として追加 _arg.push_back(op1); _arg.push_back(op2); break; } }
index AbstractLayer::create_layer(const DictionaryDatum & layer_dict) { index length = 0; const char *layer_model_name = 0; std::vector<long_t> element_ids; std::string element_name; Token element_model; const Token& t = layer_dict->lookup(names::elements); ArrayDatum* ad = dynamic_cast<ArrayDatum *>(t.datum()); if (ad) { for (Token* tp = ad->begin(); tp != ad->end(); ++tp) { element_name = std::string(*tp); element_model = net_->get_modeldict().lookup(element_name); if ( element_model.empty() ) throw UnknownModelName(element_name); // Creates several nodes if the next element in // the elements variable is a number. if ((tp+1 != ad->end()) && dynamic_cast<IntegerDatum*>((tp+1)->datum())) { // Select how many nodes that should be created. const long_t number = getValue<long_t>(*(++tp)); for(long_t i=0;i<number;++i) element_ids.push_back(static_cast<long>(element_model)); } else { element_ids.push_back(static_cast<long>(element_model)); } } } else { element_name = getValue<std::string>(layer_dict, names::elements); element_model = net_->get_modeldict().lookup(element_name); if ( element_model.empty() ) throw UnknownModelName(element_name); element_ids.push_back(static_cast<long>(element_model)); } if (layer_dict->known(names::positions)) { if (layer_dict->known(names::rows) or layer_dict->known(names::columns) or layer_dict->known(names::layers)) throw BadProperty("Can not specify both positions and rows or columns."); TokenArray positions = getValue<TokenArray>(layer_dict, names::positions); if (positions.size() == 0) { throw BadProperty("Empty positions array."); } std::vector<double_t> pos = getValue<std::vector<double_t> >(positions[0]); if (pos.size() == 2) layer_model_name = "topology_layer_free"; else if (pos.size() == 3) layer_model_name = "topology_layer_free_3d"; else throw BadProperty("Positions must have 2 or 3 coordinates."); length = positions.size(); } else if (layer_dict->known(names::columns)) { if (not layer_dict->known(names::rows)) { throw BadProperty("Both columns and rows must be given."); } length=getValue<long_t>(layer_dict, names::columns) * getValue<long_t>(layer_dict, names::rows); if (layer_dict->known(names::layers)) { layer_model_name = "topology_layer_grid_3d"; length *= getValue<long_t>(layer_dict, names::layers); } else { layer_model_name = "topology_layer_grid"; } } else { throw BadProperty("Unknown layer type."); } assert(layer_model_name != 0); Token layer_model = net_->get_modeldict().lookup(layer_model_name); if ( layer_model.empty() ) throw UnknownModelName(layer_model_name); index layer_node = net_->add_node(layer_model); // Remember original subnet const index cwnode = net_->get_cwn()->get_gid(); net_->go_to(layer_node); // Create layer nodes. for ( size_t i = 0 ; i < element_ids.size() ; ++i ) { for ( index n = 0 ; n < length ; ++n ) { net_->add_node(element_ids[i]); } } // Return to original subnet net_->go_to(cwnode); //Set layer parameters according to input dictionary. AbstractLayer *layer = dynamic_cast<AbstractLayer *>(net_->get_node(layer_node)); layer->depth_ = element_ids.size(); layer->set_status(layer_dict); return layer_node; }