Tập 54: Sym và tc subset

Đọc được cú pháp mới chỉ là bước bắt đầu. Trình biên dịch còn phải hiểu nghĩa của các biểu tượng (Symbol Resolution) và kiểm tra tính đúng đắn của kiểu (Type Checking). Sprint 83 và 84 đưa compiler DUY đi qua ranh giới của ngữ nghĩa.

Chúng tôi viết sym_subset.duy quản lý scope stack, phát hiện khai báo trùng lặp, và kết nối các identifier với nguồn gốc của chúng. Tiếp theo là tc_subset.duy — module nặng nhất của compiler với hơn 5.000 dòng code.

Type checker phải duyệt qua AST, gán kiểu cho biểu thức, suy luận kiểu cho let, và kiểm tra xem kiểu của tham số truyền vào hàm có khớp với khai báo hay không. Chúng tôi xây dựng 15 test accept và 10 test reject làm gate kiểm soát.

tc_subset.duy -> Typecheck output digest == JS tc output digest

Công cụ duy tc-compare được dùng để chạy so sánh song song. Nếu type checker viết bằng DUY chấp nhận một file reject, hoặc từ chối một file accept, digest sẽ báo lỗi lập tức.

Quá trình debug ở giai đoạn này đòi hỏi sự kiên nhẫn cực lớn. Có những lỗi checker tĩnh rất tinh vi: compiler mới gán sai kiểu cho một con trỏ hàm đệ quy tương hỗ, dẫn đến việc sinh mã máy bị hỏng bộ nhớ lúc chạy. Tìm ra lỗi đó giống như mò kim đáy bể vì chương trình không crash ngay khi compile mà crash ngẫu nhiên khi chạy Stage 1.

Mỗi lần phát hiện mismatch, tôi lại phải lật giở từng dòng đặc tả ngữ nghĩa, đối chiếu giữa logic JS và logic DUY để xem bên nào đang đi chệch hướng. Khi toàn bộ 25 fixtures kiểm thử đều xanh, tôi đã có thể thở phào nhẹ nhõm. Trình biên dịch mới đã có khả năng phán xử đúng sai về mặt ngữ nghĩa chính xác như trình biên dịch JS đàn anh.


Bình luận (0)

Đang tải bình luận...