рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░! рдЕрдм рдХрдИ рд╣рдлреНрддреЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЕрдкрдиреА Rust рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдЗрд╕ рд╡реНрдпрд╡рд╕рд╛рдп рдореЗрдВ рдХреНрдпрд╛ рдиреМрд╕рд┐рдЦрд┐рдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЙрд╕реЗ рдХреНрдпрд╛ рдкрддрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЗрддрд┐рд╣рд╛рд╕
рдпрд╣ рд╕рдм рдИрдЗрди рдХреЗ рдПрдХ рдХрд╛рдВрдЯреЗ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реБрдЖ, рдореИрдВрдиреЗ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ рдлреЛрд░реНрдХ рдХрд┐рдпрд╛ред рдЪреВрдБрдХрд┐ ein рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдФрд░ рд╕реЗ рдХреА рдЧрдИ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреА рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдЧрддрд┐ рдЙрдЪреНрдЪрддрдо рдирд╣реАрдВ рдереА, рдФрд░ рдЬрдм рдореИрдВрдиреЗ рдХреБрдЫ рд╕рдордЭрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛, рддреЛ рдореИрдВрдиреЗ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рджреБрднрд╛рд╖рд┐рдпрд╛ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЬрд┐рд╕реЗ рдЕрдВрдд рдореЗрдВ рдЫреЛрдбрд╝ рднреА рджрд┐рдпрд╛ред
рд▓реЗрдХрд┐рди рдпрд╣ рдирд┐рд░рд╛рд╢рд╛ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЬрд▓реНрджреА рд╣реИ! рдореИрдВрдиреЗ VM рдФрд░ рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рд▓реЗрдЦ рдкрдврд╝реЗ рдФрд░ рдПрдХ рд╕рд░рд▓ рд╕реНрдЯреИрдХреНрдб VM рд▓рд┐рдЦрдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред
"рд╕реНрдЯреИрдХреНрдб рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди" рдХреНрдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ?
рд╣рдмреНрд░ рдкрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ otdelny рд▓реЗрдЦ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣реИ рдХрд┐ рд▓рд┐рдВрдХ рдкрд░ рдбреНрд░рд╛рдЗрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдореИрдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдЗрд╕ рдЫреЛрдЯреА рд╕реА рдмрд╛рдд рдХрд╛ рдЕрд░реНрде рд╕рдордЭрд╛рдКрдВрдЧрд╛ред
рд╕реНрдЯреИрдХ VM рдбреЗрдЯрд╛ рдкрд░ рд╕рднреА рдСрдкрд░реЗрд╢рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕реНрдЯреИрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрддрд╛ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдСрдкрд░реЗрд╢рди рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдорд╛рддреНрд░рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдмрд╛рдж рд╕реНрдЯреИрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдирдВрдмрд░ "рднреЗрдЬ" рд╕рдХрддрд╛ рд╣реИред
рд╢реБрд░реБрдЖрдд рд╣реЛ рд░рд╣реА рд╣реИ
рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдХрд╛рд░реНрдЧреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
cargo new habr_vm
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЕрдкрдиреЗ рд╡реАрдПрдо рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдмреБрдирд┐рдпрд╛рджреА рдСрдкрд░реЗрд╢рди рдмрдирд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ:
enum Opcode { Push(i32), Add, AddAssign(i32), Sub, SubAssign(i32), }
рдпреЗ рд╣рдорд╛рд░реЗ рдореВрд▓ рд╕рдВрдЪрд╛рд▓рди рд╣реИрдВ, рдкреБрд╢ рдХрдорд╛рдВрдб рд╕реНрдЯреИрдХ рдореЗрдВ рдПрдХ рдирдпрд╛ рдирдВрдмрд░ рдЬреЛрдбрд╝ рджреЗрдЧрд╛, рдРрдб рдФрд░ рд╕рдм рд╕реНрдЯреИрдХ рд╕реЗ рджреЛ рдирдВрдмрд░ рд▓реЗрдЧрд╛ рдФрд░ рдЙрдирдХреЗ рд╕рд╛рде рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░реЗрдЧрд╛ (рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдФрд░ рдШрдЯрд╛рд╡, рдХреНрд░рдорд╢рдГ), рдореБрдЭреЗ AddAssign рдФрд░ SubAddign рдХреЛ рд╕рдордЭрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдЕрдЧрд▓рд╛ рдХрд╛рдо рдЦреБрдж рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдмрдирд╛рдирд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдПрдХ рдЬрдЯрд┐рд▓ рд╕рдВрд░рдЪрдирд╛ рдирд╣реАрдВ рдмрдирд╛рдПрдВрдЧреЗ:
struct Vm { pub stack: Vec<i32>, }
рдФрд░ рд╣рдо рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:
impl Vm {
рд╣рдордиреЗ рдЕрдкрдиреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛, рдЖрдЧреЗ рдХреНрдпрд╛? рдЕрдЧрд▓рд╛ рд╣рдореЗрдВ рдЕрдкрдирд╛ "рдкреНрд░реЛрдЧреНрд░рд╛рдо" рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:
let program = vec![ Opcode::Push(2),
рдпрд╣ рдЖрд╕рд╛рди рд╣реИ, рд╣реИ рдирд╛? рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рдЪрд▓реЛ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдЪрд▓рд╛рдПрдВ!
let mut vm = Vm {stack: Vec::new()}; vm.run(program);
рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЕрдкрдиреЗ рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдСрдкрдХреЛрдб рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
рдирд┐рд╖реНрдХрд░реНрд╖
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рдордЭрд╛рдпрд╛ рдХрд┐ рдпрд╣ рд╕рдм рдХреИрд╕реЗ рдПрдХ рд░реИрд╕реНрдЯ рдкрд░ рд▓рд┐рдЦрдирд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдореИрдВ рдпрд╣ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рд╕рдорд╛рди рд╡рд╛рдИрдПрдо рдХреЗ рд▓рд┐рдП рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рд╡рд╛рдИрдкреА рдзрдиреНрдпрд╡рд╛рдж рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдкрдХреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рдкрд╛рд░реНрд╕рд░, рд▓реЗрдХреНрд╕рд░ рдФрд░ "рдХрдВрдкрд╛рдЗрд▓рд░" рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдпрджрд┐ рдЖрдк рдПрдХ рддреИрдпрд╛рд░-рдХрд┐рдП рдЧрдП рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЖрдк рдЗрд╕ рд▓рд┐рдВрдХ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд▓реЗрдЦ рдХрд╛ рд╕рднреА рдХреЛрдб рдЗрд╕ рднрдВрдбрд╛рд░ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИред
рдЧреБрдб рд▓рдХ рд╣реЗрдмрд░рд╛!