// A tiny stack machine: a program is a vector of instructions (an ADT),
// executed by one `match` per step.
import std.io.println;
import std.text.number;
type Instruction =
| Push of int
| Add
| Multiply
| Print
;
def run(program: &vector Instruction): int {
let stack: mutable vector int = [];
let pc: mutable uint = 0;
while (pc < (length(*program) as uint)) {
match (*program)[pc] with
| Instruction.Push(value) -> { append(stack, value); }
| Instruction.Add -> {
let top: uint = (length(stack) as uint) - 1;
stack[top - 1] := stack[top - 1] + stack[top];
pop_last(&mutable stack);
}
| Instruction.Multiply -> {
let top: uint = (length(stack) as uint) - 1;
stack[top - 1] := stack[top - 1] * stack[top];
pop_last(&mutable stack);
}
| Instruction.Print -> {
println(int_to_text(stack[(length(stack) as uint) - 1]));
};
pc := pc + 1;
}
return stack[0];
}
def pop_last(stack: &mutable vector int): void {
let kept: mutable vector int = [];
let i: mutable uint = 0;
while (i + 1 < (length(*stack) as uint)) {
append(kept, (*stack)[i]);
i := i + 1;
}
*stack := kept;
}
def main(): int {
// (2 + 3) * 7 + 7
let program: vector Instruction = [
Instruction.Push(2), Instruction.Push(3), Instruction.Add(), Instruction.Print(),
Instruction.Push(7), Instruction.Multiply(), Instruction.Print(),
Instruction.Push(7), Instruction.Add(), Instruction.Print()
];
let final_value: int = run(&program);
println(int_to_text(final_value));
return 0;
}// آلة مكدس صغيرة: البرنامج متجه من التعليمات (نوع جبري)،
// تُنفذ بـ`طابق` واحد في كل خطوة.
استورد std.io.println;
استورد std.text.number;
نوع تعليمة =
| ادفع بنوع عدد
| اجمع
| اضرب
| اطبع_القمة
;
عرف شغل(البرنامج: &متجه تعليمة): عدد {
دع المكدس: متغير متجه عدد = [];
دع عداد_التعليمات: متغير طبيعي = 0;
طالما (عداد_التعليمات < (الطول(*البرنامج) مثل طبيعي)) {
طابق (*البرنامج)[عداد_التعليمات] مع
| تعليمة.ادفع(القيمة) -> { ألحق(المكدس, القيمة); }
| تعليمة.اجمع -> {
دع القمة: طبيعي = (الطول(المكدس) مثل طبيعي) - 1;
المكدس[القمة - 1] := المكدس[القمة - 1] + المكدس[القمة];
احذف_الأخير(&متغير المكدس);
}
| تعليمة.اضرب -> {
دع القمة: طبيعي = (الطول(المكدس) مثل طبيعي) - 1;
المكدس[القمة - 1] := المكدس[القمة - 1] * المكدس[القمة];
احذف_الأخير(&متغير المكدس);
}
| تعليمة.اطبع_القمة -> {
اطبع_سطر(عدد_إلى_نص(المكدس[(الطول(المكدس) مثل طبيعي) - 1]));
};
عداد_التعليمات := عداد_التعليمات + 1;
}
أرجع المكدس[0];
}
عرف احذف_الأخير(المكدس: &متغير متجه عدد): فراغ {
دع المحفوظ: متغير متجه عدد = [];
دع ف: متغير طبيعي = 0;
طالما (ف + 1 < (الطول(*المكدس) مثل طبيعي)) {
ألحق(المحفوظ, (*المكدس)[ف]);
ف := ف + 1;
}
*المكدس := المحفوظ;
}
عرف الرئيسية(): عدد {
// (2 + 3) * 7 + 7
دع البرنامج: متجه تعليمة = [
تعليمة.ادفع(2), تعليمة.ادفع(3), تعليمة.اجمع(), تعليمة.اطبع_القمة(),
تعليمة.ادفع(7), تعليمة.اضرب(), تعليمة.اطبع_القمة(),
تعليمة.ادفع(7), تعليمة.اجمع(), تعليمة.اطبع_القمة()
];
دع القيمة_النهائية: عدد = شغل(&البرنامج);
اطبع_سطر(عدد_إلى_نص(القيمة_النهائية));
أرجع 0;
}
Run it
With the interpreter, without compiling:
./build/sultanc run examples/en/programs/stack_machine.snOr compile it to an executable:
./build/sultanc examples/en/programs/stack_machine.sn -o build/example && ./build/example