Để sinh mã cho các cấu trúc điều khiển (vòng lặp, rẽ nhánh), trình biên dịch cần thêm các lệnh nhảy có điều kiện và không điều kiện. Hãy cài đặt một máy ảo ngăn xếp đầy đủ hơn, hỗ trợ các lệnh:
PUSH k: đẩy hằng số nguyên k.POP: bỏ giá trị trên đỉnh.DUP: nhân đôi giá trị trên đỉnh (đẩy thêm một bản sao).SWAP: hoán đổi hai giá trị trên đỉnh.ADD, SUB, MUL, DIV: như các bài trước (POP b rồi a, tính a OP b, đẩy kết quả; DIV chia lấy phần nguyên kiểu Python, làm tròn về −∞, mẫu số luôn khác 0).PRINT: in giá trị đỉnh ngăn xếp, không POP.JMP L: nhảy tới dòng lệnh có nhãn L.JZ L: POP giá trị trên đỉnh; nếu bằng 0 thì nhảy tới nhãn L, ngược lại tiếp tục với dòng kế tiếp.HALT: dừng chương trình ngay lập tức.Một dòng lệnh có thể có nhãn ở đầu, viết dưới dạng TÊN_NHÃN: ngay trước lệnh trên cùng một dòng (ví dụ LOOP: DUP); một dòng cũng có thể không có nhãn. Đề bảo đảm chương trình luôn dừng lại (không lặp vô hạn), với n≤200 dòng lệnh.
Ví dụ: chương trình sau in ra các số nguyên từ 3 xuống 1:
PUSH 3
LOOP: DUP
JZ END
PRINT
PUSH 1
SUB
JMP LOOP
END: HALT
In ra các giá trị được lệnh PRINT xuất ra, mỗi giá trị một dòng, theo đúng thứ tự thực thi. Nếu chương trình không thực thi lệnh PRINT nào, không in gì cả.
Ví dụ:
Đầu vào:
6
PUSH 1
PUSH 2
SWAP
PRINT
POP
PRINT
Đầu ra:
1
2
Đầu vào:
7
PUSH 6
PUSH 3
DIV
PUSH 4
MUL
PRINT
HALT
Đầu ra:
8
Đang tải editor...