%include "utils.s" global _start [bits 32] [section .text] %define FILENAME "input" ;%define FILENAME "input_test" _start: mov esi, file load_rule: xor ebx, ebx ; id .get_id: lodsb cmp al, '{' je .got_id shl ebx, 8 mov bl, al ; add new byte jmp .get_id .got_id: call id_to_idx ; idx in EDX shl edx, 4 ; *16 lea edi, [rules+edx] ; rule ptr .get_rules: ; --- rule format --- ; [ 16 ] ; [ 4 ][ 4 ][ 4 ][ 4 ] ; [ 2 ] [ 2 ][ 2 ] [ 2 ][ 2 ] [ 2 ][ 2 ] [ 2 ] ; [bound] [ vdr ][bound] [ vdr ][bound] [ vdr ][bound] [ vdr ] ; var, dir, & res ; FEDCBA9876543210 ; --- var --- 76543210 ; ...............1 -> Always ; .............00. -> a (ASCII .1100...) ; .............01. -> m (ASCII .1101...) ; .............10. -> s (ASCII .1110...) ; .............11. -> x (ASCII .1111...) ; --- dir --- ; ............0... -> < (ASCII .0....0.) ; ............1... -> > (ASCII .0....1.) ; --- res --- ; 111111111111.... -> R (ASCII .10....0 bit 0 - 1 -> ..111) ; 000000000000.... -> A (ASCII .10....1 bit 0 - 1 -> ..000) ; NNNNNNNNNNNN.... -> eval xor ecx, ecx ; output vdr & bound xor eax, eax ; input byte lodsb ; lowercase alpha or RA bt ax, 5 ; low for RA, high for alpha jc .alpha ; immediately finish with R or A or cx, 1 ; Always and ax, 1 ; bit 0 of ASCII dec ax ; R -> -1, A -> 0 shl ax, 4 ; correct position or cx, ax jmp .done .alpha: ; either [xmas][><] or a multi-char ID mov ebx, eax ; save last input lodsb ; next byte bt ax, 6 ; bit 6 low for >< jnc .is_check ; immediately finish by evaluating ID .imm_got_id_byte: shl ebx, 8 mov bl, al .imm_get_full_id: lodsb cmp al, ',' ; ends , or } je .imm_got_id cmp al, '}' jne .imm_got_id_byte .imm_got_id: call id_to_idx ; idx in EDX or cx, 1 ; out.var <- Always shl edx, 4 ; correct position or cx, dx ; out.res <- idx jmp .done .is_check: and bx, 3<<3 shr bx, 2 or cx, bx ; out.var <- bits 3&4 of last and ax, 1<<1 shl ax, 2 or cx, ax ; out.dir <- bit 1 of ASCII call dec_parse mov bx, cx mov cx, ax shl ecx, 16 mov cx, bx ; out.bound <- parse_dec ; parse_dec skips the : so get the res lodsb bt ax, 5 jc .chk_id ; res is R or A and ax, 1 dec ax shl ax, 4 or cx, ax ; out.res <- bit 0 of ASCII - 1 jmp .done .chk_id: ; res is ID xor ebx, ebx jmp .chk_got_id_byte .chk_next_byte: lodsb cmp al, ',' ; ends , je .chk_got_id .chk_got_id_byte: shl ebx, 8 mov bl, al jmp .chk_next_byte .chk_got_id: call id_to_idx ; idx in EDX shl edx, 4 or cx, dx ; out.res <- idx .done: mov eax, ecx stosd cmp byte [esi-1], ',' je .get_rules cmp byte [esi], ',' je .next_rule cmp byte [esi-1], '}' je .next_line cmp byte [esi], '}' je .next_line cmp byte [esi-1], 10 je .check_rules_over call newline .wtf: p_string wtf jmp .wtf .next_rule: inc esi jmp .get_rules .next_line: lodsb cmp al, 10 ; \n jne .next_line .check_rules_over: cmp byte [esi], 10 jne load_rule rules_over: mov eax, [next_rule_idx] dec eax call print_dec call newline ; find rule 'in' mov ebx, 'ni' call id_to_idx mov [in_idx], edx mov eax, edx call print_dec call space shl edx, 4 movzx eax, word [rules+edx] call print_dec call space movzx eax, word [rules+edx+2] call print_dec call newline ; we're now reading in the inputs to test ; find the next { proc_next_input: mov ecx, 32 mov al, '{' xchg edi, esi repne scasb xchg edi, esi cmp esi, file.over jae game_over ; get 4 nums, x m a s (ecx edx edi ebp) .get_x: call dec_parse jc .get_x mov ecx, eax .get_m: call dec_parse jc .get_m mov edx, eax .get_a: call dec_parse jc .get_a mov edi, eax .get_s: call dec_parse jc .get_s mov ebp, eax ; go through the rules push esi mov ebx, [in_idx] call check_rule add ecx, edx add ecx, edi add ecx, ebp not eax movzx eax, al test eax, eax cmovnz eax, ecx add [final_value], eax pop esi jmp proc_next_input ; rule idx in EBX, xmas in ecx edx edi ebp ; return in EAX check_rule: sub esp, 4 .inner: shl ebx, 4 lea esi, [rules+ebx] ; rule ptr mov [esp], esi .next_rule: mov esi, [esp] lodsd ; rule mov [esp], esi bt ax, 0 ; always jc .always ; .............00. -> a ; .............01. -> m ; .............10. -> s ; .............11. -> x ; ............0... -> < ; ............1... -> > mov esi, eax mov ebx, eax and bl, 0b110 ; var cmp bl, 0b000 cmove eax, edi cmp bl, 0b010 cmove eax, edx cmp bl, 0b100 cmove eax, ebp cmp bl, 0b110 cmove eax, ecx mov ebx, esi shr ebx, 16 ; rule.bound bt esi, 3 ; rule.dir jnc .less cmp eax, ebx jg .match jmp .next_rule .less: cmp eax, ebx jge .next_rule .match: mov eax, esi .always: shr ax, 4 ; rule.res test ax, ax jz .return_res cmp ax, 0x0FFF je .return_res ; nested rule movzx ebx, ax jmp .inner .return_res: movzx eax, ax add esp, 4 ret game_over: mov eax, [final_value] call print_dec call newline jmp exit ; ID in EBX, IDX return in EDX id_to_idx: xor edx, edx .test: cmp [rule_idx_to_id+edx*4], ebx je .found inc edx cmp edx, [next_rule_idx] jb .test ; new ID mov [rule_idx_to_id+edx*4], ebx inc dword [next_rule_idx] .found: ret [section .data] next_rule_idx: dd 1 final_value: dd 0 in_idx: dd 0 file: incbin FILENAME .over: [section .bss] rule_idx_to_id: resd 1024 rules: resd 1024*4 [section .rodata] wtf: db "WTF" .over: