Sambutan hangat tak terduga yang diberikan oleh publik Habr ke
posting saya tentang kompiler XD Pascal buatan rumah untuk MS-DOS membuat saya berpikir. Apakah tidak mengganggu bahwa proyek amatir, yang saya berikan banyak energi, telah menjadi beban berat bagi saya sejak saat mesin virtual DOS benar-benar menghilang dari Windows? Hasil dari refleksi adalah
kompiler XD Pascal untuk Windows . Mungkin dia kehilangan beberapa pesona nostalgia dan kehilangan kemampuan untuk bekerja secara naif dengan grafis melalui gangguan BIOS. Namun, transisi ke Windows menghembuskan kehidupan baru ke dalam proyek dan membuka jalan ke mimpi lama - kompilasi diri.
Seperti sebelumnya, saya tidak menggunakan alat bantu apa pun untuk pembuatan kompiler otomatis. Keras kepala seperti itu mungkin terlihat aneh, tetapi proyek itu memiliki satu tujuan - kesenangan saya sendiri, dan alat tambahan hanya akan berfungsi sebagai hambatan. Dalam hal ini, kompiler dikembangkan dari awal.

Lima langkah untuk mengkompilasi sendiri di Windows
Layak untuk mengatakan beberapa kata tentang tugas utama yang harus diselesaikan dalam perjalanan dari DOS ke Windows:
Pembentukan header dan bagian dari file yang dapat dieksekusi. Selain deskripsi resmi format Portable Executable, artikel
Membuat PE terkecil yang dapat dieksekusi menjadi bantuan yang sangat baik pada tahap ini. Karena header dan bagian memerlukan alamat prosedur dan variabel yang tepat, dan mereka dapat ditemukan hanya setelah menghitung ukuran kode dan data global, kompilasi harus dilakukan dalam tiga lintasan. Pada pass pertama, grafik panggilan prosedur dibuat dan prosedur "mati" ditandai; di kedua, alamat, kode dan ukuran data dihitung, tajuk diisi; di ketiga, kode dihasilkan. Kunshtuk seperti itu sangat tidak habis-habisnya, terutama mengingat bahwa pada setiap tahap semua tahap kompilasi diulangi lagi, dimulai dengan analisis leksikal. Namun, ini mengarah pada kode sumber yang sangat ringkas untuk kompiler dan tidak memerlukan representasi perantara dari program.
Tambahan: pembuatan kode relocatable saat ini diimplementasikan, kompilasi dilakukan satu-pass.
Generator kode baru. Kompilasi untuk Windows diperlukan untuk mengganti pasangan register segmen-offset dengan register offset 32-bit, serta menghapus (dan menambahkan tempat) awalan untuk mengubah panjang operan (66 jam) dan panjang alamat (67 jam).
Arahan untuk mendeklarasikan fungsi eksternal API Windows. Semua nama fungsi yang dideklarasikan dengan arahan
external
dimasukkan dalam tabel bagian impor file yang dapat dieksekusi. Karena fungsi-fungsi ini memerlukan melewati argumen dari kanan ke kiri, kami harus secara manual membalik urutan argumen dalam deklarasi dan panggilan semua fungsi tersebut. Jadi, kebutuhan untuk inversi melalui kompiler tidak lagi diperlukan. Demi kesederhanaan, semua argumen untuk prosedur dan fungsi dalam XD Pascal dilewatkan sebagai nilai 32-bit; untungnya, aturan ini juga berlaku untuk fungsi Windows API, sehingga interaksi dengan pustaka sistem tidak mempersulit mekanisme untuk meneruskan argumen.
Tambahan: inversi dari urutan argumen fungsi yang diimpor sekarang dilakukan secara otomatis.
Menghapus set dan infix operasi string dari kode sumber. Persyaratan ini terkait dengan tugas kompilasi diri. Perhitungan setiap ekspresi dalam XD Pascal dirancang sehingga semua hasil antara memiliki panjang 32 bit dan disimpan di tumpukan. Untuk string dan set Pascal, pendekatan ini tidak dapat diterima. Lebih tepatnya, itu akan memungkinkan set hingga 32 elemen dalam ukuran, tetapi set tersebut praktis tidak berguna.
Tambahan: dukungan untuk operasi string dan mengatur hingga 256 elemen dalam ukuran sekarang diimplementasikan.
Pembungkus untuk beberapa prosedur. Gagasan kompilasi diri menyebabkan pembungkus panggilan ke beberapa rutinitas di perpustakaan standar. Tanda tangan wrapper adalah sama untuk kasus kompilasi oleh kompiler eksternal (Delphi / Free Pascal) dan kompilasi diri; prosedur yang dibungkus bervariasi. Dengan demikian, semua spesifikasi metode kompilasi dilokalkan dalam beberapa bungkus. Pascal penuh dengan prosedur yang, pada pemeriksaan lebih dekat, ternyata tidak mungkin untuk diterapkan sesuai dengan aturan Pascal itu sendiri:
Read
,
Write
,
Move
, dll. Untuk prosedur yang paling umum, termasuk
Read
dan
Write
, saya membuat pengecualian dan menerapkannya atipikal untuk tata bahasa, tetapi akrab dengan penikmat Pascal. Untuk sebagian besar prosedur non-tipikal lainnya, pembungkus diperlukan. Jadi, XD Pascal tidak sepenuhnya kompatibel dengan Delphi atau Free Pascal, tetapi ini bukan masalah besar, karena Free Pascal sendiri dalam mode kompatibilitas dengan Delphi sebenarnya tetap tidak kompatibel.
Tambahan: dukungan untuk argumen variabel formal yang tidak diketik sekarang diterapkan. Ini memungkinkan membuat prosedur
BlockRead
,
BlockWrite
,
Move
,
FillChar
kompatibel dengan Delphi dan Free Pascal, sehingga secara radikal mengurangi jumlah pembungkus yang diperlukan.
Mengkompilasi Program dengan GUI
Tugas kompilasi diri, meskipun memiliki makna simbolis, tetap terbatas: kompiler adalah program konsol dan karenanya tidak tampak seperti penghuni penuh dunia Windows. Butuh beberapa inovasi lagi dalam cara menyusun program dengan antarmuka jendela:
Arahkan ke compiler untuk mengatur jenis antarmuka. Jenis antarmuka (konsol atau grafis) harus ditentukan dalam bidang header terpisah dari file yang dapat dieksekusi. Seperti yang Anda tahu, dalam Delphi dan Free Pascal untuk ini ada arahan
$APPTYPE
. Arahan
$A
A yang serupa muncul di XD Pascal.
Operasi mengambil alamat prosedur dan fungsi. Dalam Pascal klasik tidak ada petunjuk lengkap untuk prosedur dan fungsi - mereka diganti sampai batas tertentu oleh tipe prosedural. Tipe ini tidak diimplementasikan dalam XD Pascal. Meskipun demikian, masih menerapkan operasi
@
ke prosedur dalam proyek sederhana saya bagi saya tidak berguna. Namun, pemrosesan peristiwa Windows API didasarkan pada panggilan balik, dan di sini transfer alamat prosedur penanganan yang disebut tiba-tiba menjadi kebutuhan yang mendesak.
Tambahan: XD Pascal sekarang menambahkan dukungan penuh untuk jenis prosedural.
Menentukan secara eksplisit nama-nama perpustakaan yang ditautkan. Untuk program konsol, mengimpor fungsi Windows API dari perpustakaan
KERNEL32.DLL
sudah cukup. Program dengan GUI menggunakan
USER32.DLL
,
GDI32.DLL
, dll. Itu perlu untuk memperluas sintaks direktif
external
dengan menambahkan nama perpustakaan di sana.
Demo GUIApa hasilnya
Hasilnya adalah kompiler kompilasi diri yang sangat sederhana untuk Windows. Tidak mungkin membandingkannya dengan benar dengan proyek kolektif yang kuat seperti Free Pascal. Sebaliknya, ia jatuh ke dalam kategori berat
BeRo Tiny Pascal amatir terkenal. Dibandingkan dengan itu, XD Pascal memiliki keuntungan nyata: Tata bahasa Pascal lebih ketat diamati dan kesalahan dikendalikan, ada input / output file yang lengkap, aritmatika angka floating-point didukung, tidak ada ketergantungan pada assembler eksternal, kompilasi program dengan antarmuka jendela diperbolehkan.
Selanjutnya, saya harus berurusan dengan positif palsu dari beberapa antivirus - masalah baru yang saya tidak pikirkan di dunia kecil nyaman MS-DOS. Jika Anda beruntung, XD Pascal akan diperkenalkan, bersama dengan BeRo Tiny Pascal, dalam lokakarya laboratorium tentang kursus desain kompiler di MSTU. N.E. Bauman.