#include <iostream>
#define MAX_REG 4
/*
instruction numbers:
0 - Halts
1 - Loads
2 - Add
3 - Print
Program Structure
**bits:
15 - 12 -> Instruction Number
11 - 8 -> Register to use
7 - 0 -> Immediate Value
*/
template<typename U>
void print( U && a )
{
std::cout << a << std::endl;
}
template< typename T, typename ...U>
void print( T && a, U &&...b )
{
std::cout << a;
print( std::forward<U>( b )... );
}
template< typename T, typename ...U>
void emitLn( T && a, U &&...b )
{
print( std::forward<T>( a ), std::forward<U>( b )... );
}
int main()
{
int vm_registers[MAX_REG] = { 0 };
int const program_code[] = { 0x109F, 0x11C8, 0x2201, 0x3200, 0x0000 };
int instruction_number, reg_0, reg_1, reg_2;
int instruction_pointer = 0, immediate_value = 0;
auto fetch = [&instruction_pointer, &program_code]{
return program_code[instruction_pointer++];
};
auto decode = [&]( uint16_t instrNumber ) mutable -> void {
instruction_number = ( instrNumber & 0xF000 ) >> 12;
reg_0 = ( instrNumber & 0xF00 ) >> 8;
reg_1 = ( instrNumber & 0xF0 ) >> 4;
reg_2 = ( instrNumber & 0xF );
immediate_value = ( instrNumber & 0xFF );
};
auto eval = [&]() mutable -> void{
switch( instruction_number ){
case 0:
emitLn( "halt" );
break;
case 1:
emitLn( "loadi r", reg_0, " #", immediate_value );
vm_registers[reg_0] = immediate_value;
break;
case 2:
emitLn( "add r", reg_0, " r", reg_1, " r", reg_2 );
vm_registers[reg_0] = vm_registers[reg_1] + vm_registers[reg_2];
break;
case 3:
emitLn( "print r", reg_0, "; //" , vm_registers[reg_0] );
break;
}
};
int const code_count = sizeof( program_code ) / sizeof( int );
[&]()->void{
while( instruction_pointer < code_count ){
auto instrNumber = fetch();
decode( instrNumber );
eval();
}
}();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKI2RlZmluZSBNQVhfUkVHIDQKCi8qCmluc3RydWN0aW9uIG51bWJlcnM6CgkwIC0gSGFsdHMKCTEgLSBMb2FkcwoJMiAtIEFkZAoJMyAtIFByaW50ClByb2dyYW0gU3RydWN0dXJlCiAqKmJpdHM6CgkxNSAtIDEyICAtPiBJbnN0cnVjdGlvbiBOdW1iZXIKCTExIC0gOCAJIC0+IFJlZ2lzdGVyIHRvIHVzZQoJNyAgLSAwICAgLT4gSW1tZWRpYXRlIFZhbHVlCiovCnRlbXBsYXRlPHR5cGVuYW1lIFU+CnZvaWQgcHJpbnQoIFUgJiYgYSApCnsKCXN0ZDo6Y291dCA8PCBhIDw8IHN0ZDo6ZW5kbDsKfQoKdGVtcGxhdGU8IHR5cGVuYW1lIFQsIHR5cGVuYW1lIC4uLlU+CnZvaWQgcHJpbnQoIFQgJiYgYSwgVSAmJi4uLmIgKQp7CglzdGQ6OmNvdXQgPDwgYTsKCXByaW50KCBzdGQ6OmZvcndhcmQ8VT4oIGIgKS4uLiApOwp9Cgp0ZW1wbGF0ZTwgdHlwZW5hbWUgVCwgdHlwZW5hbWUgLi4uVT4Kdm9pZCBlbWl0TG4oIFQgJiYgYSwgVSAmJi4uLmIgKQp7CglwcmludCggc3RkOjpmb3J3YXJkPFQ+KCBhICksIHN0ZDo6Zm9yd2FyZDxVPiggYiApLi4uICk7Cn0KCmludCBtYWluKCkKewoJaW50IHZtX3JlZ2lzdGVyc1tNQVhfUkVHXSA9IHsgMCB9OwoJaW50IGNvbnN0IHByb2dyYW1fY29kZVtdID0geyAweDEwOUYsIDB4MTFDOCwgMHgyMjAxLCAweDMyMDAsIDB4MDAwMCB9OwoJaW50IGluc3RydWN0aW9uX251bWJlciwgcmVnXzAsIHJlZ18xLCByZWdfMjsKCglpbnQgaW5zdHJ1Y3Rpb25fcG9pbnRlciA9IDAsIGltbWVkaWF0ZV92YWx1ZSA9IDA7CglhdXRvIGZldGNoID0gWyZpbnN0cnVjdGlvbl9wb2ludGVyLCAmcHJvZ3JhbV9jb2RlXXsKCQlyZXR1cm4gcHJvZ3JhbV9jb2RlW2luc3RydWN0aW9uX3BvaW50ZXIrK107Cgl9OwoJYXV0byBkZWNvZGUgPSBbJl0oIHVpbnQxNl90IGluc3RyTnVtYmVyICkgbXV0YWJsZSAtPiB2b2lkIHsKCQlpbnN0cnVjdGlvbl9udW1iZXIgPSAoIGluc3RyTnVtYmVyICYgMHhGMDAwICkgPj4gMTI7CgkJcmVnXzAgPSAoIGluc3RyTnVtYmVyICYgMHhGMDAgKSA+PiA4OwoJCXJlZ18xID0gKCBpbnN0ck51bWJlciAmIDB4RjAgKSA+PiA0OwoJCXJlZ18yID0gKCBpbnN0ck51bWJlciAmIDB4RiApOwoJCWltbWVkaWF0ZV92YWx1ZSA9ICggaW5zdHJOdW1iZXIgJiAweEZGICk7Cgl9OwoJYXV0byBldmFsID0gWyZdKCkgbXV0YWJsZSAtPiB2b2lkewoJCXN3aXRjaCggaW5zdHJ1Y3Rpb25fbnVtYmVyICl7CgkJCWNhc2UgMDoKCQkJCWVtaXRMbiggImhhbHQiICk7CgkJCQlicmVhazsKCQkJY2FzZSAxOgoJCQkJZW1pdExuKCAibG9hZGkgciIsIHJlZ18wLCAiICMiLCBpbW1lZGlhdGVfdmFsdWUgKTsKCQkJCXZtX3JlZ2lzdGVyc1tyZWdfMF0gPSBpbW1lZGlhdGVfdmFsdWU7CgkJCQlicmVhazsKCQkJY2FzZSAyOgoJCQkJZW1pdExuKCAiYWRkIHIiLCByZWdfMCwgIiByIiwgcmVnXzEsICIgciIsIHJlZ18yICk7CgkJCQl2bV9yZWdpc3RlcnNbcmVnXzBdID0gdm1fcmVnaXN0ZXJzW3JlZ18xXSArIHZtX3JlZ2lzdGVyc1tyZWdfMl07CgkJCQlicmVhazsKCQkJY2FzZSAzOgoJCQkJZW1pdExuKCAicHJpbnQgciIsIHJlZ18wLCAiOyAvLyIgLCB2bV9yZWdpc3RlcnNbcmVnXzBdICk7CgkJCQlicmVhazsKCQl9Cgl9OwoJaW50IGNvbnN0IGNvZGVfY291bnQgPSBzaXplb2YoIHByb2dyYW1fY29kZSApIC8gc2l6ZW9mKCBpbnQgKTsKCglbJl0oKS0+dm9pZHsKCQl3aGlsZSggaW5zdHJ1Y3Rpb25fcG9pbnRlciA8IGNvZGVfY291bnQgKXsKCQkJYXV0byBpbnN0ck51bWJlciA9IGZldGNoKCk7CgkJCWRlY29kZSggaW5zdHJOdW1iZXIgKTsKCQkJZXZhbCgpOwoJCX0KCX0oKTsKCXJldHVybiAwOwp9