1. C++ / Говнокод #27777

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    97. 97
    if (op.size() == 1)
    				{
    					if (op[0].id == LexemID::REGISTER)
    					{
    						if (isSIBbase(registerName2registerId.at( std::get<std::string>(op[0].lexemas))))
    							mnemonic.mnemonics.emplace_back(IndirectAddress{
    								.base = Register(std::get<std::string>(op[0].lexemas))
    								});
    						else
    							mnemonic.mnemonics.emplace_back(IndirectAddress{
    								.index = Register(std::get<std::string>(op[0].lexemas))
    								});
    					}
    					else if (op[0].id == LexemID::LABEL_USE)
    						mnemonic.mnemonics.emplace_back(IndirectAddress{
    							.disp = LabelUse(std::get<std::string>(op[0].lexemas))
    							});
    					else if (op[0].id == LexemID::NUMBER)
    						mnemonic.mnemonics.emplace_back(IndirectAddress{
    							.disp = Constant(std::get<int>(op[0].lexemas))
    							});
    				}
    				else if (op.size() == 3)
    				{
    					if (const auto operation = std::get<std::string>(op[1].lexemas)[0]; operation == '+')
    					{
    						if (op[0].id == LexemID::REGISTER && op[2].id == LexemID::REGISTER)
    						{
    							if (isSIBbase(registerName2registerId.at(std::get<std::string>(op[0].lexemas))))
    								mnemonic.mnemonics.emplace_back(IndirectAddress{
    									.base = Register(std::get<std::string>(op[0].lexemas)),
    									.index = Register(std::get<std::string>(op[2].lexemas))
    									});
    							else
    								mnemonic.mnemonics.emplace_back(IndirectAddress{
    									.base = Register(std::get<std::string>(op[2].lexemas)),
    									.index = Register(std::get<std::string>(op[0].lexemas))
    									});
    						}
    						else if (op[0].id == LexemID::REGISTER && op[2].id == LexemID::NUMBER)
    						{
    							if (isSIBbase(registerName2registerId.at(std::get<std::string>(op[0].lexemas))))
    								mnemonic.mnemonics.emplace_back(IndirectAddress{
    									.base = Register(std::get<std::string>(op[0].lexemas)),
    									.disp = Constant(std::get<int>(op[2].lexemas))
    									});
    							else
    								mnemonic.mnemonics.emplace_back(IndirectAddress{
    									.index = Register(std::get<std::string>(op[0].lexemas)),
    									.disp = Constant(std::get<int>(op[2].lexemas))
    									});
    						}
    						else if (op[0].id == LexemID::REGISTER && op[2].id == LexemID::LABEL_USE)
    						{
    							if (isSIBbase(registerName2registerId.at(std::get<std::string>(op[0].lexemas))))
    								mnemonic.mnemonics.emplace_back(IndirectAddress{
    									.base = Register(std::get<std::string>(op[0].lexemas)),
    									.disp = LabelUse(std::get<std::string>(op[2].lexemas))
    									});
    							else
    								mnemonic.mnemonics.emplace_back(IndirectAddress{
    								.index = Register(std::get<std::string>(op[0].lexemas)),
    								.disp = LabelUse(std::get<std::string>(op[2].lexemas))
    									});
    						}
    					}
    					else if (operation == '*')
    					{
    						if (op[0].id == LexemID::NUMBER && op[2].id == LexemID::REGISTER)
    							mnemonic.mnemonics.emplace_back(IndirectAddress{
    								.base = Register(std::get<std::string>(op[2].lexemas)),
    								.scale = static_cast<uint8_t>(std::get<int>(op[0].lexemas))
    								});
    					}
    				}
    				else if(op.size() == 5)
    				{
    
    					if (op[4].id == LexemID::REGISTER)
    						mnemonic.mnemonics.emplace_back(IndirectAddress{
    							.base  = Register(std::get<std::string>(op[4].lexemas)),
    							.index = Register(std::get<std::string>(op[2].lexemas)),
    							.scale = static_cast<uint8_t>(std::get<int>(op[0].lexemas))
    							});
    					else if (op[4].id == LexemID::NUMBER)
    						mnemonic.mnemonics.emplace_back(IndirectAddress{
    							.index = Register(std::get<std::string>(op[2].lexemas)),
    							.scale = static_cast<uint8_t>(std::get<int>(op[0].lexemas)),
    							.disp = Constant(std::get<int>(op[4].lexemas))
    							});
    					else if (op[4].id == LexemID::LABEL_USE)
    						mnemonic.mnemonics.emplace_back(IndirectAddress{
    							.index = Register(std::get<std::string>(op[2].lexemas)),
    							.scale = static_cast<uint8_t>(std::get<int>(op[0].lexemas)),
    							.disp = LabelUse(std::get<std::string>(op[4].lexemas))
    							});
    ...

    чё к щам близко?

    https://github.com/kcalbSphere/PVC-16/blob/master/pvc-asm/syntaxer.cpp

    Запостил: digitalEugene, 31 Октября 2021

    Комментарии (22) RSS

    • Выравнивание по правой стеночке, как у арабов...
      Персидский код.
      Ответить
    • типичная срань из кучи ифов с каким-то говном
      Ответить
      • ну а как ещё строчку вида 4 * %b + %c + FFh перевести в scale, index, base и disp?
        Ответить
        • Для этого есть так называемые "генераторы лексических анализаторов" ("lexer generators"). А еще в некоторых языках есть "паттерн-матчинг", который можно для такого использовать.

          Руками такую срань лучше не писать.
          Ответить
          • строчка вида 4 * %b + %c + FFh отлексирована в num(4) op(*) reg(b) op(+) reg(c) op(+) num(FFh)
            здесь уже синтаксический разбор проходит.
            паттерн матчинга не существует в плюсах(да и не помог бы он здесь), а объединить выражения никак
            Ответить
            • > строчка вида 4 * %b + %c + FFh отлексирована в num(4) op(*) reg(b) op(+) reg(c) op(+) num(FFh)
              > здесь уже синтаксический разбор проходит.

              Ну так ты ж про перевод строчки спрашивал. Строчку в набор токенов переводиит лексер, выдавая токены. А чтоб токены перевести в некоторую иную хуету - нужен уже парсер.
              Кстати, лексер и парсер можно совместить в одной хуйне.

              > паттерн матчинга не существует в плюсах(да и не помог бы он здесь)

              Эта хрень:
              if (op[0].id == LexemID::REGISTER && op[2].id == LexemID::REGISTER)
              {
              ...
              }
              else if (op[0].id == LexemID::REGISTER && op[2].id == LexemID::NUMBER)
              {
              ...
              }
              else if (op[0].id == LexemID::REGISTER && op[2].id == LexemID::LABEL_USE)
              {
              ...
              }

              в паттерн-матчинг вполне переводится.
              Да и вообще, можно сделать
              if (op[0].id == LexemID::REGISTER)
              {
              	switch(op[2].id)
              	{
              		// тут вся хуйня для вариантов op[2].id
              	}
              }
              Ответить
              • 1k табов будет
                Ответить
                • Я вообще против табов, в своем личном коде я двумя пробелами отступы делаю в основном.
                  Ответить
                  • Вдвое больше байтов нужно для передачи пустого места. Из-за тебя планета умирает! /green (pun intended)
                    Ответить
                  • И правильно, если попытаешься смотреть кот в ненастроенном, то с табами будет выглядеть уродливо
                    Ответить
            • > паттерн матчинга не существует в плюсах

              Через бустоговно (boost::spirit, boost::hana) думаю можно.
              Ответить
    • У меня ощущение, что в моём эмуляторе/асме/дизасме для 8080, написанном почти 20 лет назад, было меньше копипасты...

      Там была хотя бы какая-то попытка сгруппировать команды по "форме" их кодирования.
      Ответить

    Добавить комментарий