“Bắt” nguồn cảm hứng cho ngôn ngữ lập trình từ một hình ảnh biểu thị assembly X86 trong sách giáo khoa
Tác giả Nguyễn Đình Duy, học viên khóa 2021 – 2024
Ghi chú: Bài viết này nói lại trải nghiệm tự tạo ngôn ngữ lập trình của riêng mình và không phải về một chủ đề cụ thể mà mình chọn. Những ý kiến được viết ra ở đây là những suy nghĩ và trải nghiệm riêng và mình không muốn coi chúng là sự thật.
Nội dung:
– Phần 1: Giới thiệu
+ Nguồn cảm hứng
– Phần 2: Quá trình phát triển
+ Một cái nhìn sâu vào những gì mình đã làm
Phần I: Mở đầu.
Khi mình đã “bắt” được nguồn cảm hứng cho ngôn ngữ lập trình (từ một hình ảnh biểu thị assembly X86 trong sách giáo khoa), mình biết rằng không ai sẽ dùng nó cả. Qua nguồn cảm hứng, bạn có thể thấy rằng không ai sẽ dùng cái ngôn ngữ rườm rà này. Ngôn ngữ của mình là một ngôn ngữ lập trình thủ tục (procedural), và người dùng sẽ phải viết một loạt các câu lệnh và các procedure để hoàn thành một mục tiêu.
Các bạn có thể thấy rằng không có một điểm nào là khác nhau giữa 2 chương trình trên, nhưng code của ngôn ngữ dưới rất rườm rà và được viết như một mạch chỉ dẫn.
Danh sách các token này sẽ được chuyển thành những cấu trúc dữ liệu như cây AST (abstract syntax tree) và Action Tree để tạo nên cú pháp của một câu code. Đây là một ví dụ của những gì ngôn ngữ của mình có. Mình mong rằng phần mở đầu này đã cho các bạn biết những gì mình có khi phát triển ngôn ngữ này, tiếp theo sau đó là về…
Phần II: Quá trình phát triển:
GHI CHÚ: Mình sẽ dùng file code này trong bài viết để giải thích output của ngôn ngữ:
https://docs.google.com/document/d/1at-Lw8k2HUUpX34Sy_MHcC58WSveQEY5MA5Q0gQ1VXk/edit
Các bạn có thể nhìn file để theo dõi trong khi đọc.
Phần cơ bản:
Trước khi chính thức phát triển, mình phải nghĩ về cách nó sẽ được xử lý và dịch ngôn ngữ. Vì mình còn thiếu kinh nghiệm với nhiều khái niệm và thuật toán trong lập trình, mình sẽ không compile ngôn ngữ và thay vào đó, mình sẽ interpret ngôn ngữ. Dự án cũng không có kế hoạch mở rộng nhiều, nên mình sẽ chọn Python làm ngôn ngữ để mình phát triển dự án (mặc dù Python khá chậm nên ngôn ngữ có phần chậm).
Một số luật của ngôn ngữ:
Đây là một số luật của ngôn ngữ mình:
+ Mỗi câu lệnh đều được bắt đầu bằng một từ khoá
+ Mỗi giá trị được tính ra bởi các câu lệnh đều được viết vào một cái variable built-in trong ngôn ngữ
+ Mỗi từ khoá chỉ được có 2 giá trị truyền vào
+ Các variable không được thay đổi
+ Hỗ trợ các procedure
Quá trình phát triển:
Lexer:
Mình quyết định lập trình một chương trình thường được gọi là lexer để phân tích cú pháp của một file chương trình. Output của chương trình phân tích này sẽ được dùng bởi chương trình phiên dịch.
Chương trình này sẽ tạo ra một danh sách các token khác nhau như literal, operator,… Việc phiên dịch cần phải có nhiều thông tin nhất có thể về những token này để dịch một cách hiệu quả và không sai sót.
AST tree:
Các bạn có thể thấy rằng:
– Những dòng được cách là những giá trị được truyền vào các từ khoá khác nhau
– Những loại (type) của các token được hiển thị. Ví dụ: “numberone” là một identifier cho một biến và “opfour” là một chuỗi
– Những tính năng này thường để được dùng cho việc tính toán
– Bên cạnh đó, tính năng này có phần vô dụng vì cách xử lý từ khoá của mình ít cần cây AST này
– Tuy nhiên, cách xử lý này vẫn hoạt động
Evaluation:
Cách evaluate của mình khá vụng về và không hiệu quả. Ngôn ngữ này chưa được hoàn thiện cho lắm, và vẫn chỉ là một loạt các keyword khác nhau. Việc viết mã không linh hoạt nhưng vẫn hoạt động. Code của rất rườm rà và mình không có ý định chia sẻ.
Những hạn chế:
Về cách xử lý chương trình và xử lý loại biến, ngôn ngữ lập trình của mình chỉ có 2 loại dữ liệu là interger và string
Những phần identifier chỉ có thể reference được biến và các procedure
Ngôn ngữ này có rất nhiều điểm giới hạn khác, ví dụ:
+ Khi đặt tên cho biến, người dùng cần phải dùng string để đặt tên thay vì một identifier
+ Không có các dạng cấu trúc dữ liệu như array hoặc list
+ Không có cây Action Tree, nên cách xử lý lệnh rất rườm rà
Kết luận:
Mình có một số bài học mình cần rút ra:
– Mình cần phải học những thứ cơ bản nhất như scoping, environment trước khi làm ngôn ngữ. Ngôn ngữ mình không có những tính năng này và đó là một trở ngại lớn
– Mình cần phải có một kế hoạch trước khi phát triển ngôn ngữ, tại vì hầu hết những gì mình làm đều được nghĩ ra trong quá trình phát triển, và điều này khiến ngôn ngữ mình rất lộn xộn
Nói chung, mình đã tạo ra một ngôn ngữ mà hoạt động như ý muốn, và trong lúc phát triển mình cũng đã học được rất nhiều về việc phát triển ngôn ngữ, và mình cũng rất vui khi được chia sẻ với các bạn.
Cảm ơn các bạn vì đã đọc bài viết này và chúc các bạn may mắn!
1,935 total views, 1 views today