1 #include "Enumeration.hpp"
  
    2 #include <soulng/util/Unicode.hpp>
  
    3 #include <sngcm/cmparser/Specifier.hpp>
  
    4 #include <sngcm/cmparser/Identifier.hpp>
  
    5 #include <sngcm/cmparser/TypeExpr.hpp>
  
    6 #include <sngcm/cmparser/Expression.hpp>
  
    7 #include <sngcm/cmlexer/CmajorLexer.hpp>
  
    8 #include <sngcm/cmlexer/CmajorTokens.hpp>
  
    9 
  
   10 
  
   11 
  
   12 using namespace soulng::unicode;
  
   13 using namespace sngcm::ast;
  
   14 using namespace CmajorTokens;
  
   15 
  
   16 soulng::parser::Match EnumerationParser::EnumType(CmajorLexer& lexer, ParsingContext* ctx)
  
   17 {
  
   18     #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
   19 
  
   20 
  
   21 
  
   22 
  
   23 
  
   24 
  
   25 
  
   26     #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
   27     std::unique_ptr<EnumTypeNode> enumTypeNode = std::unique_ptr<EnumTypeNode>();
  
   28     Span s = Span();
  
   29     Span beginBraceSpan = Span();
  
   30     Span endBraceSpan = Span();
  
   31     std::unique_ptr<soulng::parser::soulng::parser::Value<sngcm::ast::Specifiers>>specifiers;
  
   32     std::unique_ptr<IdentifierNode> enumTypeId;
  
   33     std::unique_ptr<Node> underlyingType;
  
   34     soulng::parser::Match match(false);
  
   35     soulng::parser::Match* parentMatch0 = &match;
  
   36     {
  
   37         soulng::parser::Match match(false);
  
   38         soulng::parser::Match* parentMatch1 = &match;
  
   39         {
  
   40             soulng::parser::Match match(false);
  
   41             soulng::parser::Match* parentMatch2 = &match;
  
   42             {
  
   43                 soulng::parser::Match match(false);
  
   44                 soulng::parser::Match* parentMatch3 = &match;
  
   45                 {
  
   46                     soulng::parser::Match match(false);
  
   47                     soulng::parser::Match* parentMatch4 = &match;
  
   48                     {
  
   49                         soulng::parser::Match match(false);
  
   50                         soulng::parser::Match* parentMatch5 = &match;
  
   51                         {
  
   52                             soulng::parser::Match match(false);
  
   53                             soulng::parser::Match* parentMatch6 = &match;
  
   54                             {
  
   55                                 int64_t pos = lexer.GetPos();
  
   56                                 soulng::lexer::Span span = lexer.GetSpan();
  
   57                                 soulng::parser::Match match = SpecifierParser::Specifiers(lexer);
  
   58                                 specifiers.reset(static_cast<soulng::parser::soulng::parser::Value<sngcm::ast::Specifiers>*>(match.value));
  
   59                                 if (match.hit)
  
   60                                 {
  
   61                                     s = span;
  
   62                                 }
  
   63                                 *parentMatch6 = match;
  
   64                             }
  
   65                             *parentMatch5 = match;
  
   66                         }
  
   67                         if (match.hit)
  
   68                         {
  
   69                             soulng::parser::Match match(false);
  
   70                             soulng::parser::Match* parentMatch7 = &match;
  
   71                             {
  
   72                                 soulng::parser::Match match(false);
  
   73                                 if (*lexer == ENUM)
  
   74                                 {
  
   75                                     ++lexer;
  
   76                                     match.hit = true;
  
   77                                 }
  
   78                                 *parentMatch7 = match;
  
   79                             }
  
   80                             *parentMatch5 = match;
  
   81                         }
  
   82                         *parentMatch4 = match;
  
   83                     }
  
   84                     if (match.hit)
  
   85                     {
  
   86                         soulng::parser::Match match(false);
  
   87                         soulng::parser::Match* parentMatch8 = &match;
  
   88                         {
  
   89                             soulng::parser::Match match(false);
  
   90                             soulng::parser::Match* parentMatch9 = &match;
  
   91                             {
  
   92                                 int64_t pos = lexer.GetPos();
  
   93                                 soulng::lexer::Span span = lexer.GetSpan();
  
   94                                 soulng::parser::Match match(true);
  
   95                                 soulng::parser::Match* parentMatch10 = &match;
  
   96                                 {
  
   97                                     soulng::lexer::Span span = lexer.GetSpan();
  
   98                                     soulng::parser::Match match = IdentifierParser::Identifier(lexer);
  
   99                                     enumTypeId.reset(static_cast<IdentifierNode*>(match.value));
  
  100                                     if (match.hit)
  
  101                                     {
  
  102                                         *parentMatch10 = match;
  
  103                                     }
  
  104                                     else
  
  105                                     {
  
  106                                         lexer.ThrowExpectationFailure(span, U"identifier");
  
  107                                     }
  
  108                                 }
  
  109                                 if (match.hit)
  
  110                                 {
  
  111                                     s.end = span.end;
  
  112                                     enumTypeNode.reset(new EnumTypeNode(s, specifiers->value, enumTypeId.release()));
  
  113                                 }
  
  114                                 *parentMatch9 = match;
  
  115                             }
  
  116                             *parentMatch8 = match;
  
  117                         }
  
  118                         *parentMatch4 = match;
  
  119                     }
  
  120                     *parentMatch3 = match;
  
  121                 }
  
  122                 if (match.hit)
  
  123                 {
  
  124                     soulng::parser::Match match(false);
  
  125                     soulng::parser::Match* parentMatch11 = &match;
  
  126                     {
  
  127                         soulng::parser::Match match(true);
  
  128                         int64_t save = lexer.GetPos();
  
  129                         soulng::parser::Match* parentMatch12 = &match;
  
  130                         {
  
  131                             soulng::parser::Match match(false);
  
  132                             soulng::parser::Match* parentMatch13 = &match;
  
  133                             {
  
  134                                 soulng::parser::Match match(false);
  
  135                                 soulng::parser::Match* parentMatch14 = &match;
  
  136                                 {
  
  137                                     int64_t pos = lexer.GetPos();
  
  138                                     soulng::parser::Match match = EnumerationParser::UnderlyingType(lexer, ctx);
  
  139                                     underlyingType.reset(static_cast<Node*>(match.value));
  
  140                                     if (match.hit)
  
  141                                     {
  
  142                                         enumTypeNode->SetUnderlyingType(underlyingType.release());
  
  143                                     }
  
  144                                     *parentMatch14 = match;
  
  145                                 }
  
  146                                 *parentMatch13 = match;
  
  147                             }
  
  148                             if (match.hit)
  
  149                             {
  
  150                                 *parentMatch12 = match;
  
  151                             }
  
  152                             else
  
  153                             {
  
  154                                 lexer.SetPos(save);
  
  155                             }
  
  156                         }
  
  157                         *parentMatch11 = match;
  
  158                     }
  
  159                     *parentMatch3 = match;
  
  160                 }
  
  161                 *parentMatch2 = match;
  
  162             }
  
  163             if (match.hit)
  
  164             {
  
  165                 soulng::parser::Match match(false);
  
  166                 soulng::parser::Match* parentMatch15 = &match;
  
  167                 {
  
  168                     soulng::parser::Match match(false);
  
  169                     soulng::parser::Match* parentMatch16 = &match;
  
  170                     {
  
  171                         int64_t pos = lexer.GetPos();
  
  172                         soulng::lexer::Span span = lexer.GetSpan();
  
  173                         soulng::parser::Match match(true);
  
  174                         soulng::parser::Match* parentMatch17 = &match;
  
  175                         {
  
  176                             soulng::lexer::Span span = lexer.GetSpan();
  
  177                             soulng::parser::Match match(false);
  
  178                             if (*lexer == LBRACE)
  
  179                             {
  
  180                                 ++lexer;
  
  181                                 match.hit = true;
  
  182                             }
  
  183                             if (match.hit)
  
  184                             {
  
  185                                 *parentMatch17 = match;
  
  186                             }
  
  187                             else
  
  188                             {
  
  189                                 lexer.ThrowExpectationFailure(span, ToUtf32(GetTokenInfo(LBRACE)));
  
  190                             }
  
  191                         }
  
  192                         if (match.hit)
  
  193                         {
  
  194                             beginBraceSpan = span;
  
  195                         }
  
  196                         *parentMatch16 = match;
  
  197                     }
  
  198                     *parentMatch15 = match;
  
  199                 }
  
  200                 *parentMatch2 = match;
  
  201             }
  
  202             *parentMatch1 = match;
  
  203         }
  
  204         if (match.hit)
  
  205         {
  
  206             soulng::parser::Match match(false);
  
  207             soulng::parser::Match* parentMatch18 = &match;
  
  208             {
  
  209                 soulng::parser::Match match = EnumerationParser::EnumConstants(lexer, ctx, enumTypeNode.get());
  
  210                 *parentMatch18 = match;
  
  211             }
  
  212             *parentMatch1 = match;
  
  213         }
  
  214         *parentMatch0 = match;
  
  215     }
  
  216     if (match.hit)
  
  217     {
  
  218         soulng::parser::Match match(false);
  
  219         soulng::parser::Match* parentMatch19 = &match;
  
  220         {
  
  221             soulng::parser::Match match(false);
  
  222             soulng::parser::Match* parentMatch20 = &match;
  
  223             {
  
  224                 int64_t pos = lexer.GetPos();
  
  225                 soulng::lexer::Span span = lexer.GetSpan();
  
  226                 soulng::parser::Match match(true);
  
  227                 soulng::parser::Match* parentMatch21 = &match;
  
  228                 {
  
  229                     soulng::lexer::Span span = lexer.GetSpan();
  
  230                     soulng::parser::Match match(false);
  
  231                     if (*lexer == RBRACE)
  
  232                     {
  
  233                         ++lexer;
  
  234                         match.hit = true;
  
  235                     }
  
  236                     if (match.hit)
  
  237                     {
  
  238                         *parentMatch21 = match;
  
  239                     }
  
  240                     else
  
  241                     {
  
  242                         lexer.ThrowExpectationFailure(span, ToUtf32(GetTokenInfo(RBRACE)));
  
  243                     }
  
  244                 }
  
  245                 if (match.hit)
  
  246                 {
  
  247                     endBraceSpan = span;
  
  248                     enumTypeNode->SetBeginBraceSpan(beginBraceSpan);
  
  249                     enumTypeNode->SetEndBraceSpan(endBraceSpan);
  
  250                     {
  
  251                         #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  252 
  
  253                         #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  254                         return soulng::parser::Match(true, enumTypeNode.release());
  
  255                     }
  
  256                 }
  
  257                 *parentMatch20 = match;
  
  258             }
  
  259             *parentMatch19 = match;
  
  260         }
  
  261         *parentMatch0 = match;
  
  262     }
  
  263     #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  264 
  
  265 
  
  266 
  
  267 
  
  268 
  
  269     #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  270     if (!match.hit)
  
  271     {
  
  272         match.value = nullptr;
  
  273     }
  
  274     return match;
  
  275 }
  
  276 
  
  277 soulng::parser::Match EnumerationParser::UnderlyingType(CmajorLexer& lexer, ParsingContext* ctx)
  
  278 {
  
  279     #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  280 
  
  281 
  
  282 
  
  283 
  
  284 
  
  285 
  
  286 
  
  287     #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  288     std::unique_ptr<sngcm::ast::Node> type;
  
  289     soulng::parser::Match match(false);
  
  290     soulng::parser::Match* parentMatch0 = &match;
  
  291     {
  
  292         soulng::parser::Match match(false);
  
  293         if (*lexer == COLON)
  
  294         {
  
  295             ++lexer;
  
  296             match.hit = true;
  
  297         }
  
  298         *parentMatch0 = match;
  
  299     }
  
  300     if (match.hit)
  
  301     {
  
  302         soulng::parser::Match match(false);
  
  303         soulng::parser::Match* parentMatch1 = &match;
  
  304         {
  
  305             soulng::parser::Match match(false);
  
  306             soulng::parser::Match* parentMatch2 = &match;
  
  307             {
  
  308                 int64_t pos = lexer.GetPos();
  
  309                 soulng::parser::Match match = TypeExprParser::TypeExpr(lexer, ctx);
  
  310                 type.reset(static_cast<sngcm::ast::Node*>(match.value));
  
  311                 if (match.hit)
  
  312                 {
  
  313                     {
  
  314                         #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  315 
  
  316                         #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  317                         return soulng::parser::Match(true, type.release());
  
  318                     }
  
  319                 }
  
  320                 *parentMatch2 = match;
  
  321             }
  
  322             *parentMatch1 = match;
  
  323         }
  
  324         *parentMatch0 = match;
  
  325     }
  
  326     #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  327 
  
  328 
  
  329 
  
  330 
  
  331 
  
  332     #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  333     if (!match.hit)
  
  334     {
  
  335         match.value = nullptr;
  
  336     }
  
  337     return match;
  
  338 }
  
  339 
  
  340 soulng::parser::Match EnumerationParser::EnumConstants(CmajorLexer& lexer, ParsingContext* ctx, sngcm::ast::EnumTypeNode* enumType)
  
  341 {
  
  342     #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  343 
  
  344 
  
  345 
  
  346 
  
  347 
  
  348 
  
  349 
  
  350     #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  351     std::unique_ptr<EnumConstantNode> enumConstant;
  
  352     soulng::parser::Match match(false);
  
  353     soulng::parser::Match* parentMatch0 = &match;
  
  354     {
  
  355         soulng::parser::Match match(false);
  
  356         soulng::parser::Match* parentMatch1 = &match;
  
  357         {
  
  358             int64_t pos = lexer.GetPos();
  
  359             soulng::parser::Match match(true);
  
  360             soulng::parser::Match* parentMatch2 = &match;
  
  361             {
  
  362                 soulng::lexer::Span span = lexer.GetSpan();
  
  363                 soulng::parser::Match match = EnumerationParser::EnumConstant(lexer, ctx, enumType);
  
  364                 enumConstant.reset(static_cast<EnumConstantNode*>(match.value));
  
  365                 if (match.hit)
  
  366                 {
  
  367                     *parentMatch2 = match;
  
  368                 }
  
  369                 else
  
  370                 {
  
  371                     lexer.ThrowExpectationFailure(span, U"enumeration constant");
  
  372                 }
  
  373             }
  
  374             if (match.hit)
  
  375             {
  
  376                 enumType->AddConstant(enumConstant.release());
  
  377             }
  
  378             *parentMatch1 = match;
  
  379         }
  
  380         *parentMatch0 = match;
  
  381     }
  
  382     if (match.hit)
  
  383     {
  
  384         soulng::parser::Match match(false);
  
  385         soulng::parser::Match* parentMatch3 = &match;
  
  386         {
  
  387             soulng::parser::Match match(true);
  
  388             soulng::parser::Match* parentMatch4 = &match;
  
  389             {
  
  390                 while (true)
  
  391                 {
  
  392                     int64_t save = lexer.GetPos();
  
  393                     {
  
  394                         soulng::parser::Match match(false);
  
  395                         soulng::parser::Match* parentMatch5 = &match;
  
  396                         {
  
  397                             soulng::parser::Match match(false);
  
  398                             if (*lexer == COMMA)
  
  399                             {
  
  400                                 ++lexer;
  
  401                                 match.hit = true;
  
  402                             }
  
  403                             *parentMatch5 = match;
  
  404                         }
  
  405                         if (match.hit)
  
  406                         {
  
  407                             soulng::parser::Match match(false);
  
  408                             soulng::parser::Match* parentMatch6 = &match;
  
  409                             {
  
  410                                 soulng::parser::Match match(false);
  
  411                                 soulng::parser::Match* parentMatch7 = &match;
  
  412                                 {
  
  413                                     int64_t pos = lexer.GetPos();
  
  414                                     soulng::parser::Match match(true);
  
  415                                     soulng::parser::Match* parentMatch8 = &match;
  
  416                                     {
  
  417                                         soulng::lexer::Span span = lexer.GetSpan();
  
  418                                         soulng::parser::Match match = EnumerationParser::EnumConstant(lexer, ctx, enumType);
  
  419                                         enumConstant.reset(static_cast<EnumConstantNode*>(match.value));
  
  420                                         if (match.hit)
  
  421                                         {
  
  422                                             *parentMatch8 = match;
  
  423                                         }
  
  424                                         else
  
  425                                         {
  
  426                                             lexer.ThrowExpectationFailure(span, U"enumeration constant");
  
  427                                         }
  
  428                                     }
  
  429                                     if (match.hit)
  
  430                                     {
  
  431                                         enumType->AddConstant(enumConstant.release());
  
  432                                     }
  
  433                                     *parentMatch7 = match;
  
  434                                 }
  
  435                                 *parentMatch6 = match;
  
  436                             }
  
  437                             *parentMatch5 = match;
  
  438                         }
  
  439                         if (match.hit)
  
  440                         {
  
  441                             *parentMatch4 = match;
  
  442                         }
  
  443                         else
  
  444                         {
  
  445                             lexer.SetPos(save);
  
  446                             break;
  
  447                         }
  
  448                     }
  
  449                 }
  
  450             }
  
  451             *parentMatch3 = match;
  
  452         }
  
  453         *parentMatch0 = match;
  
  454     }
  
  455     #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  456 
  
  457 
  
  458 
  
  459 
  
  460 
  
  461     #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  462     if (!match.hit)
  
  463     {
  
  464         match.value = nullptr;
  
  465     }
  
  466     return match;
  
  467 }
  
  468 
  
  469 soulng::parser::Match EnumerationParser::EnumConstant(CmajorLexer& lexer, ParsingContext* ctx, sngcm::ast::EnumTypeNode* enumType)
  
  470 {
  
  471     #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  472 
  
  473 
  
  474 
  
  475 
  
  476 
  
  477 
  
  478 
  
  479     #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  480     Span s = Span();
  
  481     std::unique_ptr<Node> expr = std::unique_ptr<Node>();
  
  482     std::unique_ptr<IdentifierNode> constantId;
  
  483     std::unique_ptr<Node> constantValue;
  
  484     soulng::parser::Match match(false);
  
  485     soulng::parser::Match* parentMatch0 = &match;
  
  486     {
  
  487         soulng::parser::Match match(false);
  
  488         soulng::parser::Match* parentMatch1 = &match;
  
  489         {
  
  490             int64_t pos = lexer.GetPos();
  
  491             soulng::lexer::Span span = lexer.GetSpan();
  
  492             soulng::parser::Match match(true);
  
  493             soulng::parser::Match* parentMatch2 = &match;
  
  494             {
  
  495                 soulng::lexer::Span span = lexer.GetSpan();
  
  496                 soulng::parser::Match match = IdentifierParser::Identifier(lexer);
  
  497                 constantId.reset(static_cast<IdentifierNode*>(match.value));
  
  498                 if (match.hit)
  
  499                 {
  
  500                     *parentMatch2 = match;
  
  501                 }
  
  502                 else
  
  503                 {
  
  504                     lexer.ThrowExpectationFailure(span, U"identifier");
  
  505                 }
  
  506             }
  
  507             if (match.hit)
  
  508             {
  
  509                 s = span;
  
  510             }
  
  511             *parentMatch1 = match;
  
  512         }
  
  513         *parentMatch0 = match;
  
  514     }
  
  515     if (match.hit)
  
  516     {
  
  517         soulng::parser::Match match(false);
  
  518         soulng::parser::Match* parentMatch3 = &match;
  
  519         {
  
  520             soulng::parser::Match match(false);
  
  521             soulng::parser::Match* parentMatch4 = &match;
  
  522             {
  
  523                 soulng::parser::Match match(false);
  
  524                 soulng::parser::Match* parentMatch5 = &match;
  
  525                 {
  
  526                     int64_t save = lexer.GetPos();
  
  527                     soulng::parser::Match match(false);
  
  528                     soulng::parser::Match* parentMatch6 = &match;
  
  529                     {
  
  530                         soulng::parser::Match match(false);
  
  531                         if (*lexer == ASSIGN)
  
  532                         {
  
  533                             ++lexer;
  
  534                             match.hit = true;
  
  535                         }
  
  536                         *parentMatch6 = match;
  
  537                     }
  
  538                     if (match.hit)
  
  539                     {
  
  540                         soulng::parser::Match match(false);
  
  541                         soulng::parser::Match* parentMatch7 = &match;
  
  542                         {
  
  543                             soulng::parser::Match match(false);
  
  544                             soulng::parser::Match* parentMatch8 = &match;
  
  545                             {
  
  546                                 int64_t pos = lexer.GetPos();
  
  547                                 soulng::parser::Match match = ExpressionParser::Expression(lexer, ctx);
  
  548                                 constantValue.reset(static_cast<Node*>(match.value));
  
  549                                 if (match.hit)
  
  550                                 {
  
  551                                     expr.reset(constantValue.release());
  
  552                                     expr->SetFullSpan();
  
  553                                     Span v = expr->GetSpan();
  
  554                                     s.end = expr->GetSpan().end;
  
  555                                     EnumConstantNode*  value = new EnumConstantNode(s, constantId.release(), expr.release());
  
  556                                     value->SetHasValue();
  
  557                                     value->SetStrValue(lexer.GetMatch(v));
  
  558                                     {
  
  559                                         #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  560 
  
  561                                         #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  562                                         return soulng::parser::Match(true, value);
  
  563                                     }
  
  564                                 }
  
  565                                 *parentMatch8 = match;
  
  566                             }
  
  567                             *parentMatch7 = match;
  
  568                         }
  
  569                         *parentMatch6 = match;
  
  570                     }
  
  571                     *parentMatch5 = match;
  
  572                     if (!match.hit)
  
  573                     {
  
  574                         soulng::parser::Match match(false);
  
  575                         soulng::parser::Match* parentMatch9 = &match;
  
  576                         lexer.SetPos(save);
  
  577                         {
  
  578                             soulng::parser::Match match(false);
  
  579                             soulng::parser::Match* parentMatch10 = &match;
  
  580                             {
  
  581                                 int64_t pos = lexer.GetPos();
  
  582                                 soulng::parser::Match match(true);
  
  583                                 if (match.hit)
  
  584                                 {
  
  585                                     {
  
  586                                         #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  587 
  
  588                                         #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  589                                         return soulng::parser::Match(true, new EnumConstantNode(s, constantId.release(), MakeNextEnumConstantValue(s, enumType)));
  
  590                                     }
  
  591                                 }
  
  592                                 *parentMatch10 = match;
  
  593                             }
  
  594                             *parentMatch9 = match;
  
  595                         }
  
  596                         *parentMatch5 = match;
  
  597                     }
  
  598                 }
  
  599                 *parentMatch4 = match;
  
  600             }
  
  601             *parentMatch3 = match;
  
  602         }
  
  603         *parentMatch0 = match;
  
  604     }
  
  605     #ifdef SOULNG_PARSER_DEBUG_SUPPORT
  
  606 
  
  607 
  
  608 
  
  609 
  
  610 
  
  611     #endif // SOULNG_PARSER_DEBUG_SUPPORT
  
  612     if (!match.hit)
  
  613     {
  
  614         match.value = nullptr;
  
  615     }
  
  616     return match;
  
  617 }