Created
April 21, 2022 19:33
-
-
Save cluosh/ddfd0323273e6be9aea131e7f0a80ded to your computer and use it in GitHub Desktop.
OTW Advent Challenge 2019 - Cookie Recipe Program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <unistd.h> | |
#define OP_PUSH 0x00 | |
#define OP_MIX 0x01 /* num_ingredients, type, amount, ... */ | |
#define OP_COOL 0x02 /* dough, duration */ | |
#define OP_SPLIT 0x03 /* cooled_dough, count */ | |
#define OP_ROLL 0x04 /* cooled_dough */ | |
#define OP_ENGRAVE 0x05 /* rolled_dough, form */ | |
#define OP_CUT_OUT 0x06 /* rolled_dough, form */ | |
#define OP_PLACE 0x07 /* baking_sheet, cut_out */ | |
#define OP_BAKE 0x08 /* baking_sheet, temp, minutes */ | |
#define OP_BAKING_SHEET 0x09 | |
#define OP_PRINT_FORM 0x0a /* form_parameter */ | |
#define OP_IF_ELSE 0x0b /* condition else_pc */ | |
#define OP_DEC 0x0c | |
#define OP_SWAP 0x0d | |
#define OP_DUP 0x0e | |
#define OP_JMP 0x0f /* pc */ | |
#define OP_POP 0x10 | |
#define OP_LD 0x11 /* var_id */ | |
#define OP_ST 0x12 /* var_id, value */ | |
#define OP_HLT 0x13 | |
/* | |
Program: | |
; print form for engraving | |
00626f737300000002 push 0x0200000073736f62 ; "boss" | |
0a print_form | |
000000000000000000 push 0x0 | |
12 st | |
; print form for cutting out | |
006f75746c696e6502 push 0x02656e696c74756f ; "outline" | |
0a print_form | |
000100000000000000 push 0x1 | |
12 st | |
; prepare baking sheet | |
09 baking_sheet | |
000200000000000000 push 0x2 | |
12 st | |
; list of ingredients | |
00f401000000000000 push 500 ; grams | |
000100000000000001 push 0x0100000000000001 ; type: flour | |
002c01000000000000 push 300 ; grams | |
000200000000000001 push 0x0100000000000002 ; type: butter | |
007800000000000000 push 120 ; grams | |
000300000000000001 push 0x0100000000000003 ; type: sugar | |
000100000000000000 push 1 ; nr. of packets | |
000400000000000001 push 0x0100000000000004 ; type: vanilla sugar | |
000300000000000000 push 3 ; nr. of yolks | |
000500000000000001 push 0x0100000000000005 ; type: yolks | |
000500000000000000 push 5 ; nr. of ingredients | |
01 mix | |
003c00000000000000 push 60 ; waiting time in minutes | |
0d swap | |
02 cool | |
000200000000000000 push 2 ; number of splits | |
0d swap | |
03 split | |
000200000000000000 push 2 ; number of splits | |
roll_loop: ; 0xb6 | |
0e dup | |
003501000000000000 push roll_end | |
0d swap | |
0b if_else | |
0c dec | |
0d swap | |
04 roll | |
001400000000000000 push 20 ; number of cookies per dough | |
cut_loop: ; 0xce | |
0e dup | |
000c01000000000000 push cut_end | |
0d swap | |
0b if_else | |
0c dec | |
0d swap | |
0e dup | |
000000000000000000 push 0x0 | |
11 ld | |
0d swap | |
05 engrave | |
0e dup | |
000100000000000000 push 0x1 | |
11 ld | |
0d swap | |
06 cut_out | |
000200000000000000 push 0x2 | |
11 ld | |
07 place | |
0d swap | |
00ce00000000000000 push cut_loop | |
0f jmp | |
cut_end: ; 0x10c | |
10 pop | |
10 pop | |
000a00000000000000 push 10 | |
00aa00000000000000 push 170 | |
000200000000000000 push 0x2 | |
11 ld | |
08 bake | |
00b600000000000000 push roll_loop | |
0f jmp | |
roll_end: ; 0x135 | |
13 hlt | |
*/ | |
#define DISPATCH() goto *dispatch_table[code[pc++]] | |
int main(int argc, char **argv) { | |
unsigned char code[1000]; | |
unsigned long stack[100]; | |
unsigned long vars[10]; | |
unsigned long pc, sp, tmp, i, a, b; | |
static void* dispatch_table[] = { | |
&&do_push, &&do_mix, &&do_cool, | |
&&do_split, &&do_roll, &&do_engrave, | |
&&do_cut_out, &&do_place, &&do_bake, | |
&&do_baking_sheet, &&do_print_form, &&do_if_else, | |
&&do_dec, &&do_swap, &&do_dup, &&do_jmp, | |
&&do_pop, &&do_ld, &&do_st, &&do_hlt | |
}; | |
for (i = 0; i < 1000; i++) | |
code[i] = OP_HLT; | |
read(0, code, 1000); | |
pc = 0; | |
sp = 0; | |
DISPATCH(); | |
while (1) { | |
do_push: | |
stack[sp++] = *((unsigned long *)&code[pc]); | |
pc += 8; | |
DISPATCH(); | |
do_mix: | |
write(1, "Mixing ingredients...\n", 22); | |
tmp = stack[--sp]; | |
for (i = 0; i < tmp; i++) { | |
a = stack[--sp]; | |
b = stack[--sp]; | |
switch (a & 0xf) { | |
case 0x1: | |
write(1, "Adding flour...\n", 16); | |
break; | |
case 0x2: | |
write(1, "Adding butter...\n", 17); | |
break; | |
case 0x3: | |
write(1, "Adding sugar...\n", 16); | |
break; | |
case 0x4: | |
write(1, "Adding vanilla sugar...\n", 24); | |
break; | |
case 0x5: | |
write(1, "Adding yolks...\n", 16); | |
break; | |
default: | |
write(2, "Unknown ingredient, error!\n", 27); | |
_exit(1); | |
} | |
} | |
/* Pushing dough on the stack */ | |
stack[sp++] = 0x0300000000000000; | |
DISPATCH(); | |
do_cool: | |
a = stack[--sp]; | |
b = stack[--sp]; | |
if ((a >> 56) != 0x3) { | |
write(2, "OP_COOL: Expected dough\n", 24); | |
_exit(1); | |
} | |
write(1, "Cooling...\n", 11); | |
/* Pushing cooled dough on the stack */ | |
stack[sp++] = 0x0400000000000000; | |
DISPATCH(); | |
do_split: | |
a = stack[--sp]; | |
b = stack[--sp]; | |
if ((a >> 56) != 0x4) { | |
write(2, "OP_SPLIT: Expected cooled dough\n", 32); | |
_exit(1); | |
} | |
write(1, "Splitting dough...\n", 19); | |
for (i = 0; i < b; i++) { | |
stack[sp++] = 0x0400000000000000; | |
} | |
DISPATCH(); | |
do_roll: | |
a = stack[--sp]; | |
if ((a >> 56) != 0x4) { | |
write(2, "OP_ROLL: Expected cooled dough\n", 31); | |
_exit(1); | |
} | |
write(1, "Rolling out dough...\n", 21); | |
/* Pushing cooled dough on the stack */ | |
stack[sp++] = 0x0500000000000000; | |
DISPATCH(); | |
do_engrave: | |
a = stack[--sp]; | |
b = stack[--sp]; | |
if ((a >> 56) != 0x5) { | |
write(2, "OP_ENGRAVE: Expected rolled out dough\n", 38); | |
_exit(1); | |
} | |
if ((b >> 56) != 0x8) { | |
write(2, "OP_ENGRAVE: Expected printed form\n", 34); | |
_exit(1); | |
} | |
write(1, "Engraving...\n", 13); | |
DISPATCH(); | |
do_cut_out: | |
a = stack[--sp]; | |
b = stack[--sp]; | |
if ((a >> 56) != 0x5) { | |
write(2, "OP_CUT_OUT: Expected rolled out dough\n", 38); | |
_exit(1); | |
} | |
if ((b >> 56) != 0x8) { | |
write(2, "OP_CUT_OUT: Expected printed form\n", 34); | |
_exit(1); | |
} | |
write(1, "Cutting out...\n", 15); | |
/* | |
Placing cut-out cookie on the stack. | |
You could say this is a... | |
(•_•) / ( •_•)>⌐■-■ / (⌐■_■) | |
...stack cookie. | |
*/ | |
stack[sp++] = 0x0600000000000000; | |
DISPATCH(); | |
do_place: | |
a = stack[--sp]; | |
b = stack[--sp]; | |
if ((a >> 56) != 0x7) { | |
write(2, "OP_PLACE: Expected baking sheet\n", 32); | |
_exit(1); | |
} | |
if ((b >> 56) != 0x6) { | |
write(2, "OP_PLACE: Expected cut-out cookie\n", 34); | |
_exit(1); | |
} | |
write(1, "Placing cookie on baking sheet...\n", 34); | |
DISPATCH(); | |
do_bake: | |
a = stack[--sp]; | |
b = stack[--sp]; | |
tmp = stack[--sp]; | |
if ((a >> 56) != 0x7) { | |
write(2, "OP_BAKE: Expected baking sheet\n", 31); | |
_exit(1); | |
} | |
if (b > 250) { | |
write(2, "OP_BAKE: The temperature is too damn high\n", 42); | |
_exit(1); | |
} | |
write(1, "Baking...\n", 10); | |
write(1, "Done! Enjoy your cookies.\n", 26); | |
DISPATCH(); | |
do_baking_sheet: | |
stack[sp++] = 0x0700000000000000; | |
DISPATCH(); | |
do_print_form: | |
a = stack[--sp]; | |
if ((a >> 56) != 0x2) { | |
write(2, "OP_PRINT_FORM: Expected form\n", 29); | |
_exit(1); | |
} | |
write(1, "Printing form: ", 15); | |
write(1, &a, 7); | |
write(1, "...\n", 4); | |
stack[sp++] = 0x0800000000000000; | |
DISPATCH(); | |
do_if_else: | |
a = stack[--sp]; | |
b = stack[--sp]; | |
if (a == 0) { | |
pc = b; | |
} | |
DISPATCH(); | |
do_dec: | |
stack[sp - 1]--; | |
DISPATCH(); | |
do_swap: | |
tmp = stack[sp - 2]; | |
stack[sp - 2] = stack[sp - 1]; | |
stack[sp - 1] = tmp; | |
DISPATCH(); | |
do_dup: | |
stack[sp++] = stack[sp - 1]; | |
DISPATCH(); | |
do_jmp: | |
pc = stack[--sp]; | |
DISPATCH(); | |
do_pop: | |
sp--; | |
DISPATCH(); | |
do_ld: | |
stack[sp - 1] = vars[stack[sp - 1]]; | |
DISPATCH(); | |
do_st: | |
tmp = stack[--sp]; | |
vars[tmp] = stack[--sp]; | |
DISPATCH(); | |
do_hlt: | |
return 0; | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
00000000: 0062 6f73 7300 0000 020a 0000 0000 0000 .boss........... | |
00000010: 0000 0012 006f 7574 6c69 6e65 020a 0001 .....outline.... | |
00000020: 0000 0000 0000 0012 0900 0200 0000 0000 ................ | |
00000030: 0000 1200 f401 0000 0000 0000 0001 0000 ................ | |
00000040: 0000 0000 0100 2c01 0000 0000 0000 0002 ......,......... | |
00000050: 0000 0000 0000 0100 7800 0000 0000 0000 ........x....... | |
00000060: 0003 0000 0000 0000 0100 0100 0000 0000 ................ | |
00000070: 0000 0004 0000 0000 0000 0100 0300 0000 ................ | |
00000080: 0000 0000 0005 0000 0000 0000 0100 0500 ................ | |
00000090: 0000 0000 0000 0100 3c00 0000 0000 0000 ........<....... | |
000000a0: 0d02 0002 0000 0000 0000 000d 0300 0200 ................ | |
000000b0: 0000 0000 0000 0e00 3501 0000 0000 0000 ........5....... | |
000000c0: 0d0b 0c0d 0400 1400 0000 0000 0000 0e00 ................ | |
000000d0: 0c01 0000 0000 0000 0d0b 0c0d 0e00 0000 ................ | |
000000e0: 0000 0000 0000 110d 050e 0001 0000 0000 ................ | |
000000f0: 0000 0011 0d06 0002 0000 0000 0000 0011 ................ | |
00000100: 070d 00ce 0000 0000 0000 000f 1010 000a ................ | |
00000110: 0000 0000 0000 0000 aa00 0000 0000 0000 ................ | |
00000120: 0002 0000 0000 0000 0011 0800 b600 0000 ................ | |
00000130: 0000 0000 0f13 ...... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment