Ketika seseorang menulis bahasa pemrograman baru, apa yang mereka tulis DALAM?

162

Maafkan ketidaktahuan saya. Saya mencoba-coba dalam PHP dan membuat saya basah kuyup browsing SO, dan merasa terdorong untuk mengajukan pertanyaan yang saya telah bertanya-tanya selama bertahun-tahun:

Ketika Anda menulis bahasa pemrograman yang sama sekali baru, di mana Anda menulisnya ?

Ini mungkin kedengarannya konyol bagi Anda semua programmer, yang sangat saya hormati, tetapi itu hal yang membingungkan bagi saya. Apa yang kamu kerjakan? Katakan pada diri sendiri Hari ini saya akan menciptakan bahasa baru! dan kemudian jalankan ... Notepad? Apakah semua kompiler dibangun di atas bahasa yang sudah ada sebelumnya, sedemikian rupa sehingga membuat orang terganggu sehingga bisa memetakan semua bahasa pemrograman yang pernah dibuat pada satu pohon bercabang raksasa yang akhirnya mendarat di ... Saya tidak tahu, sesuatu yang tua?

Dengan kecerdasan lemah saya, saya menemukan ini menarik ... Tolong, mendidik saya!

Drew
sumber

Jawaban:

193

Ini bukan pertanyaan bodoh. Ini pertanyaan yang sangat bagus.

Seperti yang sudah dijawab, jawaban singkatnya adalah, "Bahasa lain."

Nah itu mengarah ke beberapa pertanyaan menarik? Bagaimana jika ini adalah bahasa pertama yang ditulis untuk perangkat keras khusus Anda? Masalah yang sangat nyata bagi orang yang bekerja pada perangkat yang disematkan. Seperti yang sudah dijawab "sebuah bahasa di komputer lain". Bahkan beberapa perangkat tertanam tidak akan pernah mendapatkan kompiler, program mereka akan selalu dikompilasi di komputer yang berbeda.

Tetapi Anda dapat mendorongnya kembali lebih jauh. Bagaimana dengan program pertama yang pernah ditulis?

Nah kompiler pertama untuk "bahasa tingkat tinggi" akan ditulis dalam apa yang disebut "bahasa assembly". Bahasa assembly adalah bahasa di mana setiap instruksi dalam bahasa berhubungan dengan satu instruksi ke CPU. Bahasa tingkat sangat rendah dan sangat verbose dan sangat padat karya untuk menulis.

Tetapi bahkan menulis bahasa rakitan memerlukan program yang disebut assembler untuk mengubah bahasa rakitan menjadi "bahasa mesin". Kami kembali lebih jauh. Perakit pertama ditulis dalam "kode mesin". Suatu program yang seluruhnya terdiri dari angka-angka biner yang merupakan korespondensi satu-ke-satu langsung dengan bahasa baku komputer itu sendiri.

Tapi itu masih belum berakhir. Bahkan file dengan angka mentah saja masih perlu diterjemahkan. Anda masih perlu memasukkan angka-angka mentah dalam file ke komputer.

Yah percaya atau tidak komputer awal memiliki deretan switch di depan mereka. Anda membalik sakelar hingga mewakili angka biner, lalu Anda menjentikkan sakelar lain dan yang memuat nomor tunggal itu ke dalam memori komputer. Kemudian Anda terus menjentikkan beralih hingga Anda memuat program komputer minimal yang bisa membaca program dari file disk atau kartu punch. Anda menjentik sakelar lain dan memulai program yang berjalan. Ketika saya pergi ke universitas di tahun 80-an saya melihat komputer yang memiliki kapasitas itu tetapi tidak pernah diberi tugas memuat dalam program dengan switch.

Dan bahkan lebih awal dari itu, program komputer harus dikabel dengan papan plug !

Matius
sumber
20
+1, saya pikir jawaban ini sangat sesuai dengan semangat pertanyaan.
stderr
30
Saya pernah mengambil kelas Assembler II dan prof bertanya mengapa kami memilih pilihan. Saya mencari jawaban yang lucu: "karena saya menginginkan A. yang mudah." Pikir saya punya jawaban terbaik tetapi kami memiliki pabrik Honeywell di kota dan orang berikutnya berkata, "Saya menulis kode mikro sepanjang hari dan saya ingin belajar bahasa tingkat tinggi."
T.Rob
3
Saya sangat merekomendasikan Kode: Bahasa Tersembunyi dari Perangkat Keras dan Perangkat Lunak Komputer . Ini pada dasarnya mencakup bahan yang sama dengan jawaban ini, mulai dari tabung hampa udara hingga kompiler untuk bahasa tingkat tinggi.
MatrixFrog
Komputer telah berevolusi seperti halnya manusia, walaupun dalam waktu yang relatif sangat kecil.
Gaurav Ojha
Sekarang ini akan menjadi komentar yang tidak konstruktif, tetapi harus ditulis ... ini adalah jawaban cemerlang yang brilian dalam segala bentuk, bentuk, dan informasi :-)
Lukáš Řádek
23

Jawaban paling umum adalah C. Sebagian besar bahasa diimplementasikan dalam C atau dalam hibrida C dengan callback dan "lexer" seperti Flex dan generator parser seperti YACC . Ini adalah bahasa yang digunakan untuk satu tujuan - untuk menggambarkan sintaks dari bahasa lain. Kadang-kadang, ketika datang ke bahasa yang dikompilasi, mereka pertama kali diimplementasikan dalam C. Kemudian versi bahasa pertama digunakan untuk membuat versi baru, dan seterusnya. (Seperti Haskell .)

Prof. Falken
sumber
1
Beberapa bahasa ditulis dalam assembler, seperti picolisp. ( blog.kowalczyk.info/article/picoLisp-Arc-before-Arc.html )
Prof. Falken
1
Bagaimana dengan program lex / yacc (flex / bison)? Apakah suplemen ini dianggap untuk membuat bahasa dalam C?
Dave
1
Apakah Anda punya sesuatu untuk membuktikan jawaban yang paling umum adalah C?
RichardOD
Saya mulai memeriksa daftar di sini: google.com/Top/Computers/Programming/Languages/Open_Source Kemudian saya menutup jendela editor saya secara tidak sengaja sekitar 10 bahasa, dan kehilangan motivasi untuk melanjutkan. Bagaimanapun, sekitar setengah sejauh ini diimplementasikan dalam C dan sisanya kebanyakan bootstrap untuk diri mereka sendiri.
Prof. Falken
3
Saya pikir Anda harus menyebutkan Lex / Yacc (atau alternatif). Orang biasanya tidak mulai menulis bahasa dalam C, melainkan dengan lexer dan parser yang kemudian didukung dengan kode C.
Steve Rowe
14

Banyak bahasa yang bootstrap- yang ditulis sendiri . Mengenai mengapa Anda ingin melakukan ini, sering kali merupakan ide yang baik untuk memakan makanan anjing Anda sendiri .

Artikel wikipedia yang saya rujuk membahas masalah ayam dan telur . Saya pikir Anda akan menemukannya cukup menarik.

RichardOD
sumber
5
Yang tidak mungkin ketika Anda baru memulai.
Michael Borgwardt
1
Ya- jelas. Tetapi banyak bahasa ditulis dengan cara ini begitu memungkinkan. Saya ingin menunjukkan ini seperti yang tidak dimiliki orang lain, dan saya merasa ini adalah poin penting.
RichardOD
+1 untuk menggunakan istilah bootstrap. Sangat menarik bahwa Anda harus mengkompilasi kompiler Anda dua kali. Pertama kali jelas dengan kompiler telanjang-tulang yang Anda miliki dan kedua kalinya dengan kompiler yang baru saja Anda buat. Katakanlah Anda menambahkan pengoptimalan ke kompiler Anda. Kompiler yang Anda buat dapat menghasilkan kode dengan optimisasi tersebut, tetapi itu sendiri tidak menjalankan kode yang dioptimalkan sampai Anda mengkompilasinya lagi dengan kompilator optimisasi.
Les
@ Les- Ya bootstrap adalah konsep yang menarik.
RichardOD
2
Komentar acak di sini. Jawaban untuk pertanyaan kuno tentang siapa yang lebih dulu (ayam atau telur) adalah ayam yang lebih dulu. Alasannya adalah bahwa untuk mereproduksi / mereplikasi sesuatu, Anda harus terlebih dahulu memiliki reproduksi / replikator untuk melakukan reproduksi / replikasi.
SpicyWeenie
10

Cukup banyak bahasa apa pun, meskipun menggunakan satu yang cocok untuk bekerja dengan grafik dan struktur data kompleks lainnya akan membuat banyak hal lebih mudah. Kompiler produksi sering ditulis dalam C atau C ++ untuk alasan kinerja, tetapi bahasa seperti OCaml, SML, Prolog, dan Lisp bisa dibilang lebih baik untuk membuat prototipe bahasa.

Ada juga beberapa "bahasa kecil" yang digunakan dalam desain bahasa. Lex dan yacc digunakan untuk menentukan sintaks dan tata bahasa, misalnya, dan mereka mengkompilasi ke C. (Ada port untuk bahasa lain, seperti ocamllex / ocamlyacc, dan banyak alat serupa lainnya.)

Sebagai kasus khusus, dialek Lisp baru sering dibangun di atas implementasi Lisp yang ada, karena mereka dapat mendukung sebagian besar infrastruktur yang sama. Menulis juru bahasa Skema dapat dilakukan dalam Skema di bawah halaman kode, di mana orang dapat dengan mudah menambahkan fitur baru.

Pada dasarnya, kompiler hanyalah program yang membaca sesuatu dan menerjemahkannya ke sesuatu yang lain - mengonversi sumber LaTeX ke DVI, mengubah kode C menjadi perakitan dan kemudian ke bahasa mesin, mengubah spesifikasi tata bahasa menjadi kode C untuk pengurai, dll. Perancangnya menentukan struktur format sumber (parsing), apa arti struktur tersebut, cara menyederhanakan data (mengoptimalkan), dan jenis output yang akan dihasilkan. Penerjemah membaca sumber dan menjalankannya secara langsung. (Penerjemah biasanya lebih mudah untuk menulis, tetapi jauh lebih lambat.)

sepeda diam
sumber
4

Sebenarnya Anda dapat menulis dalam hampir semua bahasa yang Anda suka. Tidak ada yang mencegah Anda menulis kompiler C di Ruby. "Yang harus Anda lakukan adalah mengurai program dan memancarkan kode mesin yang sesuai. Jika Anda dapat membaca / menulis file, bahasa pemrograman Anda mungkin sudah cukup.

Jika Anda memulai dari awal pada platform baru, Anda dapat melakukan kompilasi silang: menulis kompiler untuk platform baru Anda, yang berjalan di Jawa atau secara native di x86. Kembangkan di PC Anda dan kemudian transfer program ke platform target baru Anda.

Kompiler yang paling dasar mungkin Assembler dan C.

ziggystar
sumber
Namun, bahasa "apa pun" ini harus mendukung panggilan rekursif. Kalau tidak, mengimplementasikan penganalisis sintaks dan pengurai akan menjadi tantangan nyata.
2
Jika Anda memilih bahasa yang tidak cocok untuk suatu tugas, itu salah Anda sendiri. Ini dapat terjadi untuk proyek apa pun, bukan hanya kompiler / juru bahasa.
ziggystar
4

"Menulis bahasa pemrograman baru" secara teknis tidak melibatkan kode apa pun. Itu hanya datang dengan spesifikasi untuk bagaimana bahasa Anda dan bagaimana cara kerjanya. Setelah Anda tahu seperti apa bahasa Anda, Anda dapat menulis penerjemah dan juru bahasa untuk benar-benar membuat bahasa Anda "berfungsi".

Seorang penerjemah memasukkan suatu program dalam satu bahasa dan mengeluarkan program yang setara dalam bahasa lain. Seorang penerjemah menginput suatu program dalam beberapa bahasa dan menjalankannya.

Sebagai contoh, kompiler C biasanya menerjemahkan kode sumber C (bahasa input) ke program bahasa assembly (bahasa output). Assembler kemudian mengambil program bahasa assembly dan menghasilkan bahasa mesin. Setelah Anda memiliki hasil, Anda tidak perlu penerjemah untuk menjalankan program Anda. Karena sekarang Anda memiliki program bahasa mesin, CPU bertindak sebagai juru bahasa.

Banyak bahasa diimplementasikan secara berbeda. Sebagai contoh, javacadalah penerjemah yang mengubah kode sumber Java ke bytecode JVM. JVM adalah interpreter [1] yang menjalankan bytecode Java. Setelah Anda menjalankan javacdan mendapatkan bytecode, Anda tidak perlu javaclagi. Namun, kapan pun Anda ingin menjalankan program, Anda membutuhkan JVM.

Fakta bahwa penerjemah tidak perlu dijaga untuk menjalankan suatu program adalah apa yang memungkinkan untuk "bootstrap" bahasa Anda tanpa membuatnya akhirnya berjalan "di atas" lapisan dan lapisan bahasa lain.

[1] Sebagian besar JVM melakukan terjemahan di belakang layar, tetapi mereka tidak benar-benar penerjemah karena antarmuka ke JVM bukanlah "bahasa input -> bahasa keluaran".

Kannan Goundan
sumber
3

Secara umum Anda dapat menggunakan bahasa apa saja yang Anda suka. PHP ditulis dalam bahasa C, misalnya. Jika Anda tidak memiliki akses ke kompiler apa pun, Anda harus menggunakan bahasa assembly dan mengompilasinya ke kode mesin dengan tangan.

Kaivosukeltaja
sumber
2
Anda tidak perlu mengkompilasi kode mesin. itu adalah bahasa asli CPU menurut definisi.
Stu Thompson
1
Benar. Yang ingin saya katakan adalah "kompilasi kode mesin dari bahasa assembly atau sesuatu yang serupa dengan tangan". Saya bisa saja salah, tapi saya kira beberapa orang cukup mengetikkan kode sebagai biner / hex langsung.
Kaivosukeltaja
2

Banyak bahasa yang pertama ditulis dalam bahasa lain yang tersedia dan kemudian diimplementasikan kembali dengan sendirinya dan di-bootstrap seperti itu (atau hanya mempertahankan implementasi dalam bahasa asing, seperti PHP dan perl), tetapi beberapa bahasa, seperti assembler pertama dikompilasi dengan tangan ke kode mesin seperti C-compiler pertama dikompilasi dengan tangan ke assembly.

Saya sudah tertarik dengan bootstrap sejak saya membacanya. Untuk mempelajari lebih lanjut, saya mencoba melakukannya sendiri dengan menulis superset BF saya sendiri, yang saya sebut EBF , dengan sendirinya. versi pertama EBF memiliki 3 primitif ekstra dan saya mengompilasi biner pertama. Saya menemukan ritme dua langkah ketika melakukannya. Saya menerapkan fitur dalam bahasa saat ini dalam satu rilis dan memiliki rilis manis di mana saya menulis ulang kode untuk memanfaatkan fitur yang diimplementasikan. Bahasa itu cukup ekspresif untuk digunakan untuk membuat penerjemah LISP .

Saya memiliki versi tangan yang dikompilasi bersama dengan sumber di tag rilis pertama dan kode ini cukup kecil. Versi terakhir adalah 12 kali lebih besar dalam ukuran dan kode dan memungkinkan untuk kode yang lebih kompak sehingga kompilasi dengan tangan versi saat ini akan sulit untuk mendapatkan yang benar.

Edmund Grimley Evans melakukan sesuatu yang mirip dengan bahasa HEX-nya

Salah satu hal menarik tentang melakukan ini sendiri adalah Anda memahami mengapa ada beberapa hal seperti itu. Kode saya adalah produk jika penyesuaian tambahan kecil dan sepertinya lebih berkembang daripada dirancang dari awal. Saya ingat itu ketika membaca kode hari ini yang saya pikir terlihat agak aneh.

Sylwester
sumber
1

Biasanya dengan bahasa pemrograman tujuan umum yang cocok untuk pengembangan sistem, misalnya C, Haskell, ML, Lisp, dll., Tetapi daftar opsinya panjang. Juga, biasanya dengan beberapa bahasa khusus domain untuk implementasi bahasa, yaitu generator penganalisa parser dan leksikal, bahasa perantara seperti LLVM , dll. Dan mungkin beberapa skrip shell, kerangka kerja pengujian, dan sistem konfigurasi bangun, misalnya autoconf.

james woodyatt
sumber
1

Sebagian besar kompiler adalah wriiten C atau ac seperti program jika tidak c maka lang lang adalah cara untuk pergi Namun ketika menulis lang baru dari awal dan Anda tidak memiliki lib makro atau kode sumber dari bahasa prototipe Anda harus mendefinisikan fungsi Anda sendiri Sekarang dalam Bahasa Apa? Anda hanya dapat menulis Formulir "kode sumber yang disebut psedocode ke mesin itu terlihat seperti tata bahasa bnf dari object lang terstruktur berorientasi objek seperti Fortran basic algo lisp. Jadi gambar menulis kode silang yang menyerupai salah satu sintaks bahasa ini. Itu kode psedo

chris anderson
sumber
1
Saya tidak percaya kode psedo seharusnya dapat dibaca oleh mesin
Richard Tingle
0

Biner lebih lanjut, atau operasi perakitan harus diterjemahkan ke dalam fungsi, itulah pekerjaan assembler / kompiler, kemudian ke objek, dari data dan fungsi, jika Anda tidak memiliki file sumber untuk melihat "bagaimana fungsi objek ini harus diwakili dalam Anda implementasi bahasa, Maka Anda harus mengenali "melihat" menerapkan, atau menentukan fungsi, prosedur, dan struktur data Anda sendiri, Yang membutuhkan banyak pengetahuan, Anda perlu bertanya pada diri sendiri apa fungsi. Pikiran Anda kemudian menjadi simulasi bahasa. Pisahkan ini programmer Master dari yang lain.

pengguna3093481
sumber
0

Saya juga punya pertanyaan ini beberapa bulan yang lalu. Dan saya membaca beberapa artikel dan menonton beberapa video yang membantu saya mulai menulis bahasa saya sendiri yang disebut soft. Belum lengkap tapi saya belajar banyak hal dari perjalanan ini.

Hal dasar yang harus Anda ketahui adalah bagaimana kompiler bekerja ketika harus mengeksekusi cuplikan kode. Kompiler memiliki banyak fase seperti analisis leksikal, penganalisa semantik, AST (Pohon Sintaks Abstrak) dll.

Apa yang saya lakukan dalam bahasa baru saya dapat ditemukan di sini - http://www.singhajit.com/writing-a-new-programming-language/

Jika Anda menulis bahasa untuk pertama kalinya maka semuanya adalah yang terbaik dan Anda masih memiliki jalan panjang.

Ajit Singh
sumber
0

Apa bahasa pemrograman secara umum?

bahasa pemrograman hanyalah cara untuk berbicara dengan komputer. berbicara kasar pada awalnya karena komputer hanya dapat memahami nol dan satu (karena fakta bahwa komputer terbuat dari transistor sebagai saklar yang hanya dapat mengambil dua keadaan, kami menyebut dua keadaan ini 0 dan 1) dan bekerja dengan 0,1 sulit untuk kita sebagai manusia sehingga para ilmuwan komputer memutuskan untuk melakukan pemetaan satu-ke-satu dari setiap instruksi dalam biner (0,1) ke bentuk yang lebih dapat dibaca manusia yang mereka sebut bahasa assembly.

misalnya jika kita memiliki instruksi seperti:

11001101

dalam pertemuan itu akan disebut:

LOAD_A 15

yang berarti memuat konten register a ke lokasi memori 15. seperti yang saya katakan itu hanya sebuah konvensi seperti memilih 0 dan 1 untuk dua status transistor atau apa pun di komputer. dengan cara ini memiliki program dengan 50 instruksi, mengingat bahasa assembly akan lebih mudah. sehingga pengguna akan menulis kode rakitan dan beberapa program (assembler dalam kasus ini) akan menerjemahkan kode-kode tersebut menjadi instruksi biner atau bahasa mesin sebagaimana mereka menyebutnya.

tetapi kemudian dengan komputer yang diperbaiki setiap hari ada ruang untuk program yang lebih rumit dengan instruksi lebih banyak, katakanlah 10.000.

dalam hal ini pemetaan satu-ke-satu seperti perakitan tidak akan berfungsi, jadi bahasa pemrograman tingkat tinggi lainnya dibuat. mereka mengatakan misalnya jika untuk hubungan dengan perangkat I / O untuk mencetak sesuatu pada layar yang dibuat oleh pengguna membutuhkan sekitar 80 instruksi, mari kita lakukan sesuatu di sini dan kita dapat mengemas semua kode ini ke dalam satu perpustakaan dan menyebutnya sebagai contoh printf dan juga membuat program lain yang dapat menerjemahkan printf ini di sini ke kode perakitan terkait dan dari sana perakitan akan melakukan sisanya. jadi mereka menyebutnya kompiler.

jadi sekarang setiap pengguna yang ingin hanya mencetak sesuatu di layar dia tidak perlu menulis semua instruksi dalam biner atau rakitan dia cukup ketik printf ("sesuatu") dan semua program seperti kompiler dan assembler akan melakukan sisanya. sekarang nanti kode lain yang lebih panjang akan dikemas dengan cara yang sama hanya untuk memfasilitasi pekerjaan orang lain seperti yang Anda lihat bahwa Anda bisa menyederhanakan ribuan baris kode menjadi satu kode dalam python dan mengemasnya untuk penggunaan orang lain.

jadi katakanlah Anda telah mengemas banyak kode berbeda dalam python dan membuat modul (libray, paket atau apa pun yang Anda ingin menyebutnya) dan Anda memanggil modul itu mgh (hanya nama saya). sekarang katakanlah kita telah membuat mgh ini entah bagaimana, siapa pun yang mengatakan:

import mgh
mgh.connect(ip,port.data)...

dapat dengan mudah terhubung ke server jauh dengan ip dan nomor port yang ditentukan dan mengirim data sesudahnya (atau sesuatu seperti itu). sekarang orang bisa melakukan semuanya dengan menggunakan satu baris tunggal, tetapi yang terjadi adalah banyak kode dieksekusi yang telah diambil dari file mgh. dan pengemasannya bukan untuk mempercepat proses eksekusi tetapi lebih memudahkan pekerjaan programmer lain. jadi di sini jika seseorang ingin menggunakan kode Anda terlebih dahulu ia harus mengimpor file dan kemudian penerjemah python akan mengenali semua kode di dalamnya dan sehingga bisa menafsirkan kode.

sekarang jika Anda ingin membuat bahasa pemrograman dan Anda ingin menjalankannya, pertama perlu terjemahan, misalnya katakanlah Anda membuat program yang dapat memahami sintaks dan mengubahnya menjadi c, dalam hal ini setelah diterjemahkan ke c, sisanya akan diurus, oleh c compiler, lalu assembler, linker, .... meskipun Anda harus membayar harga menjadi lebih lambat karena harus dikonversi ke c terlebih dahulu.

sekarang satu hal lain yang dapat Anda lakukan adalah membuat program yang dapat menerjemahkan semua kode ke bahasa assembly yang sama seperti apa yang terjadi dengan c tetapi dalam hal ini program dapat melakukannya secara langsung dan dari sana sisanya akan dilakukan oleh linker. kita tahu bahwa program ini disebut kompiler.

jadi yang saya bicarakan adalah bahwa, satu-satunya kode yang dipahami oleh sistem adalah 0,1, jadi entah bagaimana Anda harus mengonversi sintaks Anda menjadi itu, sekarang di sistem operasi kami banyak program berbeda seperti assembler, linker dan ... have telah dibuat untuk memberi tahu Anda bahwa jika Anda dapat mengubah kode Anda menjadi perakitan, mereka dapat menangani sisanya atau seperti yang saya katakan Anda bahkan dapat menggunakan kompiler bahasa pemrograman lain dengan mengubah kode Anda ke bahasa itu.

Mgh Gh
sumber