kernel/source/misc/demangle.cpp
// welcome to the fucked up part: expression parsing.
welcome to the fucked up part: expression parsing.
welcome to the fucked up part : expression parsing .
static nx::string parseExpr(nx::string_view& s, State& st)
	{
		if(s.find("pp_") == 0)  { s.remove_prefix(3); return "++" + parseExpr(s, st); }
		if(s.find("mm_") == 0)  { s.remove_prefix(3); return "--" + parseExpr(s, st); }
		for(const auto& un : unaryOperators)
		{
			if(s.find(un.str.cstr()) == 0)
			{
				s.remove_prefix(un.str.size());
				return un.replacement + parseExpr(s, st);
			}
		}
		for(const auto& bi : binaryOperators)
		{
			if(s.find(bi.str.cstr()) == 0)
			{
				s.remove_prefix(bi.str.size());
				return bi.replacement + parseExpr(s, st).append(parseExpr(s, st));
			}
		}
		for(const auto& te : ternaryOperators)
		{
			if(s.find(te.str.cstr()) == 0)
			{
				s.remove_prefix(te.str.size());
				return te.replacement + parseExpr(s, st).append(parseExpr(s, st)).append(parseExpr(s, st));
			}
		}
		if(s[0] == 'T')
			return parseTemplateParam(s, st);
		if(auto un = parseUnresolvedName(s, st); !un.empty())
			return un;
		return parsePrimaryExpr(s, st);
	}
static nx :: string parseExpr ( nx :: string_view & s , State & st ) { if ( s . find ( " " ) == 0 ) { s . remove_prefix ( 3 ) ; return " " + parseExpr ( s , st ) ; } if ( s . find ( " " ) == 0 ) { s . remove_prefix ( 3 ) ; return " " + parseExpr ( s , st ) ; } for ( const auto & un : unaryOperators ) { if ( s . find ( un . str . cstr ( ) ) == 0 ) { s . remove_prefix ( un . str . size ( ) ) ; return un . replacement + parseExpr ( s , st ) ; } } for ( const auto & bi : binaryOperators ) { if ( s . find ( bi . str . cstr ( ) ) == 0 ) { s . remove_prefix ( bi . str . size ( ) ) ; return bi . replacement + parseExpr ( s , st ) . append ( parseExpr ( s , st ) ) ; } } for ( const auto & te : ternaryOperators ) { if ( s . find ( te . str . cstr ( ) ) == 0 ) { s . remove_prefix ( te . str . size ( ) ) ; return te . replacement + parseExpr ( s , st ) . append ( parseExpr ( s , st ) ) . append ( parseExpr ( s , st ) ) ; } } if ( s [ 0 ] == ' ' ) return parseTemplateParam ( s , st ) ; if ( auto un = parseUnresolvedName ( s , st ) ; ! un . empty ( ) ) return un ; return parsePrimaryExpr ( s , st ) ; }
welcome to the fucked up part: expression parsing.
welcome to the fucked up part : expression parsing .
// TODO: currently stuck on template param substitutions. /*
			<expression>    ::= <unary operator-name> <expression>
							::= <binary operator-name> <expression> <expression>
							::= <ternary operator-name> <expression> <expression> <expression>
							::= pp_ <expression>                             # prefix ++
							::= mm_ <expression>                             # prefix --

							::= cl <expression>+ E                           # expression (expr-list), call
							::= cv <type> <expression>                       # type (expression), conversion with one argument
							::= cv <type> _ <expression>* E                  # type (expr-list), conversion with other than one argument
							::= tl <type> <braced-expression>* E             # type {expr-list}, conversion with braced-init-list argument
							::= il <braced-expression>* E                    # {expr-list}, braced-init-list in any other context
							::= [gs] nw <expression>* _ <type> E             # new (expr-list) type
							::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
							::= [gs] na <expression>* _ <type> E             # new[] (expr-list) type
							::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
							::= [gs] dl <expression>                         # delete expression
							::= [gs] da <expression>                         # delete[] expression
							::= dc <type> <expression>                       # dynamic_cast<type> (expression)
							::= sc <type> <expression>                       # static_cast<type> (expression)
							::= cc <type> <expression>                       # const_cast<type> (expression)
							::= rc <type> <expression>                       # reinterpret_cast<type> (expression)
							::= ti <type>                                    # typeid (type)
							::= te <expression>                              # typeid (expression)
							::= st <type>                                    # sizeof (type)
							::= sz <expression>                              # sizeof (expression)
							::= at <type>                                    # alignof (type)
							::= az <expression>                              # alignof (expression)
							::= nx <expression>                              # noexcept (expression)
							::= <template-param>
							::= <function-param>
							::= dt <expression> <unresolved-name>   # expr.name
							::= pt <expression> <unresolved-name>   # expr->name
							::= ds <expression> <expression>        # expr.*expr
							::= sZ <template-param>                 # sizeof...(T), size of a template parameter pack
							::= sZ <function-param>                 # sizeof...(parameter), size of a function parameter pack
							::= sP <template-arg>* E                # sizeof...(T), size of a captured template parameter pack from an alias template
							::= sp <expression>                     # expression..., pack expansion
							::= tw <expression>                     # throw expression
							::= tr                                  # throw with no operand (rethrow)
							::= <unresolved-name>                   # f(p), N::f(p), ::f(p),
																	# freestanding dependent name (e.g., T::x),
																	# objectless nonstatic member reference
							::= <expr-primary>
		*/ // note: prefix ++ and -- have the same string prefix (i think) as their suffix counterparts, // so try them first.