Bahasa mini adalah bahasa imperatif sederhana yang dibangun sepanjang jalur compiler, mulai dari v1 yang hanya memuat pernyataan, ekspresi, dan tipe dasar, hingga versi lanjutan yang menambahkan fungsi, closure, dan struktur data. Topik ini menetapkan rujukan kanonis bahasa mini v1 lewat berkas bahasa_kursus.md, yang akan dipakai ulang sepanjang pembangunan compiler. Pembaca memperoleh satu titik rujukan untuk sintaksis dan semantik bahasa yang akan dikompilasi.
Mengapa spesifikasi ditetapkan lebih dulu#
Tata bahasa dan semantik bahasa mini ditetapkan sebelum lexer, parser, atau codegen ditulis. Spesifikasi menjadi kontrak yang mengikat setiap modul: lexer harus menerima semua bentuk yang diizinkan tata bahasa, parser harus membangun AST yang merepresentasikan struktur sintaksis, dan codegen harus menghasilkan bytecode yang menjalankan semantik pernyataan. Tanpa spesifikasi, keputusan desain tersebar di seluruh kode, dan perubahan satu modul dapat merusak modul lain secara diam-diam.
Bahasa mini sengaja dibuat kecil, sekitar tiga puluh aturan produksi pada v1, sehingga setiap tahap pipeline dapat diilustrasikan dengan kode yang ditinjau dalam satu sesi. Bentuk umum bahasa mengambil subset Lua dan Python: pernyataan let untuk pengikatan, print untuk keluaran, if dan while untuk kontrol alur, serta blok dengan kurung kurawal. Pilihan bentuk ini bukan estetika semata, melainkan kontrak yang menentukan apa yang harus dikenal lexer.
Tipe dasar dan struktur leksikal#
Lima tipe dasar tersedia pada v1: int untuk bilangan bulat, float untuk bilangan desimal, bool untuk kebenaran, string untuk teks, dan nil untuk kekosongan. Bilangan bulat dan desimal dapat dicampur dalam ekspresi aritmetika, dengan hasil mengikuti tipe yang lebih luas, sehingga int + float menghasilkan float. Operator logika and dan or menggunakan evaluasi pendek, sehingga operan kanan tidak dievaluasi bila hasil sudah dapat ditentukan dari operan kiri.
Struktur leksikal bahasa mini mirip subset Lua dan Python. Identifier diawali huruf atau garis bawah, lalu diikuti huruf, angka, atau garis bawah. Komentar diawali // hingga akhir baris, sebagaimana banyak bahasa dengan sintaksis turunan C. String diapit tanda kutip ganda dan tidak memuat escape sequence pada v1, dengan fitur ini ditunda agar implementasi lexer tetap sederhana. Daftar kata kunci yang dilarang dipakai sebagai identifier meliputi let, print, if, else, while, true, false, nil, and, dan or.
Tata bahasa dan presedensi#
Tata bahasa lengkap v1 dituliskan dalam notasi BNF pada berkas bahasa_kursus.md di samping topik ini. Berkas itu menjadi rujukan kanonis sepanjang pembangunan compiler, sehingga pembaca dianjurkan membaca isinya sebagai kontrak masukan bagi setiap tahap pipeline. Ringkasan tata bahasa diperlihatkan sebagai satu blok berikut, dengan urutan produksi yang merefleksikan presedensi operator dari yang paling longgar ke yang paling lekat.
# Bahasa Mini v1: Spesifikasi Ringkas
Dokumen ini adalah rujukan kanonis untuk bahasa mini yang dibangun sepanjang
jalur compiler. Versi v1 mencakup pernyataan, ekspresi, dan tipe dasar.
Fitur lanjutan (fungsi, closure, struktur data, kelas) ditambahkan pada versi
sesudah v1 dan akan diperbarui di sini.
## Leksikal
- Identifier: huruf atau garis bawah diikuti huruf, angka, atau garis bawah.
- Bilangan bulat: deret digit, misalnya `42`.
- Bilangan desimal: deret digit, titik, deret digit, misalnya `3.14`.
- String: deret karakter diapit tanda kutip ganda, misalnya `"halo"`.
- Komentar: diawali `//` hingga akhir baris.
- Kata kunci: `let`, `print`, `if`, `else`, `while`, `true`, `false`, `nil`,
`and`, `or`.
- Operator: `+ - * /`, `< <= > >= == !=`, `!`, `=`.
- Pemisah: `( ) { }`.
## Tipe dasar
| Tipe | Nilai | Contoh |
|---|---|---|
| int | bilangan bulat | `42` |
| float | bilangan desimal | `3.14` |
| bool | kebenaran | `true`, `false` |
| string | teks | `"halo"` |
| nil | kekosongan | `nil` |
Tipe `int` dan `float` dapat dicampur dalam ekspresi aritmetika, dan hasil
mengikuti tipe yang lebih luas, sehingga `int + float` menghasilkan `float`.
## Tata bahasa (BNF)
Notasi: `*` berarti nol atau lebih, `?` berarti nol atau satu, dan `|` berarti
pilihan. Karakter dalam tanda kutip adalah terminal literal.
```
program := statement* EOF
statement := let_stmt
| print_stmt
| if_stmt
| while_stmt
| block_stmt
| expr_stmt
let_stmt := "let" IDENT "=" expression
print_stmt := "print" expression
if_stmt := "if" expression block ("else" block)?
while_stmt := "while" expression block
block_stmt := "{" statement* "}"
expr_stmt := expression
expression := logic_or
logic_or := logic_and ("or" logic_and)*
logic_and := equality ("and" equality)*
equality := comparison (("==" | "!=") comparison)*
comparison := term (("<" | "<=" | ">" | ">=") term)*
term := factor (("+" | "-") factor)*
factor := unary (("*" | "/") unary)*
unary := ("-" | "!") unary
| primary
primary := NUM_INT
| NUM_FLOAT
| STRING
| "true"
| "false"
| "nil"
| IDENT
| "(" expression ")"
```
Presedensi operator dari yang paling lekat: unary `!` dan `-`, lalu `* /`,
lalu `+ -`, lalu `< <= > >=`, lalu `== !=`, lalu `and`, lalu `or`. Seluruh
operator biner berasosiatif kiri.
## Pernyataan
- `let IDENT = expression` mengikat nilai ke nama dalam scope saat ini.
Pernyataan ulang dengan nama yang sama menimpa binding sebelumnya.
- `print expression` mengevaluasi ekspresi dan mencetak hasilnya ke keluaran
standar, diikuti baris baru.
- `if expression block else block?` mengevaluasi kondisi. Bila bernilai
`true`, blok pertama dijalankan. Bila `false` dan blok `else` ada, blok
itu dijalankan.
- `while expression block` mengulang blok selama kondisi bernilai `true`.
- `{ statement* }` adalah blok yang membuka scope baru.
- `expression` sebagai pernyataan mengevaluasi ekspresi dan membuang hasilnya.
## Ekspresi
Ekspresi aritmetika `+ - * /` beroperasi pada `int` dan `float`. Operator
perbandingan `< <= > >= == !=` menghasilkan `bool`. Operator logika `and`
dan `or` mengevaluasi operan kiri lebih dulu dan menggunakan evaluasi pendek:
`and` berhenti bila operan kiri `false`, dan `or` berhenti bila operan kiri
`true`. Operator unary `-` membalik tanda numerik, dan `!` membalik `bool`.
## Contoh program
```
// Menjumlahkan 1 sampai 10
let n = 10
let hasil = 0
let i = 1
while i <= n {
hasil = hasil + i
i = i + 1
}
print hasil
```
Keluaran: `55`.
```
// Percabangan dengan string
let nama = "Ali"
let dewasa = true
if dewasa {
print nama
} else {
print "anonim"
}
```
Keluaran: `Ali`.
## Yang belum ada di v1
Hal-hal berikut belum tersedia di v1 dan akan ditambahkan pada versi lanjutan:
- Fungsi dan closure (modul runtime).
- Tipe data gabungan: array dan map (modul runtime).
- Pattern matching (modul pengerjaan proyek).
- Penanganan error terstruktur (modul pengerjaan proyek).Produksi expression := logic_or menetapkan titik masuk parse ekspresi, kemudian turun ke logic_or, logic_and, equality, comparison, term, factor, unary, dan primary. Struktur berlapis ini menangani presedensi secara langsung: aturan yang lebih dalam mengikat lebih kuat, sedangkan aturan yang lebih luar mengikat lebih longgar. Asosiativitas kiri dinyatakan dengan rekursi kiri pada level yang sama, misalnya term := factor (("+" | "-") factor)*, sehingga 1 - 2 - 3 dikelompokkan sebagai (1 - 2) - 3. Penanganan presedensi lewat struktur tata bahasa akan menjadi titik utama pada modul parsing.
Posisi v1 dalam jalur#
Bahasa mini v1 sengaja tidak memuat fungsi, closure, atau struktur data. Ketiganya ditambahkan pada modul runtime, setelah pipeline dasar (lexer, parser, analisis semantik, IR, dan codegen) selesai dibangun. Membaca topik-topik pipeline tanpa menguasai v1 akan menyulitkan pembaca, karena setiap modul mengasumsikan tata bahasa pada bahasa_kursus.md sebagai kontrak masukan. Modul runtime dan modul pengerjaan proyek akan memperbarui bahasa_kursus.md terlebih dahulu, kemudian menulis implementasi yang memenuhi spesifikasi baru, sehingga berkas itu tetap menjadi sumber kebenaran tunggal sepanjang jalur.
Ringkasan#
- Bahasa mini v1 memuat pernyataan, ekspresi, dan tipe dasar, dengan tata bahasa yang dituliskan dalam BNF pada
bahasa_kursus.md. - Lima tipe dasar adalah
int,float,bool,string, dannil, denganintdanfloatdapat dicampur dalam ekspresi aritmetika. - Tata bahasa disusun berlapis untuk menangani presedensi operator, dari
oryang paling longgar hingga unary yang paling lekat. - Fitur lanjutan (fungsi, closure, struktur data) ditunda ke modul runtime, dengan
bahasa_kursus.mdsebagai rujukan yang akan diperbarui.
Referensi#
- Crafting Interpreters — Bob Nystrom — Buku daring gratis dengan sintaks bahasa Lox yang menjadi inspirasi bentuk bahasa mini pada jalur ini.
- Lua 5.4 Reference Manual — Lua.org — Sintaks dan semantik Lua yang dijadikan rujukan subset pernyataan dan ekspresi.
- Backus–Naur form — Wikipedia — Notasi BNF yang dipakai untuk menuliskan tata bahasa bahasa mini.