Skip to content

Instantly share code, notes, and snippets.

@cluosh
Created April 21, 2022 19:33
Show Gist options
  • Save cluosh/ddfd0323273e6be9aea131e7f0a80ded to your computer and use it in GitHub Desktop.
Save cluosh/ddfd0323273e6be9aea131e7f0a80ded to your computer and use it in GitHub Desktop.
OTW Advent Challenge 2019 - Cookie Recipe Program
#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;
}
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