В прошлый раз мы разрезали однострочник "Hello, World!" как торт и увидели его слои, от компилятора до процессора 🍰
Давай разберёмся с верхним слоем — компилятором
⚙️ Что это вообще такое
Компилятор — переводчик. Он берёт код, который пишет и понимает человек, и переводит его в форму, которую способна понимать и исполнять машина, а человек там мало что поймёт (да ему и не надо). Отдельно качать компилятор обычно не надо: он приезжает вместе с установкой .NET SDK (набор инструментов для разработки) и работает на этапе сборки, ещё до того, как программа запустится🧩
Кажется, что такой перевод — это очень просто, "просто одну строку сконвертировать в другую, и всё!"👩💼 На самом деле это целый завод с конвейером: несколько фаз, и каждая передаёт результат следующей 🏭
Давай посмотрим, что рождается на выходе каждой🔎
🔤 Фаза 1. Разбор на токены (лексер)
Текст рубится на токены — минимальные значимые кусочки🪓
Результат — плоский список:
Console · . · WriteLine · ( · "Hello, World!" · ) · ;Пока это просто «слова», без понимания, что они значат.
🌳 Фаза 2. Сборка дерева (парсер)
Токены складываются в синтаксическое дерево — оно отражает грамматику: что во что вложено. Упрощённо это выглядит так:
вызов метода
├ что зовём: Console.WriteLine
└ аргумент: "Hello, World!"
Полное дерево, прямо из компилятора — на дикпике 1. Смысла в нём всё ещё нет, это чистая форма
🧠 Фаза 3. Добавление смысла (семантика)
Компилятор проходит по дереву и добавляет узлам смысл — формализует, какой символ и тип за ними стоит. Результат — на дикпике 2. Если при написании кода ошибёшься в имени или типе, то компилятор будет ругаться на это именно на этом этапе
📦 Фаза 4. Генерация (emit)
В конце дерево со смыслом превращается в IL (Intermediate Language, промежуточный переносимый код, но это ещё не машинный код🐁)
Результатом компиляции одной нашей строки станут три инструкции:
ldstr "Hello, World!"
call Console.WriteLine(string)
ret
Они пакуются в сборку — файл .dll
🎩 А теперь фокус
В дереве не было ни класса, ни метода — мы их не писали. Но C# годами требовал каркас:
class Program со статическим методом Main внутри. Если заглянуть в собранный .dll, внутри окажется
Program, а в нём метод <Main>$(string[]).Компилятор дописал каркас за нас, а наш однострочник стал телом этого метода. Причём имя метода специально сделано таким сложным, чтобы к нему нельзя было обратиться из кода🛑
🅰️ Что с этим делать
🟢 Ошибка компиляции может возникнуть на одном из этапов сборки: не закрылась скобка — это парсер, опечатка в имени типа — это семантика
🟢 В результате компиляции получается .dll с IL внутри.
Как IL превратится в настоящие инструкции процессора — узнаем в следующий раз👉
🧑💻dp🥁
#dotnet #csharp #инженерныештучки #heavywednesday


