Bahasa pemrograman berbahasa Indonesia dengan interpreter, compiler VM, dan bytecode resmi.
IDScript / IDS = I[n]D[onesian] Script atau ringkasnya I[n]D[o] Script.
Mulai Cepat • CLI • Format File • Sintaks • VM • Lisensi
| Info | Nilai |
|---|---|
| Pembuat | Elang MRJ |
| GitHub | Elang-elang |
elangmuhamad888@gmail.com |
|
| Repository | https://github.com/Elang-elang/IDScript |
| Pendahulu | Indonesian Script / IS |
| Status | Prototype / pre-alpha |
| Python | >=3.13 |
Latar Belakang Singkat
IDScript lahir sebagai kelanjutan dari Indonesian Script atau IS, sebuah proyek bahasa pemrograman berbahasa Indonesia yang sebelumnya dibuat sebagai prototype dan kemudian terbengkalai. IS membuktikan bahwa sintaks pemrograman dapat dibuat lebih dekat dengan istilah Indonesia, tetapi proyek tersebut belum memiliki struktur compiler, runtime, dan format bytecode yang cukup rapi untuk dilanjutkan sebagai bahasa yang lebih stabil.
IDScript meneruskan gagasan itu dengan fondasi baru: grammar Lark, AST, interpreter normal, compiler VM resmi, format module .idsm, format compiled bytecode .idsc, builtin runtime, dan CLI publik bernama idscript.
Instalasi Lokal
python -m pip install -e .Dengan dependency pengembangan:
python -m pip install -e .[dev]Program Pertama
fungsi utama(): Angka {
println("Halo dari IDScript");
kembalikan 0;
}
Jalankan:
idscript main.idsFormat utama:
idscript <file> {-m|--module,-c|--bytecode,--both} <outputFile>Mode Interpreter
Tanpa flag compile, idscript menjalankan interpreter normal dan tidak membuat .idsm atau .idsc.
idscript program.idsEntrypoint default adalah utama. Entrypoint lain dapat dipilih dengan --main.
idscript program.ids --main jalankanMode Module `.idsm`
idscript program.ids -m build/program
idscript program.ids --module build/program.idsmJika outputFile tidak punya suffix, CLI otomatis memakai .idsm.
Mode Bytecode `.idsc`
idscript program.ids -c build/program
idscript program.ids --bytecode build/program.idscMode ini menulis .idsc saja dan tidak membuat .idsm sebagai side effect.
Mode Both
idscript program.ids --both build/programOutput:
build/program.idsm
build/program.idsc
Menjalankan Bytecode
File .ids, .idsm dan .idsc dapat diberikan langsung ke CLI.
idscript build/program.idscMode REPL
Tanpa argumen file, idscript masuk ke REPL interaktif dengan syntax highlighting via prompt_toolkit + Pygments.
idscriptSetiap input harus diakhiri ;. Ekspresi akan langsung dievaluasi, statement akan dieksekusi.
Informasi lebih lanjut: README IDSRepl
| Format | Fungsi |
|---|---|
.ids |
Source IDScript yang ditulis manusia. |
.idsm |
IDScript Module, format module VM yang masih deskriptif/readable. |
.idsc |
IDScript Compiled, bytecode final yang opcode-nya dikodekan. |
Alur Compile
program.ids -> program.idsm -> program.idsc -> VM
Contoh:
idscript app.ids --module app.idsm
idscript app.ids --bytecode app.idsc
idscript app.idscCatatan versi: Format .idsm/.idsc lawas (sebelum penambahan opcode MAKE_FUNCTION) tidak kompatibel dengan compiler/VM saat ini. Jika mengalami error "Opcode VM ... belum diimplementasikan", rebuild module dengan compiler terbaru.
| Bentuk Import | Resolusi Path |
|---|---|
dari "./mod.ids" impor ... |
Relatif ke file pemanggil. |
dari "../mod.ids" impor ... |
Relatif ke file pemanggil. |
dari "iterasi.ids" impor ... |
Folder builtin IDScript/builtins. |
dari "atribut.ids" impor ... |
Folder builtin IDScript/builtins. |
dari "./math.ids" impor { var tambah, konstan VERSI };
dari "./math.ids" impor { var tambah sebagai plus };
dari "iterasi.ids" impor { var panjang, var Daftar };
Bagian ini dibuat sebagai referensi cepat. Buka bagian yang dibutuhkan saja.
Tipe Bawaan
| Tipe IDScript | Makna Runtime |
|---|---|
Teks |
String |
Angka |
Integer |
Float |
Float |
Boolean |
Boolean |
Kosong |
kosong / None |
Apapun |
Nilai bebas |
var nama: Teks = "Budi";
var umur: Angka = 20;
var rasio: Float = 1.5;
var aktif: Boolean = benar;
var nihil: Kosong = kosong;
var bebas: Apapun = [1, "dua", benar];
Komentar
// komentar satu baris
/*
komentar banyak baris
*/
Konstanta `KONSTANTA`
KONSTANTA NILAI: Angka = 10;
publik KONSTANTA VERSI: Teks = "0.1.0";
privat KONSTANTA RAHASIA: Teks = "internal";
Catatan:
KONSTANTAhanya ada di top-level.publikberarti dapat diekspor dari module.- Default visibility adalah privat.
Variabel `var` dan Final `final`
var nilai: Angka = 1;
nilai = nilai + 1;
final total: Angka = 100;
Optional type:
var mungkin: ?Angka = kosong;
Return, Throw, Break, Continue
fungsi ambil(): Angka {
kembalikan 7;
}
fungsi gagal(): Teks {
kesalahan "terjadi kesalahan";
}
fungsi hitung(): Angka {
var total: Angka = 0;
untuk (var angka dari dalam [1, 2, 3, 4]) {
jika (angka == 2) { lanjutkan; }
jika (angka == 4) { berhentikan; }
total = total + angka;
}
kembalikan total;
}
Fungsi
Deklarasi fungsi bernama:
fungsi tambah(a: Angka, b: Angka): Angka {
kembalikan a + b;
}
fungsi kali(final a: Angka, final b: Angka): Angka {
kembalikan a * b;
}
publik fungsi utama(): Angka {
kembalikan tambah(2, 3);
}
Fungsi Generik (type parameter):
fungsi identitas<T>(nilai: T): T {
kembalikan nilai;
}
fungsi utama(): Angka {
kembalikan identitas<Angka>(5);
}
Fungsi Ekspresi / Anonymous / Lambda (ExprFunc):
fungsi utama(): Angka {
var kali: Apapun = fungsi(a: Angka, b: Angka): Angka {
kembalikan a * b;
};
kembalikan kali(3, 4); // 12
}
Fungsi ekspresi dapat ditangkap di variabel, dijadikan argumen, dikembalikan, dan juga mendukung generic params:
fungsi utama(): Angka {
var fn: Apapun = fungsi<T>(x: T): T {
kembalikan x;
};
kembalikan fn<Angka>(5); // 5
}
Catatan:
- Entrypoint default adalah
fungsi utama(). - Interpreter normal memperketat
utamaagar tidak menerima argumen dan mengembalikanAngkaatau?Angka. - Fungsi ekspresi memiliki nama sintetis
'<anonim>'untuk keperluan stack trace. - Fungsi ekspresi didukung penuh di interpreter normal (runtime compiler) dan VM bytecode compiler.
If / Elif / Else
fungsi status(nilai: Angka): Teks {
jika (nilai > 80) {
kembalikan "baik";
} namun jika (nilai > 60) {
kembalikan "cukup";
} jika tidak {
kembalikan "kurang";
}
}
Negasi memakai bukan.
fungsi cek(flag: Boolean): Angka {
jika (bukan flag) {
kembalikan 0;
}
kembalikan 1;
}
Di VM, jika (bukan x) dikompilasi ke TO_BOOL lalu POP_JUMP_IF_TRUE.
Loop `selama` dan `untuk`
fungsi sampai_lima(): Angka {
var angka: Angka = 0;
selama (angka < 5) {
angka = angka + 1;
}
kembalikan angka;
}
fungsi jumlah(): Angka {
var total: Angka = 0;
untuk (var angka dari dalam [1, 2, 3]) {
total = total + angka;
}
kembalikan total;
}
Destructuring target:
fungsi jumlah_pasangan(): Angka {
var total: Angka = 0;
untuk (var (a, b) dari dalam [[1, 2], [3, 4]]) {
total = total + a + b;
}
kembalikan total;
}
Try / Catch / Else / Finally
fungsi aman(): Angka {
var nilai: Angka = 0;
coba {
kesalahan 5;
} tangkap (e) {
nilai = 5;
} jika tidak {
nilai = 99;
} diakhiri {
nilai = nilai + 1;
}
kembalikan nilai;
}
Semantik mengikuti model Python:
- Blok
cobadijalankan lebih dulu. - Blok
tangkapberjalan jika ada error. - Blok
jika tidakberjalan hanya jika tidak ada error. - Blok
diakhiriselalu berjalan, termasuk sebelumkembalikankeluar dari blokcoba.
Catatan VM:
- VM resmi sudah mendukung
coba/tangkap/jika tidak/diakhirimelalui opcodeSETUP_TRY. - Handler pertama menangani error yang dilempar oleh
kesalahanatau exception runtime.
Switch / Match `pilah`
fungsi pilih(x: Angka): Teks {
pilah (x) {
kasus 1:
kembalikan "satu";
kasus 2:
kembalikan "dua";
kasus bawaan:
kembalikan "lain";
}
}
Pattern sequence:
fungsi total_data(): Angka {
var total: Angka = 0;
pilah ([1, 2, 3]) {
kasus [kepala, ...ekor]:
total = kepala + ekor[0] + ekor[1];
}
kembalikan total;
}
Type Alias `tipe`
tipe ID = Angka;
tipe Nama = Teks;
fungsi ambil_id(): ID {
kembalikan 7;
}
Dynamic alias:
tipe Kotak<T> = daftar<T>;
var angka: Kotak<Angka> = [1, 2, 3];
Antarmuka `antarmuka`
antarmuka User {
nama: Teks,
umur: Angka,
}
fungsi ambil_umur(user: User): Angka {
kembalikan user["umur"];
}
Struktur, Turunan, Implementasi, dan Sifat
Struktur:
struktur Orang {
publik nama: Teks,
privat umur: Angka,
}
Turunan:
struktur Makhluk {
publik nama: Teks,
}
struktur Orang {
publik umur: Angka,
} turunan dari Makhluk;
Implementasi metode:
implementasi Orang {
publik metode sapa(ini: Orang): Teks {
kembalikan "Halo " + ini.nama;
}
}
Sifat / trait:
sifat BisaSapa {
metode sapa(ini: Orang): Teks;
}
implementasi BisaSapa untuk Orang {
publik metode sapa(ini: Orang): Teks {
kembalikan ini.nama;
}
}
Aturan penting:
- Field default privat.
- Duplicate field saat turunan menghasilkan error.
- Duplicate method saat turunan menghasilkan error.
- Tidak ada override implicit.
- Trait memvalidasi nama argumen, tipe argumen, dan return type.
Enum
Unit variant:
enum Gender {
publik Pria,
publik Wanita,
}
Tuple variant:
enum Data {
publik Nomor(Angka),
publik Pasangan(Teks, Angka),
}
Struct variant:
enum Event {
publik Login { nama: Teks, umur: Angka },
}
Discriminant variant:
enum Kode {
publik Oke = 200,
publik Gagal = 500,
}
Metode enum:
implementasi Kode {
publik metode nilai(ini: Apapun): Angka {
kembalikan ini.value;
}
}
Expression
Literal:
var teks: Teks = "halo";
var angka: Angka = 10;
var pecahan: Float = 3.14;
var flag: Boolean = benar;
var kosong_nilai: Kosong = kosong;
List dan kamus:
var angka: daftar<Angka> = [1, 2, 3];
var user: kamus<Teks, Apapun> = {"nama": "Budi", "umur": 20};
Call, attribute, dan index:
println("Halo");
var nama: Teks = user.nama;
var pertama: Angka = [1, 2, 3][0];
Operator:
var hasil: Angka = 1 + 2 * 3;
var pangkat: Angka = 2 ** 3;
Boolean dan comparison:
jika (benar dan bukan salah) {
println("oke");
}
jika (2 didalam [1, 2, 3]) {
println("ada");
}
identifikasi dan info:
var angka: Angka = 7;
var salin: Angka = identifikasi angka;
jika (info angka == "Angka") {
println("ini angka");
}
Hasil dari info atau identifikasi mencangkup
| Nama | Penjelasan |
|---|---|
Teks |
berisi string atau sebuah teks |
Angka |
berisi integer atau angka bulat |
Float |
berisi float atau angka desimal |
Boolean |
berisi kondisi benar atau salah |
Daftar |
berisi list atau daftar |
Kamus |
berisi dictionary atau kamus |
Fungsi |
berisi fungsi atau metode |
Struktur |
berisi struktur dari objek struktur |
Antarmuka |
berisi tipe kamus dari objek tipe |
Tipe |
berisi objek tipe |
Objek |
berisi objek yang tak terdefinisi |
Kosong |
berisi kekosongan |
Type Annotation Lanjutan
var mungkin: ?Angka = kosong;
var angka: daftar<Angka> = [1, 2, 3];
var data: kamus<Teks, Angka> = {"a": 1};
var operasi: fungsi<(Angka, Angka): Angka>;
var hasil_operasi: hasil<Angka, Teks>;
var nilai: <Angka, Teks> = 1;
var mode: <"dev", "prod"> = "dev";
Buka contoh
tipe Nama = Teks
struktur Orang {
publik nama: Nama,
publik umur: Angka,
}
sifat BisaSapa {
metode sapa(ini: Orang): Teks;
}
implementasi BisaSapa untuk Orang {
publik metode sapa(ini: Orang): Teks {
kembalikan "Halo " + ini.nama;
}
}
fungsi utama(): Angka {
final budi: Orang = Orang { nama: "Budi", umur: 20 };
println(budi.sapa());
jika (info budi == "Struktur") {
println("Budi adalah struktur Orang");
}
kembalikan budi.umur;
}
Opcode bergaya Python
VM resmi memakai opcode eksplisit agar mudah dibaca dan didebug.
| Lama | Baru |
|---|---|
CONST |
LOAD_CONST |
LOAD |
LOAD_NAME |
STORE |
STORE_NAME |
STORE_LOCAL |
STORE_FAST |
POP |
POP_TOP |
BINARY |
BINARY_OP |
COMPARE |
COMPARE_OP |
JUMP |
JUMP_ABSOLUTE |
POP_JUMP_IF_FALSE |
POP_JUMP_IF_FALSE |
CALL |
CALL_FUNCTION |
RETURN |
RETURN_VALUE |
FUNC |
MAKE_FUNCTION |
Opcode lama TIDAK didukung lagi untuk kompatibilitas.
Contoh bytecode konseptual if/else
LOAD_NAME pi
TO_BOOL
POP_JUMP_IF_FALSE L_else
LOAD_NAME pi
STORE_NAME Pi
JUMP_ABSOLUTE L_end
L_else:
LOAD_CONST 0
STORE_NAME Pi
L_end:
LOAD_CONST None
RETURN_VALUE
Catatan: label seperti L_else hanya simbol disassembler/compiler. Runtime tetap memakai offset angka.
| Path | Fungsi |
|---|---|
src/IDScript/__main__.py |
CLI publik idscript. |
src/IDScript/gramm.lark |
Grammar utama IDScript. |
src/IDScript/compile/entrypoint.py |
Entrypoint interpreter normal. |
src/IDScript/compile/ids_ast |
Definisi AST. |
src/IDScript/compile/parser |
Transformer parse tree ke AST. |
src/IDScript/compile/runtime |
Interpreter normal dan runtime model. |
src/IDScript/compile/Compiler |
Compiler VM resmi, bytecode, dan VM runtime. |
src/IDScript/IDSRepl |
REPL interaktif — README |
src/IDScript/maker |
Python-to-IDScript binding API — README |
src/IDScript/builtins |
Builtin standar — README |
Jalankan dari folder src:
bash run_tests.sh # full suite (~10 menit)
bash run_tests.sh --fast # hanya test cepat (tanpa parser/VM)Atau secara manual:
cd src
python -m pytest IDScript/compile/testing/ IDScript/maker/testing/ -q -k 'not test_compile_example_file'
python -m pytest IDScript/compile/testing/test_compile.py -q -k 'not test_compile_example_file'
python -m pytest IDScript/compile/Compiler/testing/test_compiler.py -qCatatan:
test_compile_example_filemembutuhkanExample/main.idspada root project yang belum tersedia.test_permintaan_builtin_wraps_requests_responsemembutuhkanrequestsyang diinstal secara otomatis oleh test.- VM bytecode compiler dan interpreter normal sudah mendukung semua fitur bahasa termasuk fungsi ekspresi dan generic.
IDScript menggunakan MIT License.
Ringkasan Lisensi
- Kamu boleh memakai, menyalin, memodifikasi, menggabungkan, mempublish, mendistribusikan, sublicense, dan menjual IDScript.
- Kamu boleh memakai IDScript untuk proyek pribadi, pendidikan, riset, maupun komersial.
- Copyright notice dan permission notice MIT harus tetap disertakan pada salinan atau bagian substantial dari software.
- IDScript diberikan apa adanya, tanpa garansi apa pun.
- Pembuat dan pemegang hak cipta tidak bertanggung jawab atas klaim, kerusakan, atau masalah lain dari penggunaan IDScript.
Lihat file LICENSE.md untuk teks lengkap.