Membuat bahasa pemrograman dinamis, berorientasi objek, dengan sintaks Bahasa Indonesia yang terinspirasi oleh Ruby, diimplementasikan menggunakan SBCL (Steel Bank Common Lisp).
- Tentukan daftar kata kunci bahasa Indonesia (pemetaan lengkap dari Ruby)
if → jika | end → selesai | def → fungsi else → lain | class → kelas | return → kembali elsif → lainjika | module → modul | self → diri unless → kecuali | do → lakukan | nil → kosong while → selama | begin → mulai | true → benar until → sampai | rescue → selamatkan | false → salah for → untuk | ensure → pastikan | raise → lempar in → dalam | require → butuh | include → sertakan next → lanjut | break → hentikan | super → induk and → dan | or → atau | not → bukan - Definisikan spesifikasi token (identifier, number, string, operator, delimiter)
- Desain format komentar (
#komentar baris,#=...=#komentar blok) - Tentukan simbol-simbol operator (aritmatika, perbandingan, logika, penugasan)
- Implementasi fungsi
tokenize(string)→ daftar token - Kenali: identifier, keyword, integer, float, string, simbol, operator
- Tangani interpolasi string (
"Halo, #{nama}") (lexer + parser + executor) - Tangani heredoc string (
idn-heredocvia registry) - Laporkan kesalahan leksikal dengan nomor baris & kolom
- Tulis unit test untuk setiap jenis token
- Definisikan struktur/node AST (gunakan CLOS classes atau defstruct)
literal-node(nil, benar, salah, integer, float, string, simbol)identifier-node(variabel, konstanta, pemanggilan metode)binary-op-node(+, -, *, /, ==, !=, <, >, dsb.)unary-op-node(!, -)if-node(kondisi, tubuh, cabang-lain)while-node/until-nodefor-node/each-nodefunction-def-node(nama, parameter, tubuh)class-def-node(nama, induk, tubuh)module-def-node(nama, tubuh)call-node(penerima, metode, argumen, blok)assignment-node(target, nilai)array-literal-node/hash-literal-nodeblock-node(parameter, tubuh)return-noderequire-node
- Fungsi bantu untuk membangun dan berjalan di AST
- Implementasi recursive descent parser atau Pratt parser
- Fungsi
parse(tokens)→ AST - Tangani ekspresi dengan presedensi operator yang benar
- Parsing struktur kontrol:
jika/lain/selesai,selama/selesai,untuk/dalam/selesai - Parsing definisi fungsi:
fungsi nama(param) ... selesai - Parsing definisi kelas:
kelas Nama < Induk ... selesai - Parsing definisi modul:
modul Nama ... selesai - Parsing literal array:
[1, 2, 3] - Parsing literal hash:
{kunci => nilai} - Parsing pemanggilan metode dengan blok:
objek.metode(arg) lakukan |x| ... selesai(parser + executor) - Parsing operator penugasan:
=,+=,-=,||= - Laporkan kesalahan sintaks yang baik
- Tulis unit test parser
- Implementasi walker AST: fungsi
eksekusi(ast, lingkungan) - Pilihan strategi eksekusi: B. Interpreter murni — Walk AST dan eksekusi langsung
- Eksekusi ekspresi literal
- Eksekusi operasi biner dan unary
- Evaluasi
jika/kecualiconditional - Evaluasi loop
selama/sampai/untuk - Eksekusi
kembali(return) - Eksekusi pemanggilan fungsi dan metode
- Implementasi rantai lingkungan (lexical scope)
- Fungsi
lingkungan-cari(lingkungan, nama) - Fungsi
lingkungan-tetapkan(lingkungan, nama, nilai) - Dukungan closure: lingkungan menangkap variabel luar
- Lingkungan global untuk konstanta dan definisi level atas
- Lingkungan lokal per pemanggilan fungsi / blok
- Definisikan root class
Objek(semua adalah objek) - Definisikan
Kelassebagai metaclass - Sistem pewarisan tunggal dengan
induk(super) - Metode lookup: diri → kelas → induk → ... → Objek
- Konstruktor
awali(initialize) - Akses variabel instans
@nama - Akses variabel kelas
@@nama - Variabel global
$nama - Metode
diri(self) -
indukuntuk memanggil metode parent - Mixins:
sertakan(include) —idn-sertakandisrc/objek.lisp - Visibilitas metode:
umum,pribadi,terlindung(infrastruktur siap) - Aksesor atribut:
baca_atribut,tulis_atribut,akses_atribut(idn-definisikan-aksesor)
- Parsing blok inline
lakukan |param| ... selesai(parser:parse-block-after-call) - Objek
Procuntuk blok yang dapat disimpan - Keyword
lambdauntuk fungsi anonim - Keyword
hasilkan(yield) untuk memanggil blok - Metode
.panggilpada Proc/Lambda - Konversi blok implisit ke Proc melalui
&blok(via executor block passing)
- Kelas
Angka(Numeric) abstrak - Kelas
BilanganBulat(Integer) — di-back oleh SBCL integer - Kelas
BilanganPecahan(Float) — di-back oleh SBCL float - Operasi aritmatika:
+,-,*,/,%(modulo),**(pangkat) - Metode:
.abs,.ke_atas(ceil),.ke_bawah(floor),.bulatkan(round) - Metode:
.ganjil?,.genap?,.positif?,.negatif?,.nol? - Iterasi:
3.kali lakukan |i| ... selesai(via block passing ke metode kali) - Range:
1.sampai(10),1...10
- Kelas
Teks(String) - Interpolasi:
"Nama saya #{nama}"(lexer + parser + executor) - Konkatenasi:
+, penggandaan:* - Metode:
.panjang,.besar(upcase),.kecil(downcase),.kapital - Metode:
.potong,.ganti,.pisah,.berisi? - Metode:
.kosong?,.awalan?,.akhiran?,.lucuti,.balik - Metode:
.==,.ke_integer,.ke_simbol - Heredoc:
<<~TEKS ... TEKS - Encoding UTF-8 (didukung SBCL secara default)
- Kelas
Larik(Array) - Literal:
[1, 2, 3] - Akses:
larik[0] - Metode:
.panjang,.kosong? - Metode:
.dorong(push),.ambil(pop),.sisipkan,.hapus_pada - Iterasi:
.setiap,.peta(map),.pilih(select),.tolak(reject) - Metode:
.pertama,.terakhir,.gabung(join) - Metode:
.urutkan(sort),.balik(reverse),.unik(uniq) - Metode:
.jumlah,.termasuk?,.ke_teks
- Kelas
Kamus(Hash) - Literal:
{kunci => nilai} - Akses:
.ambil(kunci),.atur(kunci, nilai) - Metode:
.kunci,.nilai,.ukuran - Iterasi:
.setiap_pasangan(each_pair) - Metode:
.gabung(merge),.punya_kunci?,.hapus - Metode:
.kosong?,.ke_teks - Default value / default proc (
idn-buat-kamusdengan parameter opsional)
- Kelas
Simbol(Symbol) - Literal:
:nama - Konversi ke/dari Teks:
.to_s,.nama - Perbandingan:
.==
- Kelas
Rentang(Range) - Literal inklusif:
1..10 - Literal eksklusif:
1...10 - Iterasi range (via
untuk .. dalam) - Metode:
.berisi?(cover?/include?) - Metode:
.ke_larik,.to_s,.awal,.akhir,.eksklusif?
-
tulis,cetak— output ke stdout -
baca— input dari stdin - Kelas
Berkas(File):.buka,.baca,.baca_semua,.tulis,.tulis_baris,.tutup,.nama - Blok File:
Berkas.buka("path") lakukan |f| ... selesai(via block passing) - Direktori:
dir_sekarang,dir_daftar,dir_ada?,dir_buat
- Strip:
.lucuti(sudah ada di Teks) - Padding:
.isi_kiri,.isi_kanan,.tengah - Format string:
"Halo ~@!".format(nama)di Teks
- Kelas
Waktu(Time) -
waktu_sekarang - Metode:
.tahun,.bulan,.hari,.jam,.menit,.detik - Metode:
.to_s,.+detik,.- - Format tanggal:
.format(fmt)miripstrftime
- Modul enumerasi diterapkan ke Larik
- Metode:
.suntik/.lipat(inject/reduce) - Metode:
.semua?,.ada? - Metode:
.hitung - Metode:
.kelompokkan(group_by) - Metode:
.urutkan_menurut(sort_by),.tak_ada?
-
json_urai(teks)— parse JSON → objek IDN -
json_hasilkan(objek)— objek IDN → JSON string - Tanpa dependensi eksternal (parser & serializer murni CL)
- Kelas dasar
Eksepsi(Exception) - Sintaks:
mulai ... selamatkan NamEksepsi => e ... selesai -
pastikan(ensure) untuk cleanup -
lain(else) untuk kasus tanpa eksepsi -
lempar(raise) untuk melempar eksepsi - Backtrace yang informatif (nama tipe AST + lokasi di pesan error)
- Eksepsi bawaan:
KesalahanArgumen,KesalahanNama,KesalahanTipeTanpaMetode,KesalahanSintaks,KesalahanIO
- Read-Eval-Print Loop interaktif (
make replataubin/idn) - Multi-line input (deteksi
selesaiyang belum ditutup) - History dengan readline/editline (
rlwrap bin/idn) - Auto-completion (
:complete <awal>— saran keyword, fungsi, variabel) - Pretty-print hasil evaluasi (angka, teks, larik, kamus, dll.)
- Mode debug / inspeksi (
:debug,:inspeksi <var>, breakpoints) - Variabel khusus:
_(hasil terakhir),_galat(error terakhir)
- Fungsi
butuh "nama_file"untuk load file.idn - Path pencarian: direktori kerja,
./lib,~/.idn/lib - Flag
-e 'kode'untuk eksekusi inline - Flag
-cuntuk check sintaks saja - Shebang support:
#!/usr/bin/env idn
- Buat executable binary
idndari SBCL image (make build) - Script
Makefileataubuild.lispuntuk build - Instalasi via
make install - Dokumentasi CLI (
idn --help,idn --version)
- Test runner kustom dengan macro
uji,uji-token,uji-parse - Test suite untuk lexer (81 tes)
- Test suite untuk parser (63 tes)
- Test suite untuk eksekutor (40 tes)
- Test suite untuk tipe data bawaan (67 tes)
- Test suite untuk stdlib (17 tes)
- Test suite untuk eksepsi (6 tes)
- Test suite untuk REPL (5 tes)
- Total: 279 tes, semua lulus
-
halo_dunia.idn— program sederhana -
faktorial.idn— rekursi -
fibonacci.idn— iterasi & rekursi -
kelas.idn— OOP: kelas, pewarisan -
blok.idn— lambda -
larik.idn— manipulasi larik & enumerasi -
kamus.idn— manipulasi hash -
berkas.idn— operasi file I/O -
eksepsi.idn— penanganan kesalahan -
web_server.idn— HTTP server sederhana (src/stdlib/webserver.lisp)
- JIT compilation via SBCL native compiler
- Inline caching untuk method lookup
- Constant folding & dead code elimination
- Pattern matching
cocokkan/kasus/ketika(src/stdlib/fase8.lisp) - Keyword arguments:
fungsi(nama:, umur: 0) - Splat operator:
*arg,**opsi - Refinements / monkey patching
- Metaprogramming:
definisi_metode,definisi_kelas(src/stdlib/fase8.lisp) - Method
hilang_metode(method_missing) -
const_missing - Threading / konkurensi
- Fibers / coroutines
- LSP (Language Server Protocol) — via formatter/linter built-in
- Formatter kode (
idn fmt—src/stdlib/formatter.lisp) - Linter (
idn lint—src/stdlib/formatter.lisp) - Debugger interaktif
- Profiler
- Documentation generator (seperti RDoc/YARD)
- FFI untuk memanggil fungsi C (
src/stdlib/fase8.lisp) - Embedding: panggil SBCL Common Lisp dari kode IDN
- Compile to binary standalone executable (
make buildviabuild.lisp)
IDN/
├── bin/
│ └── idn # Entry point executable (SBCL script)
├── src/
│ ├── packages.lisp # Definisi package CL
│ ├── utils.lisp # Fungsi utilitas
│ ├── lexer.lisp # Tokenizer
│ ├── ast.lisp # Definisi AST node
│ ├── parser.lisp # Parser
│ ├── lingkungan.lisp # Environment/scope
│ ├── eksekutor.lisp # AST executor/interpreter
│ ├── objek.lisp # Sistem objek/kernel
│ ├── blok.lisp # Blok, Proc, Lambda
│ ├── eksepsi.lisp # Exception system
│ ├── angka.lisp # Kelas angka (Integer, Float)
│ ├── teks.lisp # Kelas String
│ ├── larik.lisp # Kelas Array
│ ├── kamus.lisp # Kelas Hash
│ ├── simbol.lisp # Kelas Symbol
│ ├── rentang.lisp # Kelas Range
│ └── loader.lisp # File loader / 'butuh'
├── stdlib/
│ ├── io.idn # I/O built-in
│ ├── teks_util.idn # String utilities
│ ├── waktu.idn # Time/Date
│ ├── enumerasi.idn # Enumerable module
│ └── json.idn # JSON handler
├── test/
│ ├── test_runner.lisp # Test framework & runner
│ ├── test_lexer.lisp
│ ├── test_parser.lisp
│ ├── test_eksekutor.lisp
│ ├── test_objek.lisp
│ └── test_stdlib.lisp
├── contoh/
│ ├── halo_dunia.idn
│ ├── faktorial.idn
│ ├── fibonacci.idn
│ ├── kelas.idn
│ ├── blok.idn
│ ├── larik.idn
│ ├── kamus.idn
│ ├── berkas.idn
│ └── eksepsi.idn
├── dok/
│ ├── sintaks.md # Referensi sintaks lengkap
│ ├── stdlib.md # Dokumentasi stdlib
│ └── tutorial.md # Tutorial pengguna
├── Makefile # Build script
├── build.lisp # SBCL build script (dump executable)
├── idn.asd # ASDF system definition
├── task.md # File ini
└── README.md
- Bahasa Indonesia standar: Gunakan KBBI sebagai acuan kata kunci. Hindari kata serapan yang ambigu.
- Inspirasi Ruby: Prioritaskan "programmer happiness" — sintaks harus bersih, ekspresif, dan intuitif.
- Pendekatan Kompilasi: Strategi awal adalah kompilasi AST ke kode Common Lisp (seperti cara Clojure di JVM). Setiap node AST menghasilkan kode CL yang ekuivalen, lalu dievaluasi oleh SBCL. Ini memberi kita garbage collection, optimisasi, dan runtime yang matang secara gratis.
- Konvensi penamaan file: Gunakan
.idnsebagai ekstensi file bahasa ini. - Nama bahasa: IDN (singkatan dari IDonesiaN), diucapkan "idian".
Yang harus selesai untuk rilis awal:
- Tokenizer & Parser lengkap
- Eksekusi ekspresi, kondisional, loop, fungsi
- Kelas, pewarisan, mixin
- Tipe data: Angka, Teks, Larik, Kamus, Simbol
- Blok & lambda
- REPL yang berfungsi
- Contoh program bekerja