PL/0

**L/0** adalah bahasa pemrograman yang dirancang untuk tujuan pendidikan, khususnya sebagai alat bantu dalam memahami cara kerja kompiler. Bahasa ini dibuat oleh Niklaus Wirth dan pertama kali diperkenalkan dalam bukunya yang terkenal, *Algorithms + Data Structures = Programs* pada tahun 1976.

L/0 memiliki sintaks yang menyerupai bahasa Pascal, tetapi jauh lebih sederhana. Bahasa ini hanya mendukung fitur dasar, seperti: Tidak ada dukungan untuk bilangan real, Hanya beberapa operasi aritmetika sederhana dan Alur kontrol terbatas, hanya menggunakan struktur `if` dan `while``.`Karena sangat terbatas, L/0 tidak cocok untuk membangun aplikasi nyata. Namun, justru kesederhanaannya inilah yang membuatnya ideal sebagai contoh dalam pengajaran: mudah dipahami, dan kompilernya bisa dibuat ringkas dan jelas bagi pemula yang ingin belajar dasar-dasar pemrograman dan pemrosesan bahasa.

## Fitur
Dalam bahasa pemrograman L/0, semua konstanta dan variabel harus dideklarasikan secara eksplisit sebelum digunakan. Bahasa ini hanya mendukung satu tipe data, yaitu integer.

Fungsionalitas L/0 sangat terbatas, dengan dukungan untuk:

* Operator aritmetika dasar (seperti penjumlahan dan pengurangan)
* Operator perbandingan (seperti lebih besar dari, sama dengan, dan sebagainya)
* Satu fungsi khusus bernama `ganjil`, yang digunakan untuk menguji apakah sebuah nilai merupakan bilangan ganjil

Dalam versi asli yang dikembangkan oleh Niklaus Wirth, bahasa ini bahkan tidak memiliki perintah input/output standar. Sebagai gantinya, kompiler secara otomatis mencetak nilai setiap kali suatu variabel mengalami perubahan.

Sebagai contoh, program sederhana dalam L/0 akan memperlihatkan hasilnya langsung saat variabel berubah, tanpa perlu perintah cetak eksplisit. Pendekatan ini bertujuan untuk menjaga bahasa tetap sederhana, dan untuk mempermudah analisis hasil program saat dipelajari oleh pemula.

### Contoh kode skrip

```pascal
var i, s;
begin
  i := 0; s := 0;
  while i < 5 do
  begin
    i := i + 1;
    s := s + i * i
  end
end.
```
memberikan hasil:
```pascal
0
          0
          1
          1
          2
          5
          3
         14
          4
         30
          5
         55
```
Sebagian besar implementasi bahasa pemrograman **L/0** menambahkan **rutinitas input dan output sederhana**, masing-masing satu fungsi untuk **membaca data** dan satu lagi untuk **menampilkan hasil**. Hal ini dilakukan untuk meningkatkan kegunaan bahasa dalam praktik pembelajaran. Struktur kontrol alur dalam L/0 terdiri dari:

* Konstruksi `if-then`, yang memungkinkan percabangan berdasarkan kondisi
* Konstruksi `while-do`, yang memungkinkan pengulangan selama kondisi terpenuhi 
* Prosedur yang ditentukan oleh pengguna, yang memungkinkan pengorganisasian kode menjadi bagian-bagian terpisah

## Tata bahasa penggunaan skrip
Berikut ini adalah aturan sintaksis bahasa model yang didefinisikan dalam bahasa program EBNF:
```ebnf
program = block "." ;

block = [ "const" ident "=" number {"," ident "=" number} ";"]
        [ "var" ident {"," ident} ";"]
        { "procedure" ident ";" block ";" } statement ;

statement = [ ident ":=" expression | "call" ident 
              | "?" ident | "!" expression 
              | "begin" statement {";" statement } "end" 
              | "if" condition "then" statement 
              | "while" condition "do" statement ];

condition = "odd" expression |
            expression ("="|"#"|"<"|"<="|">"|">=") expression ;

expression = [ "+"|"-"] term { ("+"|"-") term};

term = factor {("*"|"/") factor};

factor = ident | number | "(" expression ")";
```
Bahasa pemrograman PL/0 dirancang dengan sintaks yang sederhana, sehingga sangat cocok digunakan dalam pengajaran dasar-dasar pembuatan kompiler. Salah satu keunggulan utamanya adalah kemudahan dalam menulis parser penurunan rekursif, yang membuatnya populer di kalangan mahasiswa dan pengajar di seluruh dunia dalam mata kuliah konstruksi kompiler.

Karena PL/0 hanya menyediakan fitur minimal, para mahasiswa biasanya menghabiskan sebagian besar waktu mereka untuk memperluas kemampuan bahasa dan kompiler yang mereka buat. Pengembangan ini sering dimulai dengan menambahkan struktur kontrol baru seperti REPEAT .. UNTIL. Selanjutnya, mereka dapat mengimplementasikan fitur yang lebih kompleks, seperti kemampuan prosedur untuk menerima parameter, serta menambahkan struktur data seperti array, string, atau tipe data numerik lainnya seperti bilangan titik mengambang. Pendekatan bertahap ini membantu memperdalam pemahaman siswa terhadap prinsip-prinsip desain dan implementasi bahasa pemrograman.

## Penggunaan dalam pendidikan
Artikel utama mengenai kompiler memberikan penghargaan khusus kepada PL/0 karena perannya dalam memperkenalkan sejumlah konsep penting dalam dunia pengembangan kompiler. Beberapa di antaranya mencakup penyempurnaan bertahap, parsing keturunan rekursif, notasi EBNF (Extended Backus-Naur Form), kode-P, dan diagram-T. Bahasa ini telah lama digunakan untuk mendidik mahasiswa dalam menerapkan konsep-konsep tersebut secara langsung, menjadikannya bagian penting dalam kurikulum ilmu komputer di banyak universitas.

Selama tiga dekade terakhir, sebagian besar mata kuliah tentang konstruksi kompiler yang menggunakan PL/0 mengikuti pendekatan klasik yang dirintis oleh Niklaus Wirth. Namun, dalam beberapa tahun terakhir, terjadi pergeseran pendekatan di beberapa institusi. Banyak kursus mulai mengganti metode parsing keturunan rekursif dengan pendekatan berbasis alat bantu klasik ala Unix, seperti lex dan yacc.

Menanggapi perkembangan teknologi dan kebutuhan pembelajaran yang lebih relevan dengan praktik pemrograman modern, kini telah hadir implementasi PL/0 terbaru bernama PL/0 Language Tools. Versi ini mengintegrasikan konsep-konsep modern seperti pemrograman berorientasi objek dan pola desain, serta ditulis menggunakan bahasa skrip populer seperti Python. Pendekatan ini memungkinkan mahasiswa mempelajari dan memahami arsitektur kompiler melalui gaya pemrograman yang lebih kontemporer dan mudah diakses.

## Konstruksi kompiler
Pada Desember 1976, Niklaus Wirth menulis sebuah buku ringkas tentang pembuatan kompiler yang menyertakan kode sumber lengkap dari kompiler PL/0. Aturan sintaks PL/0 yang digunakan dalam buku tersebut diambil dari edisi pertama buku *Compilerbau* karya Wirth. Dalam edisi-edisi berikutnya, Wirth melakukan sejumlah perubahan pada sintaks PL/0 sebagai hasil dari perkembangan penelitiannya. Salah satu perubahan utama adalah penulisan kata kunci seperti *const* dan *procedure* menggunakan huruf kapital, yang membuat PL/0 tampil lebih mirip dengan bahasa Modula-2, bahasa pemrograman lain yang juga dikembangkan oleh Wirth.

Pada waktu yang sama, rekan dan kolaborator Wirth, C. A. R. Hoare, sedang mengembangkan konsep komunikasi antar proses dalam sistem paralel, yang dikenal sebagai *Communicating Sequential Processes* (CSP). Dalam konsep ini, Hoare menggunakan simbol tanda seru (!) dan tanda tanya (?) untuk menandai primitif komunikasi antar proses. Terinspirasi oleh hal ini, Wirth menambahkan kedua simbol tersebut ke dalam bahasa PL/0. Namun, dalam buku tersebut, Wirth tidak menjelaskan makna atau semantik dari simbol-simbol tersebut, meninggalkan pengguna untuk menafsirkan atau mengimplementasikan fungsinya sendiri.

## Contoh kode skrip
Program ini menghasilkan keluaran berupa kuadrat dari angka 1 hingga 10. Dalam praktik pengajaran modern pada mata kuliah konstruksi kompiler, penggunaan simbol tanda seru (!) yang digunakan dalam versi awal PL/0 telah banyak digantikan oleh prosedur standar seperti `WriteLn`. Perubahan ini mencerminkan adaptasi terhadap konvensi pemrograman yang lebih umum dan memudahkan integrasi dengan bahasa-bahasa pemrograman yang lebih dikenal oleh mahasiswa saat ini.
```pascal
VAR x, squ;

PROCEDURE square;
BEGIN
   squ:= x * x
END;

BEGIN
   x := 1;
   WHILE x <= 10 DO
   BEGIN
      CALL square;
      ! squ;
      x := x + 1
   END
END.
```
Program berikut digunakan untuk mencetak bilangan prima dari 1 hingga 100. Dalam sintaks EBNF PL/0, pernyataan keluaran menggunakan simbol tanda seru (!), yang berfungsi sebagai instruksi untuk mencetak nilai ke layar. Dalam implementasi yang lebih modern, simbol ini sering digantikan dengan perintah seperti `WriteLn` agar lebih sesuai dengan gaya pemrograman saat ini. Program ini menjadi contoh umum dalam pembelajaran dasar pemrograman dan konstruksi kompiler karena logikanya sederhana tetapi cukup efektif untuk mendemonstrasikan alur kontrol, penggunaan variabel, dan proses perulangan.
```pascal
const max = 100;
var arg, ret;

procedure isprime;
var i;
begin
	ret := 1;
	i := 2;
	while i < arg do
	begin
		if arg / i * i = arg then
		begin
			ret := 0;
			i := arg
		end;
		i := i + 1
	end
end;

procedure primes;
begin
	arg := 2;
	while arg < max do
	begin
		call isprime;
		if ret = 1 then write arg;
		arg := arg + 1
	end
end;

call primes
```
Contoh berikut berasal dari edisi kedua buku *Compilerbau* karya Niklaus Wirth, yang diterbitkan pada tahun 1986 di Jerman. Buku ini menjadi salah satu referensi penting dalam bidang konstruksi kompiler dan banyak digunakan dalam pengajaran ilmu komputer, khususnya pada bagian yang menjelaskan cara kerja dan implementasi bahasa pemrograman sederhana seperti PL/0.
```pascal
VAR x, y, z, q, r, n, f;

PROCEDURE multiply;
VAR a, b;
BEGIN
  a := x;
  b := y;
  z := 0;
  WHILE b > 0 DO
  BEGIN
    IF ODD b THEN z := z + a;
    a := 2 * a;
    b := b / 2
  END
END;

PROCEDURE divide;
VAR w;
BEGIN
  r := x;
  q := 0;
  w := y;
  WHILE w <= r DO w := 2 * w;
  WHILE w > y DO
  BEGIN
    q := 2 * q;
    w := w / 2;
    IF w <= r THEN
    BEGIN
      r := r - w;
      q := q + 1
    END
  END
END;

PROCEDURE gcd;
VAR f, g;
BEGIN
  f := x;
  g := y;
  WHILE f # g DO
  BEGIN
    IF f < g THEN g := g - f;
    IF g < f THEN f := f - g
  END;
  z := f
END;

PROCEDURE fact;
BEGIN
  IF n > 1 THEN
  BEGIN
    f := n * f;
    n := n - 1;
    CALL fact
  END
END;

BEGIN
  ?x; ?y; CALL multiply; !z;
  ?x; ?y; CALL divide; !q; !r;
  ?x; ?y; CALL gcd; !z;
  ?n; f := 1; CALL fact; !f
END.
```


## Bahasa pemograman Oberon-0
Dalam edisi ketiga dan terakhir bukunya tentang konstruksi kompilator, Niklaus Wirth menggantikan bahasa PL/0 dengan Oberon-0. Bahasa Oberon-0 dirancang dengan kompleksitas yang lebih tinggi dibandingkan PL/0. Bahasa ini mendukung fitur seperti array, record, deklarasi tipe, dan parameter pada prosedur, yang tidak tersedia dalam PL/0. Meskipun penerbit asli buku-buku Wirth, Addison-Wesley, memutuskan untuk menghentikan penerbitannya, Wirth sendiri terus memperbarui dan menerbitkan edisi revisi dari bukunya sejak tahun 2004. Hingga Agustus 2017, revisi terbaru yang tersedia berasal dari bulan Mei 2017.

## Lihat juga

* P-code machine
* City & Guilds Mnemonic Code

## Pranala luar

* Kompiler (.pas file) dari edisi pertama *Compilerbau,* buku ditulis dalam bahasa pemograman Pascal
* Another copy of the compiler di situs Pascal untuk mesin kecil
* Penerjemah dari "Algoritma + Struktur data = Program-program" buku, ditulis dalam bahasa pemograman Pascal Pascal
* Pengembangan suatu PL/0 penyusun gaya berdasarkan 'Konstruksi kompiler' ditulis dalam Mocka (Modul-2 pada Linux)
* Sebuah makalah yang menjelaskan penggunaan of PL/0 di Universitas Rochester
* Halaman beranda dari PL/0 buku referensi, "Algoritma + Struktur data = Program-program"
* http://sourceforge.net/projects/pl0-compiler (ditulis dalam C/C++, penggunaan untuk QT framework)
* https://modernc.org/pl0 (ditulis dalam Go, berjalan di terminal, lintas platform)
* https://github.com/dodobyte/plzero (kompiler yang sangat kecil menghasilkan eksekusi Windows)
* https://github.com/MarcRochkind/pl0compiler (kompiler untuk IBM 701 ditulis dalam C; menghasilkan perakit 701)
* Kategori:PL/0 Tugas yang dilaksanakan di PL/0 di rosettacode.org

## Referensi