pol-core/bscript/str.cpp | 346 +++++++++++++++++++++++------------------------ 1 file changed, 168 insertions(+), 178 deletions(-) diff --git a/pol-core/bscript/str.cpp b/pol-core/bscript/str.cpp index 1f00dda..47d120c 100644 --- a/pol-core/bscript/str.cpp +++ b/pol-core/bscript/str.cpp @@ -659,84 +659,71 @@ namespace Pol { } } - bool try_to_format(std::stringstream &to_stream, BObjectImp *what, std::string& frmt) + // suplementory function to format + inline bool try_to_format(std::stringstream &to_stream, BObjectImp *what, std::string& frmt) { - if ( frmt.empty() ) - { - to_stream << what->getStringRep(); - return false; - } + if (frmt.empty()) { + to_stream << what->getStringRep(); + return false; + } - if (frmt.find('b') != std::string::npos) - { - if ( !what->isa( BObjectImp::OTLong ) ) - { - to_stream << ""; - return false; + if (frmt.find('b') != std::string::npos) { + if (!what->isa(BObjectImp::OTLong)) { + to_stream << ""; + return false; + } + BLong* plong = static_cast(what); + int n = plong->value(); + if (frmt.find('#') != std::string::npos) + to_stream << ((n<0) ? "-" : "") << "0b"; + int_to_binstr(n, to_stream); } - BLong* plong = static_cast( what ); - int n = plong->value(); - if (frmt.find('#') != std::string::npos) - to_stream << ( ( n < 0 ) ? "-" : "" ) << "0b"; - int_to_binstr( n, to_stream ); - } - else if (frmt.find('x') != std::string::npos) - { - if ( !what->isa( BObjectImp::OTLong ) ) - { - to_stream << ""; - return false; + else if (frmt.find('x') != std::string::npos) { + if (!what->isa(BObjectImp::OTLong)) { + to_stream << ""; + return false; + } + BLong* plong = static_cast(what); + int n = plong->value(); + if (frmt.find('#') != std::string::npos) + to_stream << "0x"; + to_stream << std::hex << n; } - BLong* plong = static_cast( what ); - int n = plong->value(); - if (frmt.find('#') != std::string::npos) - to_stream << "0x"; - to_stream << std::hex << n; - } - else if (frmt.find('o') != std::string::npos) - { - if ( !what->isa( BObjectImp::OTLong ) ) - { - to_stream << ""; - return false; + else if (frmt.find('o') != std::string::npos) { + if (!what->isa(BObjectImp::OTLong)) { + to_stream << ""; + return false; + } + BLong* plong = static_cast(what); + int n = plong->value(); + if (frmt.find('#') != std::string::npos) + to_stream << "0o"; + to_stream << std::oct << n; } - BLong* plong = static_cast( what ); - int n = plong->value(); - if (frmt.find('#') != std::string::npos) - to_stream << "0o"; - to_stream << std::oct << n; - } - else if (frmt.find('d') != std::string::npos) - { - int n; - if ( what->isa( BObjectImp::OTLong ) ) - { - BLong* plong = static_cast( what ); - n = plong->value(); + else if (frmt.find('d') != std::string::npos) { + int n; + if (what->isa(BObjectImp::OTLong)) { + BLong* plong = static_cast(what); + n = plong->value(); + } + else if (what->isa(BObjectImp::OTDouble)) { + Double* pdbl = static_cast(what); + n = (int)pdbl->value(); + } + else { + to_stream << ""; + return false; + } + to_stream << std::dec << n; } - else if ( what->isa( BObjectImp::OTDouble ) ) - { - Double* pdbl = static_cast( what ); - n = (int)pdbl->value(); - } - else - { - to_stream << ""; - return false; + else { + to_stream << ""; + return false; } - to_stream << std::dec << n; - } - else - { - to_stream << ""; - return false; - } - return true; + return true; } - // -- - BObjectImp* String::call_method( const char* methodname, Executor& ex ) { ObjMethod* objmethod = getKnownObjMethod( methodname ); @@ -791,117 +778,120 @@ namespace Pol { } case MTH_FORMAT: { - if ( ex.numParams() > 0 ) - { - - std::string s = this->getStringRep(); // string itself - std::stringstream result; - - size_t tag_start_pos; // the position of tag's start "{" - size_t tag_stop_pos; // the position of tag's end "}" - size_t tag_dot_pos; - int tag_param_idx; - - size_t str_pos = 0; // current string position - unsigned int next_param_idx = 0; // next index of .format() parameter - - while ((tag_start_pos = s.find("{", str_pos)) != std::string::npos) - { - if ((tag_stop_pos = s.find("}", tag_start_pos)) != std::string::npos) - { - - result << s.substr( str_pos, tag_start_pos - str_pos ); - str_pos = tag_stop_pos + 1; - - std::string tag_body = s.substr(tag_start_pos + 1, (tag_stop_pos - tag_start_pos) - 1); - s_trim( tag_body ); // trim the tag of whitespaces - - std::string frmt; - size_t formatter_pos = tag_body.find( ':' ); - - if (formatter_pos != std::string::npos) - { - frmt = tag_body.substr(formatter_pos + 1, std::string::npos); // - tag_body = tag_body.substr( 0, formatter_pos ); // remove property from the tag - } - - std::string prop_name; - // parsing {1.this_part} - tag_dot_pos = tag_body.find( ".", 0 ); - - // '.' is found within the tag, there is a property name - if (tag_dot_pos != std::string::npos) - { - prop_name = tag_body.substr( tag_dot_pos + 1, std::string::npos ); // - tag_body = tag_body.substr( 0, tag_dot_pos ); // remove property from the tag - - // if s_tag_body is numeric then use it as an index - if ( s_parse_int( tag_param_idx, tag_body ) ) - { - tag_param_idx -= 1; // sinse POL indexes are 1-based - } - else - { - result << ""; - continue; - } - } - else - { - if ( s_parse_int( tag_param_idx, tag_body ) ) - { - tag_param_idx -= 1; // sinse POL indexes are 1-based - } - else - { // non-integer body has just next idx in line - prop_name = tag_body; - tag_param_idx = next_param_idx++; - } - } - - // -- end of property parsing - - //cout << "prop_name: '" << prop_name << "' tag_body: '" << tag_body << "'"; - - // Checks that tag_param_idx is >0, otherwise it would fail when compared with ex.numParams() - if ( tag_param_idx < 0 || ex.numParams() <= static_cast( tag_param_idx ) ) - { - result << ""; - continue; - } - - BObjectImp *imp = ex.getParamImp( tag_param_idx ); - - if ( prop_name.empty() == false ) - { // accesing object member - BObjectRef obj_member = imp->get_member( prop_name.c_str() ); - BObjectImp *member_imp = obj_member->impptr(); - try_to_format( result, member_imp, frmt ); - } - else - { - try_to_format( result, imp, frmt ); - } - } - else - { - break; - } - } - - if ( str_pos < s.length() ) - { - result << s.substr(str_pos, std::string::npos); - } - - return new String( result.str() ); - - } - else - { - return new BError( "string.format() requires a parameter." ); - } + if (ex.numParams() > 0) { + + //string s = this->getStringRep(); // string itself + std::stringstream result; + + unsigned int tag_start_pos; // the position of tag's start "{" + unsigned int tag_stop_pos; // the position of tag's end "}" + unsigned int tag_dot_pos; + + int tag_param_idx; + + unsigned int str_pos = 0; // current string position + unsigned int next_param_idx = 0; // next index of .format() parameter + + char w_spaces[] = "\t "; + + while ((tag_start_pos = value_.find("{", str_pos)) != std::string::npos) { + if ((tag_stop_pos = value_.find("}", tag_start_pos)) != std::string::npos) { + + result << value_.substr(str_pos, tag_start_pos - str_pos); + str_pos = tag_stop_pos + 1; + + std::string tag_body = value_.substr(tag_start_pos + 1, (tag_stop_pos - tag_start_pos) - 1); + + tag_start_pos = tag_body.find_first_not_of(w_spaces); + tag_stop_pos = tag_body.find_last_not_of(w_spaces); + + //cout << "' tag_body1: '" << tag_body << "'"; + + // trim the tag of whitespaces (slightly faster code ~25%) + if (tag_start_pos != std::string::npos && tag_stop_pos != std::string::npos) + tag_body = tag_body.substr(tag_start_pos, (tag_stop_pos - tag_start_pos) + 1); + else if (tag_start_pos != std::string::npos) + tag_body = tag_body.substr(tag_start_pos); + else if (tag_stop_pos != std::string::npos) + tag_body = tag_body.substr(0, tag_stop_pos + 1); + + // s_trim( tag_body ); // trim the tag of whitespaces + + //cout << "' tag_body2: '" << tag_body << "'"; + + std::string frmt; + size_t formatter_pos = tag_body.find(':'); + + if (formatter_pos != std::string::npos) { + frmt = tag_body.substr(formatter_pos + 1, std::string::npos); // + tag_body = tag_body.substr(0, formatter_pos); // remove property from the tag + } + + std::string prop_name; + // parsing {1.this_part} + tag_dot_pos = tag_body.find(".", 0); + + // '.' is found within the tag, there is a property name + if (tag_dot_pos != std::string::npos) { + prop_name = tag_body.substr(tag_dot_pos + 1, std::string::npos); // + tag_body = tag_body.substr(0, tag_dot_pos); // remove property from the tag + + // if s_tag_body is numeric then use it as an index + if (s_parse_int(tag_param_idx, tag_body)) { + tag_param_idx -= 1; // sinse POL indexes are 1-based + } + else { + result << ""; + continue; + } + } + else { + if (s_parse_int(tag_param_idx, tag_body)) { + tag_param_idx -= 1; // sinse POL indexes are 1-based + } + else { // non-integer body has just next idx in line + prop_name = tag_body; + tag_param_idx = next_param_idx++; + } + } + + // -- end of property parsing + + //cout << "prop_name: '" << prop_name << "' tag_body: '" << tag_body << "'"; + + if (ex.numParams() <= tag_param_idx) { + result << ""; + continue; + } + + BObjectImp *imp = ex.getParamImp(tag_param_idx); + + if (prop_name.empty() == false) { // accesing object + BObjectRef obj_member = imp->get_member(prop_name.c_str()); + BObjectImp *member_imp = obj_member->impptr(); + try_to_format(result, member_imp, frmt); + + } + else { + try_to_format(result, imp, frmt); + } + + } + else { + break; + } + } + + if (str_pos < value_.length()) { + result << value_.substr(str_pos, std::string::npos); + } + + return new String(result.str()); + } + else { + return new BError("string.format() requires a parameter."); + } } case MTH_JOIN: {