Bước đầu tiên của compiler viết bằng DUY là Lexer — module cắt chuỗi ký tự nguồn thành các tokens. Sprint 81 đặt ra mục tiêu: Lexer viết bằng DUY phải cho ra đầu ra khớp 100% với Lexer viết bằng JS.
Để chứng minh điều này, chúng tôi viết tools/lex_core.duy bằng subset DUY. Đồng thời, viết một công cụ so sánh là duy lex-compare để chạy thử nghiệm trên một tập hợp (corpus) gồm 10 file nguồn khác nhau. Lệnh so sánh sẽ chạy cả hai phiên bản lexer (JS và DUY) trên cùng một file, sau đó so khớp từng token từ tên, kiểu dữ liệu, cho đến vị trí dòng/cột.
source.duy -> [ JS Lexer ] -> token stream digest \ Must match
-> [ DUY Lexer ] -> token stream digest / exactly!
Thử nghiệm đầu tiên thất bại ngay lập tức. Màn hình báo đỏ rực với hàng loạt mismatch về vị trí dòng cột. Thủ phạm hóa ra là sự khác biệt trong cách xử lý ký tự xuống dòng (\r\n của Windows và \n của Unix). JS engine ẩn một số chi tiết này thông qua các hàm xử lý chuỗi cao cấp của V8, trong khi DUY lexer tự chạy trên mảng byte thô của file nên báo vị trí cột lệch nhau khi gặp ký tự xuống dòng Windows.
Tôi phải mất cả đêm để tinh chỉnh thuật toán quét byte trong lex_core.duy để chuẩn hóa line endings trước khi tính toán số cột. Mỗi lần sửa code, tôi lại chạy script so sánh, nhìn số lỗi mismatch giảm dần từ hàng trăm xuống hàng chục, rồi về không. Khi cả 10 file trong corpus đều cho ra digest trùng khớp hoàn toàn, chúng tôi tiến hành đo hiệu năng. Kết quả benchmark lexer viết bằng DUY biên dịch qua LLVM chạy nhanh gấp đôi phiên bản JS chạy trên V8. Đó không chỉ là chiến thắng về hiệu năng; đó là bằng chứng đầu tiên cho thấy con đường tự trị của chúng tôi hoàn toàn khả thi.
Bình luận (0)
Đang tải bình luận...