Tôi muốn tìm hiểu thêm về lập trình ghép nối thông qua việc tạo ra một ngôn ngữ đơn giản nhỏ, dựa trên ngăn xếp và tuân theo mô hình ghép.
Thật không may, tôi đã không tìm thấy nhiều tài nguyên liên quan đến các ngôn ngữ kết hợp và việc triển khai chúng, vì vậy xin lỗi trước cho sự ngây thơ có thể của tôi.
Do đó, tôi đã định nghĩa ngôn ngữ của mình là một chuỗi đơn giản của các hàm, được biểu diễn trong AST dưới dạng một danh sách:
data Operation
= Concat [Operation]
| Quotation Operation
| Var String
| Lit Literal
| LitOp LiteralOperation
data Literal
= Int Int
| Float Float
data LiteralOperation
= Add | Sub | Mul | Div
Chương trình sau, 4 2 swap dup * +
(tương ứng với 2 * 2 + 4
) một khi được phân tích cú pháp, sẽ cho AST sau:
Concat [Lit (Int 4), Lit (Int 2), Var "swap", Var "dup", LitOp Mul, LitOp Add]
Bây giờ tôi phải suy luận và kiểm tra các loại.
Tôi đã viết hệ thống loại này:
data Type
= TBasic BasicType -- 'Int' or 'Float'
| TVar String -- Variable type
| TQuoteE String -- Empty stack, noted 'A'
| TQuote String Type -- Non empty stack, noted 'A t'
| TConc Type Type -- A type for the concatenation
| TFun Type Type -- The type of functions
Đó là nơi câu hỏi của tôi xuất hiện, bởi vì tôi không biết nên suy luận kiểu gì từ biểu hiện đó. Loại kết quả là rõ ràng, Int
nhưng tôi không biết làm thế nào để thực sự kiểm tra hoàn toàn chương trình này ở cấp độ loại.
Lúc đầu, như bạn có thể thấy ở trên, tôi đã nghĩ về một TConc
loại đại diện cho sự ghép nối giống như TFun
kiểu đại diện cho một hàm, bởi vì cuối cùng, chuỗi nối tạo thành một hàm duy nhất.
Một tùy chọn khác, mà tôi chưa khám phá, sẽ là áp dụng quy tắc suy luận thành phần hàm cho từng phần tử của chuỗi biểu thức này. Tôi không biết làm thế nào nó sẽ hoạt động với dựa trên ngăn xếp.
Câu hỏi là như vậy: làm thế nào để chúng ta làm điều đó? Nên sử dụng thuật toán nào và cách tiếp cận nào ở cấp độ loại?