Bahasa pengaturcaraan baharu Mash

Selama beberapa tahun saya mencuba tangan saya dalam membangunkan bahasa pengaturcaraan saya sendiri. Saya mahu mencipta, pada pendapat saya, bahasa yang paling mudah, berfungsi sepenuhnya dan mudah yang mungkin.

Dalam artikel ini saya ingin menyerlahkan peringkat utama kerja saya dan, sebagai permulaan, menerangkan konsep bahasa yang dicipta dan pelaksanaan pertamanya, yang sedang saya usahakan.

Biar saya katakan terlebih dahulu bahawa saya menulis keseluruhan projek dalam Free Pascal, kerana... program di atasnya boleh dipasang untuk sejumlah besar platform, dan pengkompil itu sendiri menghasilkan binari yang sangat dioptimumkan (saya mengumpul semua komponen projek dengan bendera O2).

Masa jalan bahasa

Pertama sekali, patut dibincangkan tentang mesin maya yang perlu saya tulis untuk menjalankan aplikasi masa depan dalam bahasa saya. Saya memutuskan untuk melaksanakan seni bina tindanan, mungkin, kerana ia adalah cara yang paling mudah. Saya tidak menemui satu pun artikel biasa tentang cara melakukan ini dalam bahasa Rusia, jadi selepas membiasakan diri dengan bahan bahasa Inggeris, saya duduk untuk mereka bentuk dan menulis basikal saya sendiri. Seterusnya saya akan membentangkan idea dan perkembangan saya yang "maju" dalam perkara ini.

Pelaksanaan tindanan

Jelas sekali, di bahagian atas VM ialah timbunan. Dalam pelaksanaan saya ia berfungsi dalam blok. Pada asasnya ini ialah tatasusunan mudah penunjuk dan pembolehubah untuk menyimpan indeks bahagian atas timbunan.
Apabila ia dimulakan, tatasusunan 256 elemen dicipta. Jika lebih banyak penunjuk ditolak ke tindanan, saiznya meningkat sebanyak 256 elemen seterusnya. Sehubungan itu, apabila mengeluarkan elemen dari timbunan, saiznya diselaraskan.

VM menggunakan beberapa tindanan:

  1. Timbunan utama.
  2. Timbunan untuk menyimpan mata pulangan.
  3. Timbunan pemungut sampah.
  4. Cuba/tangkap/akhirnya sekat timbunan pengendali.

Pemalar dan Pembolehubah

Yang ini mudah sahaja. Pemalar dikendalikan dalam sekeping kod kecil yang berasingan dan tersedia dalam aplikasi masa hadapan melalui alamat statik. Pembolehubah ialah tatasusunan penunjuk saiz tertentu, akses kepada selnya dijalankan oleh indeks - i.e. alamat statik. Pembolehubah boleh ditolak ke bahagian atas timbunan atau dibaca dari sana. Sebenarnya, kerana Walaupun pembolehubah kami pada asasnya menyimpan penunjuk kepada nilai dalam memori VM, bahasa dikuasai dengan bekerja dengan penunjuk tersirat.

Pengumpul sampah

Dalam VM saya ia adalah separa automatik. Itu. pemaju sendiri yang memutuskan bila hendak menghubungi pengutip sampah. Ia tidak berfungsi menggunakan kaunter penunjuk biasa, seperti dalam Python, Perl, Ruby, Lua, dll. Ia dilaksanakan melalui sistem penanda. Itu. apabila pembolehubah bertujuan untuk diberikan nilai sementara, penunjuk kepada nilai ini ditambahkan pada timbunan pemungut sampah. Pada masa hadapan, pengumpul dengan cepat menjalankan senarai penunjuk yang telah disediakan.

Mengendalikan cubaan/tangkap/akhirnya blok

Seperti dalam mana-mana bahasa moden, pengendalian pengecualian adalah komponen penting. Teras VM dibungkus dalam blok try..catch, yang boleh kembali ke pelaksanaan kod selepas menangkap pengecualian dengan menolak beberapa maklumat tentangnya ke dalam tindanan. Dalam kod aplikasi, anda boleh menentukan cuba/tangkap/akhirnya blok kod, menentukan titik masuk pada tangkapan (pengendali pengecualian) dan akhirnya/akhir (hujung blok).

Multithreading

Ia disokong pada peringkat VM. Ia mudah dan senang digunakan. Ia berfungsi tanpa sistem gangguan, jadi kod itu harus dilaksanakan dalam beberapa utas beberapa kali lebih cepat, masing-masing.

Perpustakaan luaran untuk VM

Tidak ada cara untuk melakukannya tanpa ini. VM menyokong import, sama seperti cara ia dilaksanakan dalam bahasa lain. Anda boleh menulis sebahagian daripada kod dalam Mash dan sebahagian daripada kod dalam bahasa ibunda, kemudian memautkannya menjadi satu.

Penterjemah daripada bahasa Mash peringkat tinggi kepada bytecode untuk VM

bahasa perantaraan

Untuk menulis penterjemah dari bahasa kompleks ke dalam kod VM dengan cepat, saya mula-mula membangunkan bahasa perantaraan. Hasilnya adalah tontonan dahsyat seperti pemasang yang tidak ada gunanya untuk dipertimbangkan di sini. Saya hanya akan mengatakan bahawa pada tahap ini penterjemah memproses kebanyakan pemalar dan pembolehubah, mengira alamat statik mereka dan alamat titik masuk.

Seni bina penterjemah

Saya tidak memilih seni bina terbaik untuk pelaksanaan. Penterjemah tidak membina pokok kod, seperti yang dilakukan oleh penterjemah lain. Dia melihat pada permulaan struktur. Itu. jika sekeping kod yang dihuraikan kelihatan seperti "while <condition>:", maka jelas sekali bahawa ini adalah binaan gelung sementara dan perlu diproses sebagai binaan gelung sementara. Sesuatu seperti sarung suis yang kompleks.

Terima kasih kepada penyelesaian seni bina ini, penterjemah ternyata tidak begitu pantas. Walau bagaimanapun, kemudahan pengubahsuaiannya telah meningkat dengan ketara. Saya menambah struktur yang diperlukan lebih cepat daripada kopi saya boleh menyejukkan. Sokongan OOP penuh telah dilaksanakan dalam masa kurang dari seminggu.

Pengoptimuman kod

Di sini, sudah tentu, ia boleh dilaksanakan dengan lebih baik (dan akan dilaksanakan, tetapi kemudian, sebaik sahaja seseorang mencapainya). Setakat ini, pengoptimum hanya tahu cara memotong kod, pemalar dan import yang tidak digunakan daripada pemasangan. Juga, beberapa pemalar dengan nilai yang sama digantikan dengan satu. Itu sahaja.

Bahasa tumbuk

Konsep asas bahasa

Idea utama adalah untuk membangunkan bahasa yang paling berfungsi dan mudah yang mungkin. Saya fikir pembangunan itu mengatasi tugasnya dengan cepat.

Blok kod, prosedur dan fungsi

Semua binaan dalam bahasa dibuka dengan titik bertindih. : dan ditutup oleh pengendali akhir.

Prosedur dan fungsi diisytiharkan sebagai proc dan func, masing-masing. Hujah-hujah disenaraikan dalam kurungan. Semuanya seperti kebanyakan bahasa lain.

Operator pulangan anda boleh mengembalikan nilai daripada fungsi, operator memecahkan membolehkan anda keluar dari prosedur/fungsi (jika ia berada di luar gelung).

Contoh kod:

...

func summ(a, b):
  return a + b
end

proc main():
  println(summ(inputln(), inputln()))
end

Reka Bentuk yang Disokong

  • Gelung: untuk..akhir, sementara..akhir, sehingga..akhir
  • Syarat: jika..[lain..]tamat, tukar..[kes..tamat..][lain..]tamat
  • Kaedah: proc <name>():... end, func <name>():... end
  • Label & pergi: <nama>:, lompat <nama>
  • Penghitungan enum dan tatasusunan malar.

Pembolehubah

Penterjemah boleh menentukannya secara automatik, atau jika pembangun menulis var sebelum mentakrifkannya.

Contoh kod:

a ?= 10
b ?= a + 20

var a = 10, b = a + 20

Pembolehubah global dan tempatan disokong.

OOP

Nah, kami telah sampai ke topik yang paling lazat. Mash menyokong semua paradigma pengaturcaraan berorientasikan objek. Itu. kelas, pewarisan, polimorfisme (termasuk dinamik), pantulan automatik dinamik dan introspeksi (penuh).

Tanpa berlengah lagi, lebih baik berikan contoh kod sahaja.

Kelas yang mudah dan bekerja dengannya:

uses <bf>
uses <crt>

class MyClass:
  var a, b
  proc Create, Free
  func Summ
end

proc MyClass::Create(a, b):
  $a = new(a)
  $b = new(b)
end

proc MyClass::Free():
  Free($a, $b)
  $rem()
end

func MyClass::Summ():
  return $a + $b
end

proc main():
  x ?= new MyClass(10, 20)
  println(x->Summ())
  x->Free()
end

Akan keluaran: 30.

Warisan dan polimorfisme:

uses <bf>
uses <crt>

class MyClass:
  var a, b
  proc Create, Free
  func Summ
end

proc MyClass::Create(a, b):
  $a = new(a)
  $b = new(b)
end

proc MyClass::Free():
  Free($a, $b)
  $rem()
end

func MyClass::Summ():
  return $a + $b
end

class MyNewClass(MyClass):
  func Summ
end

func MyNewClass::Summ():
  return ($a + $b) * 2
end

proc main():
  x ?= new MyNewClass(10, 20)
  println(x->Summ())
  x->Free()
end

Akan keluaran: 60.

Bagaimana pula dengan polimorfisme dinamik? Ya, ini adalah refleksi!:

uses <bf>
uses <crt>

class MyClass:
  var a, b
  proc Create, Free
  func Summ
end

proc MyClass::Create(a, b):
  $a = new(a)
  $b = new(b)
end

proc MyClass::Free():
  Free($a, $b)
  $rem()
end

func MyClass::Summ():
  return $a + $b
end

class MyNewClass(MyClass):
  func Summ
end

func MyNewClass::Summ():
  return ($a + $b) * 2
end

proc main():
  x ?= new MyClass(10, 20)
  x->Summ ?= MyNewClass::Summ
  println(x->Summ())
  x->Free()
end

Akan keluaran: 60.

Sekarang mari kita luangkan sedikit masa untuk introspeksi nilai dan kelas mudah:

uses <bf>
uses <crt>

class MyClass:
  var a, b
end

proc main():
  x ?= new MyClass
  println(BoolToStr(x->type == MyClass))
  x->rem()
  println(BoolToStr(typeof(3.14) == typeReal))
end

Akan output: benar, benar.

Mengenai pengendali tugasan dan petunjuk eksplisit

Operator ?= digunakan untuk menetapkan pembolehubah penunjuk kepada nilai dalam ingatan.
Operator = menukar nilai dalam ingatan menggunakan penunjuk daripada pembolehubah.
Dan sekarang sedikit tentang petunjuk eksplisit. Saya menambahkannya pada bahasa supaya ia wujud.
@<pembolehubah> β€” ambil penunjuk eksplisit kepada pembolehubah.
?<pembolehubah> β€” dapatkan pembolehubah dengan penuding.
@= β€” memberikan nilai kepada pembolehubah dengan penunjuk eksplisit kepadanya.

Contoh kod:

uses <bf>
uses <crt>

proc main():
  var a = 10, b
  b ?= @a
  PrintLn(b)
  b ?= ?b
  PrintLn(b)
  b++
  PrintLn(a)
  InputLn()
end

Akan mengeluarkan: beberapa nombor, 10, 11.

Cuba..[tangkap..][akhirnya..]tamat

Contoh kod:

uses <bf>
uses <crt>

proc main():
  println("Start")
  try:
    println("Trying to do something...")
    a ?= 10 / 0
  catch:
    println(getError())
  finally:
    println("Finally")
  end
  println("End")
  inputln()
end

ΠŸΠ»Π°Π½Ρ‹ Π½Π° Π±ΡƒΠ΄ΡƒΡ‰Π΅Π΅

Saya terus melihat dan melihat GraalVM & Truffle. Persekitaran masa jalan saya tidak mempunyai pengkompil JIT, jadi dari segi prestasi ia kini hanya bersaing dengan Python. Saya berharap saya akan dapat melaksanakan kompilasi JIT berdasarkan GraalVM atau LLVM.

repositori

Anda boleh bermain dengan perkembangan dan mengikuti projek itu sendiri.

Website
Repositori pada GitHub

Terima kasih kerana membaca sehingga akhir jika anda membacanya.

Sumber: www.habr.com

Tambah komen