Changelog
Semua perubahan penting pada AHA! Lang
Changelog
Semua perubahan penting pada AHA! Lang didokumentasikan dalam berkas ini. Anda selalu dapat membangun versi terbaru dari kode sumber — lihat Getting Started.
1.4.5 — 2026-08-16
Ditambahkan
- Fungsi generik (F3):
fn pick<T>(a: T, b: T) -> T { if a > b { a } else { b } }— fungsi dengan tipe parameter generik. - Monomorphization via LLVM: Setiap kombinasi unik (nama generik, tipe konkret) menjadi fungsi LLVM terpisah (
pick_Int,pick_String, ...), dikompilasi lazy di call site pertama dan di-cache. Nol biaya runtime — generics resolve sepenuhnya saat kompilasi. - Banyak type params:
fn first<A, B>(a: A, b: B) -> A— binding konkret di-infer dari argumen call site. - Anotasi return type:
-> Tatau-> int— return type generik atau konkret. - Monomorphization bersarang: Fungsi generik bisa memanggil fungsi generik lain (
fn twice<U>(x: U) -> U { id(x) }). - Rangkaian Pengujian: 417 pengujian lulus (sebelumnya 404; +13 pengujian generics: identity int/string/bool/struct, pick, dua type params, panggilan bersarang, bentuk IR).
Diubah
predeclare_functionsmenyimpan fungsi generik digeneric_defs(tanpa pre-deklarasi langsung); body dikompilasi saat monomorphization.compile_functionme-skip body fungsi generik di top-level (hanya di-instantiate saat dipanggil).- Fixpoint loop me-skip fungsi generik (return type hanya ada per instantiation).
Keamanan
- Generics tidak menambah jalur unsafe: semua tipe tetap diverifikasi saat kompilasi; monomorphization murni duplikasi codegen per tipe.
1.4.4 — 2026-08-16
Ditambahkan
- Anotasi Tipe (F2):
let x: int = 5— deklarasi variabel dapat membawa anotasi tipe eksplisit (int,string,bool, atau nama struct). Nilai diperiksa tipenya saat kompilasi:let x: int = "hi"→ error kompilasiType mismatch: variable 'x' annotated as 'int' but value has type 'String'let p: Point = Other { ... }→ error kompilasi bila nama struct berbeda
- Inferensi Tipe (F2): Variabel tanpa anotasi tipenya di-infer dari ekspresi (literal, panggilan fungsi, if-expression).
- Inferensi return type fungsi:
fn greet() { "hello" }ber-return type String — caller bisalet s = greet(); len(s). - If-expression dengan cabang string:
fn pick(a) { if a > 0 { "pos" } else { "neg" } }kini mengembalikan string sungguhan (phi node memakai tipe cabang, bukan selalu i64). - Rangkaian Pengujian: 404 pengujian lulus (sebelumnya 384; +20 pengujian inferensi/anotasi tipe).
Diubah
infer_expr_type&infer_expr_type_with_scopemendukung anotasi dan inferensi return type fungsi.- Hint tipe yang tidak dikenal (
let x: unknown = 7) bersifat lenient — fallback ke Int, konsisten dengan struct field hints.
Keamanan
- Anotasi tipe diverifikasi saat kompilasi: ketidakcocokan anotasi dengan tipe nilai menghasilkan error kompilasi, bukan perilaku tak terdefinisi.
1.4.3 — 2026-08-16
Ditambahkan
- Halaman Referensi Sintaks: Referensi lengkap seluruh sintaks AHA! yang terverifikasi dari compiler — 13 kata kunci, identifier, literal, tipe, operator dengan tabel precedence, statement, ekspresi, alur kontrol, komentar, builtin, dan ringkasan grammar EBNF. Tersedia di /id/syntax (ID) dan /en/syntax (EN).
- Struct sebagai parameter fungsi (F1): Struct dapat dioper by-value ke fungsi. Parameter dialokasikan dengan tipe LLVM struct yang benar; akses field di dalam fungsi bekerja normal.
- Struct sebagai return value fungsi (F1): Fungsi dapat mengembalikan struct literal. Caller menyimpan hasilnya ke binding
letdan membaca field-nya. - Struct literal langsung sebagai argumen:
sum(Point { x: 1, y: 2 })— tanpa variabel perantara. - Rantai fungsi struct:
sum(make(20, 22))— return value struct langsung dioper ke fungsi lain. unify_with()pada AhaType: Menyatukan tipe parameter dari beberapa call site (String dan nama struct meng-override default Int).- Rangkaian Pengujian: 384 pengujian lulus (sebelumnya 373; +11 pengujian struct param/return).
Diubah
infer_expr_type&infer_expr_type_with_scopekini mengenaliStructLiteraldanFieldAccessuntuk inferensi tipe pre-pass yang akurat.scan_call_sitesmelacak binding variabel struct (struct_var_types) agar inferensi tipe bisa resolve struct variable sebagai argumen fungsi.- Language Tour: Memperbaiki sintaks
fordarifor i 0..10menjadifor i in 0..10— kata kunciinwajib menurut parser. Juga menambahkan "Referensi Sintaks" ke navigasi docs.
1.4.2 — 2026-08-16
Ditambahkan
- Mutasi Field (F1):
p.x = value— penugasan field struct saat runtime.p.xkini menjadi lvalue: load struct,insertvaluefield baru, store kembali. Tipe diperiksa terhadap deklarasi field (fieldstringmenolak nilai int dan sebaliknya). - Target Penugasan Generik: Parser kini memperlakukan
=sebagai operator infix, sehingga baikx = 5(identifier) maupunp.x = 5(field access) mengurai menjadiAssignmentExpressiondengan target ekspresi generik. - Rangkaian Pengujian: 373 pengujian lulus (sebelumnya 363; +10 pengujian mutasi field, termasuk mutasi di dalam loop dan penugasan ulang field string).
Diubah
AssignmentExpression.name: Identifier→AssignmentExpression.target: Box<Expression>— memungkinkan bentuk lvalue di masa depan (mis. penugasan elemen arrayarr[0] = x).
Diperbaiki
TokenType::Assigntidak ada diprecedence(), sehingga=jatuh keparse_prefixsebagai token tak terduga. DitambahkanPrecedence::Assign.
Keamanan
- Menugaskan nilai dengan tipe yang salah ke field bertipe menghasilkan kesalahan saat kompilasi.
1.4.1 — 2026-08-16
Ditambahkan
- Codegen Struct (Roadmap Phase 2 #1): definisi
struct Point { x, y }kini menghasilkan tipe struct LLVM yang sesungguhnya. LiteralPoint { x: 1, y: 2 }membangun agregat viainsertvalue; akses fieldp.xdibaca viaextractvalue. - Field Struct Bertipe: anotasi tipe field (
name: string, age: int) dihormati saat runtime — fieldstringmemakai layout{i8*, i64}, fieldintmemakaii64. Literal diperiksa tipenya terhadap deklarasi. Akses field mempertahankan tipe yang dideklarasikan, sehinggalen(p.name),p.name == "...", danp.first + p.lastbekerja dengan benar. - Sintaks Literal Struct:
TypeName { field: value, ... }— dibatasi oleh registry nama struct sehingga kondisi blok biasaif x { ... }tidak terpengaruh. - PRD (Product Requirements Document):
PRD.md— mendefinisikan visi AHA! dari web hingga aerospace, prioritas roadmap, dan tata kelola proyek. - Rangkaian Pengujian (struct): 28 pengujian backend mencakup semantik JIT, bentuk IR, field bertipe, dan jalur kesalahan.
Diubah
- Alur kerja branch: semua pengembangan kini terjadi di branch
development;mainhanya menerima PR dengan CI hijau. - PRD menggantikan perencanaan ad-hoc: semua fitur masa depan wajib berasal dari roadmap di
PRD.md. - F5 (Resource lifetimes) dibekukan: ownership/lifetimes tidak akan disentuh sampai F1–F4 (penyelesaian struct, inferensi tipe, generics, sistem modul) stabil.
Keamanan
- Tipe field struct diperiksa saat kompilasi: menugaskan literal string ke field
int(atau sebaliknya) menghasilkan kesalahan saat kompilasi, bukan perilaku runtime tak terdefinisi.
1.4.0 — 2026-05-17
Ditambahkan
- Sistem Tipe (
src/types.rs): enumAhaType(Int,Bool,String,Void,Array,Function) dengan pemeriksaan tipe saat kompilasi viacheck_binary_op()dancheck_prefix_op() - TypedValue: semua metode ekspresi codegen kini mengembalikan
TypedValueyang memasangkan nilai LLVM denganAhaType-nya - Tipe String: string kini merupakan struct LLVM
{i8*, i64}(pointer + panjang), menggantikan cast pointer-ke-int yang tidak aman - Konkatenasi String:
"hello" + " world"mengalokasikan buffer baru viamalloc, menyalin viamemcpy, menambahkan null-terminator - Perbandingan String:
==dan!=pada string menggunakanstrcmpdari pustaka standar C - Builtin
len(): mengembalikan panjang string dalam O(1) dengan membaca field panjang struct - Penautan C Runtime: deklarasi eksternal untuk
malloc,memcpy,strlen,strcmp - Komentar Blok: komentar multi-baris
/* ... */ - Urutan Escape String:
\n,\t,\\,\",\r,\0 - Peningkatan Identifier: digit setelah karakter pertama (
my_var2), prefiks garis bawah (_private) - Rangkaian Pengujian: 84 pengujian di 4 modul — lexer, parser, sistem tipe, dan JIT ujung-ke-ujung
Diubah
Token.r#typediganti nama menjadiToken.kind— mengikuti konvensi Rust, menghilangkan sintaks raw identifier- Cakupan variabel: peta datar → tumpukan cakupan dengan pelacakan tipe
compile_expression()mengembalikanTypedValuedi seluruh penangan ekspresi- Semua pesan keluaran dan komentar sumber distandarkan ke bahasa Inggris
- Roadmap README diperbarui untuk mencerminkan status implementasi secara akurat
Diperbaiki
- Operator
!=menghasilkan"=="alih-alih"!="(kesalahan copy-paste di lexer) - Kondisi
iftidak dikonversi darii64kei1sebelumbuild_conditional_branch - Node phi mereferensikan basic block asli alih-alih end block sebenarnya
- Ekspresi terakhir di badan program dikompilasi dua kali
- Fungsi memancarkan return implisit dan eksplisit sekaligus, menyebabkan kesalahan LLVM "multiple terminators"
- Kompilasi fungsi dapat membocorkan state scope/builder saat terjadi kesalahan
- Parser mengembalikan
Expression::Identifier("ERROR")saat gagal parse, menyebarkan AST tidak valid ke codegen
Keamanan
- Ketidakcocokan tipe (
"hello" + 5) kini menghasilkan kesalahan saat kompilasi alih-alih perilaku runtime tak terdefinisi - Semua panggilan
.unwrap()diganti dengan.expect("descriptive context")untuk panic yang dapat di-debug
1.3.0 — Rilis Sebelumnya
- Compiler awal dengan lexer, parser, codegen
- Tipe bilangan bulat, boolean, string (sebagai trik pointer)
- Perulangan If/else, while, for
- Fungsi dengan parameter
- Stdlib dasar: print, print_str, abs, min, max