Browse Source

Added cc_x86 in M1 for x86

Jeremiah Orians 4 years ago
parent
commit
f482b010f5
2 changed files with 4975 additions and 1 deletions
  1. 1 1
      CHANGELOG.org
  2. 4974 0
      Linux Bootstrap/x86/cc_x86.M1

+ 1 - 1
CHANGELOG.org

@@ -33,7 +33,7 @@ Imported from mescc-tools:
 		hex1 in hex0, hex1, M1 and NASM
 		hex2 in hex1, hex2, M1 and NASM
 		M0 in hex2, M1 and NASM
-		cc_x86 in NASM
+		cc_x86 in M1 and NASM
 
 ** Changed
 Reduced stack usage thanks to akkartik

+ 4974 - 0
Linux Bootstrap/x86/cc_x86.M1

@@ -0,0 +1,4974 @@
+;; Copyright (C) 2017 Jeremiah Orians
+;; This file is part of stage0.
+;;
+;; stage0 is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; stage0 is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with stage0.  If not, see <http://www.gnu.org/licenses/>.
+
+DEFINE ADDI8_EAX 83C0
+DEFINE ADDI8_EBX 83C3
+DEFINE ADDI8_ECX 83C1
+DEFINE ADDI8_EDX 83C2
+DEFINE ADDI8_ESI 83C6
+DEFINE ADD_eax_into_ebx 01C3
+DEFINE ADD_ebx_into_eax 01D8
+DEFINE ADD_ecx_into_eax 01C8
+DEFINE ADD_edi_into_ecx 01F9
+DEFINE AND_EAX_EBX 21D8
+DEFINE ANDI32_EAX 25
+DEFINE CALL_EAX FFD0
+DEFINE CALL32 E8
+DEFINE CMPI8_EAX 83F8
+DEFINE CMPI8_EBP 83fd
+DEFINE CMPI8_EBX 83FB
+DEFINE CMPI8_ECX 83F9
+DEFINE CMPI8_EDX 83FA
+DEFINE CMPI8_ESI 83FE
+DEFINE CMP_EAX_EBX 39D8
+DEFINE CMP_EAX_ECX 39C8
+DEFINE CMP_EBX_ECX 39D9
+DEFINE CMP_ECX_EBX 39CB
+DEFINE CMP_EDI_ESI 39FE
+DEFINE CMP_EBX_EDX 39D3
+DEFINE COPY_EAX_to_EBP 89C5
+DEFINE COPY_EAX_to_EBX 89C3
+DEFINE COPY_EAX_to_ECX 89C1
+DEFINE COPY_EAX_to_EDX 89C2
+DEFINE COPY_EAX_to_ESI 89C6
+DEFINE COPY_EBP_to_EAX 89E8
+DEFINE COPY_EBX_to_EAX 89D8
+DEFINE COPY_EBX_to_ECX 89D9
+DEFINE COPY_EBX_to_EDX 89DA
+DEFINE COPY_ECX_to_EAX 89C8
+DEFINE COPY_ECX_to_EBX 89CB
+DEFINE COPY_EDI_to_ESI 89FE
+DEFINE COPY_EDX_to_EAX 89D0
+DEFINE COPY_EDX_to_EBP 89D5
+DEFINE COPY_EDX_to_EBX 89D3
+DEFINE COPY_ESI_to_EAX 89F0
+DEFINE COPY_ESI_to_EDI 89F7
+DEFINE IDIV_EBX F7FB
+DEFINE IMUL_EAX_by_EBX 0FAFC3
+DEFINE IMULI8_EAX 6BC0
+DEFINE IMULI8_EBP 6BED
+DEFINE INT_80 CD80
+DEFINE JBE8 76
+DEFINE JE32 0F84
+DEFINE JG32 0F8F
+DEFINE JG8 7F
+DEFINE JL32 0F8C
+DEFINE JLE32 0F8E
+DEFINE JMP32 E9
+DEFINE JNE32 0F85
+DEFINE LEA32_ECX_from_esp 8D0C24
+DEFINE LOAD32_Absolute32_eax A1
+DEFINE LOAD32_Absolute32_ebx 8B1D
+DEFINE LOAD32_Absolute32_ecx 8B0D
+DEFINE LOAD32_EAX_from_EAX 8B00
+DEFINE LOAD32_EAX_from_EAX_Immediate8 8B40
+DEFINE LOAD32_EAX_from_EBP_Immediate8 8B45
+DEFINE LOAD32_EAX_from_EBX 8B03
+DEFINE LOAD32_EAX_from_EBX_Immediate8 8B43
+DEFINE LOAD32_EAX_from_ECX_Immediate8 8B41
+DEFINE LOAD32_EAX_from_EDX_Immediate8 8B42
+DEFINE LOAD32_EBP_from_EBP 8B6D00
+DEFINE LOAD32_EBX_from_EAX_Immediate8 8B58
+DEFINE LOAD32_EBX_from_EBX 8B1B
+DEFINE LOAD32_EBX_from_EBX_Immediate8 8B5B
+DEFINE LOAD32_EBX_from_ECX_Immediate8 8B59
+DEFINE LOAD32_ECX_from_EAX_Immediate8 8B48
+DEFINE LOAD32_ECX_from_EBX 8B0B
+DEFINE LOAD32_ECX_from_ECX 8B09
+DEFINE LOAD32_ECX_from_ECX_Immediate8 8B49
+DEFINE LOAD32_ECX_from_EDX_Immediate8 8B4A
+DEFINE LOAD32_EDI_from_EDX_Immediate8 8B7A
+DEFINE LOAD32_EDX_from_EDX_Immediate8 8B52
+DEFINE LOAD8_al_from_EAX 8A00
+DEFINE LOAD8_al_from_EBX 8A03
+DEFINE LOAD8_al_from_ECX 8A01
+DEFINE LOAD8_al_from_EDX 8A02
+DEFINE LOAD8_bl_from_EBX 8A1B
+DEFINE LOAD8_bl_from_ECX 8A19
+DEFINE LOAD8_bl_from_EDX 8A1A
+DEFINE LOAD8_cl_from_EBX 8A0B
+DEFINE LOAD8_cl_from_EBX_Immediate8 8A4B
+DEFINE LOADI32_EAX B8
+DEFINE LOADI32_EBX BB
+DEFINE LOADI32_ECX B9
+DEFINE LOADI32_EDI BF
+DEFINE LOADI32_EDX BA
+DEFINE LOADI32_ESI BE
+DEFINE MOVZX_al 0FB6C0
+DEFINE MOVZX_bl 0FB6DB
+DEFINE MOVZX_cl 0FB6C9
+DEFINE NULL 00000000
+DEFINE POP_EAX 58
+DEFINE POP_EBP 5D
+DEFINE POP_EBX 5B
+DEFINE POP_ECX 59
+DEFINE POP_EDI 5F
+DEFINE POP_EDX 5A
+DEFINE POP_ESI 5E
+DEFINE PUSH_EAX 50
+DEFINE PUSH_EBP 55
+DEFINE PUSH_EBX 53
+DEFINE PUSH_ECX 51
+DEFINE PUSH_EDI 57
+DEFINE PUSH_EDX 52
+DEFINE PUSH_ESI 56
+DEFINE RETURN C3
+DEFINE SALI8_EAX C1E0
+DEFINE SHRI8_EAX C1E8
+DEFINE SHRI8_EBX C1EB
+DEFINE STORE32_Absolute32_eax A3
+DEFINE STORE32_Absolute32_ebx 891D
+DEFINE STORE32_Absolute32_ecx 890D
+DEFINE STORE32_Absolute32_edx 8915
+DEFINE STORE32_EAX_into_EBP_Immediate8 8945
+DEFINE STORE32_EAX_into_EBX 8903
+DEFINE STORE32_EAX_into_ECX_Immediate8 8941
+DEFINE STORE32_EAX_into_EDX 8902
+DEFINE STORE32_EAX_into_EDX_Immediate8 8942
+DEFINE STORE32_EBP_into_EDX_Immediate8 896A
+DEFINE STORE32_EBX_into_EAX 8918
+DEFINE STORE32_EBX_into_EAX_Immediate8 8958
+DEFINE STORE32_EBX_into_EDX_Immediate8 895A
+DEFINE STORE32_ECX_into_EAX 8908
+DEFINE STORE32_ECX_into_EAX_Immediate8 8948
+DEFINE STORE32_ECX_into_EDX_Immediate8 894A
+DEFINE STORE32_EDX_into_EAX_Immediate8 8950
+DEFINE STORE32_EDX_into_EBP_Immediate8 8955
+DEFINE STORE32_ESI_into_EBP_Immedate8 8975
+DEFINE STORE32_ESI_into_EDX_Immedate8 8972
+DEFINE STORE8_al_into_Address_EBX 8803
+DEFINE STORE8_al_into_Address_ECX 8801
+DEFINE STORE8_al_into_Address_ESI 8806
+DEFINE STORE8_bl_into_Address_ECX 8819
+DEFINE SUBI8_EAX 83E8
+DEFINE SUBI8_ECX 83E9
+DEFINE SUBI8_ESI 83EE
+DEFINE SWAP_EAX_EBX 93
+
+
+	;; Register usage:
+	;; EAX => Temps
+
+	;; Struct TYPE format: (size 28)
+	;; NEXT => 0
+	;; SIZE => 4
+	;; OFFSET => 8
+	;; INDIRECT => 12
+	;; MEMBERS => 16
+	;; TYPE => 20
+	;; NAME => 24
+
+	;; Struct TOKEN_LIST format: (size 20)
+	;; NEXT => 0
+	;; LOCALS/PREV => 4
+	;; S => 8
+	;; TYPE => 12
+	;; ARGS/DEPTH => 16
+
+; Where the ELF Header is going to hit
+; Simply jump to _start
+; Our main function
+:_start
+	POP_EAX                                     ;·Get·the·number·of·arguments
+	POP_EBX                                     ;·Get·the·program·name
+	POP_EBX                                     ;·Get·the·actual·input name
+	LOADI32_ECX %0                              ;·prepare·read_only
+	LOADI32_EAX %5                              ;·the·syscall·number·for·open()
+	INT_80                                      ; Now open that damn file
+	STORE32_Absolute32_eax &Input_file          ; Preserve the file pointer we were given
+
+	POP_EBX                                     ;·Get·the·actual·output name
+	LOADI32_ECX %577                            ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC
+	LOADI32_EDX %384                            ; Prepare file as RW for owner only (600 in octal)
+	LOADI32_EAX %5                              ;·the·syscall·number·for·open()
+	INT_80                                      ; Now open that damn file
+	CMPI8_EAX !0                                ; Check for missing output
+	JG32 %_start_out                            ; Have real input
+	LOADI32_EAX %1                              ; Use stdout
+
+:_start_out
+	STORE32_Absolute32_eax &Output_file         ; Preserve the file pointer we were given
+
+	LOADI32_EAX %45                             ; the Syscall # for SYS_BRK
+	LOADI32_EBX %0                              ; Get current brk
+	INT_80                                      ; Let the kernel do the work
+	STORE32_Absolute32_eax &MALLOC              ; Set our malloc pointer
+	LOADI32_EAX %0                              ; HEAD = NULL
+	CALL32 %read_all_tokens                     ; Read all tokens
+	CALL32 %Reverse_List                        ; Reverse order
+;	CALL32 %debug_list                          ; Try to figure out what is wrong
+	STORE32_Absolute32_eax &global_token        ; Set global_token
+	CALL32 %program                             ; Convert into program
+	LOADI32_EAX &header_string1                 ; Our header string
+	CALL32 %File_Print                          ; Print it
+	LOAD32_Absolute32_eax &output_list          ; Our output_list
+	CALL32 %recursive_output                    ; Print core program
+;	LOADI32_EAX &header_string2                 ; Our Enable debug
+;	CALL32 %File_Print                          ; Print it
+	LOADI32_EAX &header_string3                 ; Our second label
+	CALL32 %File_Print                          ; Print it
+	LOAD32_Absolute32_eax &globals_list         ; Our globals
+	CALL32 %recursive_output                    ; Get them
+	LOADI32_EAX &header_string4                 ; Our final header
+	CALL32 %File_Print                          ; Print it
+	LOAD32_Absolute32_eax &strings_list         ; Our strings
+	CALL32 %recursive_output                    ; Get them
+	LOADI32_EAX &header_string5                 ; Make this a bare assembly
+	CALL32 %File_Print                          ; Print it
+
+:Done
+	; program completed Successfully
+	LOADI32_EBX %0                              ; All is well
+	LOADI32_EAX %1                              ; put the exit syscall number in eax
+	INT_80                                      ; Call it a good day
+
+:header_string1  "
+# Core program
+"
+:header_string2  "
+:ELF_data
+"
+:header_string3  "
+# Program global variables
+"
+:header_string4  "
+# Program strings
+"
+:header_string5  "
+:ELF_end
+"
+
+
+;; read_all_tokens function
+;; Recieves Token_List* in EAX
+;; Tokenizes all input and returns updated list in EAX
+;; Returns TOKEN in EAX
+;; Uses EAX for C
+:read_all_tokens
+	STORE32_Absolute32_eax &Token
+	CALL32 %fgetc
+:read_all_tokens_loop
+	CMPI8_EAX !-4                               ; Check for EOF
+	JE32 %read_all_tokens_done                  ; Stop if found
+	CALL32 %get_token                           ; Read all tokens
+	JMP32 %read_all_tokens_loop                 ; Loop
+:read_all_tokens_done
+	LOAD32_Absolute32_eax &Token
+	RETURN
+
+
+;; get_token function
+;; Recieves INT in EAX
+;; Makes a list of TOKEN_LIST
+;; C and STRING_INDEX are stored in memory, ECX is used for S and EDX is used for current
+;; Returns C in EAX
+:get_token
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+
+	STORE32_Absolute32_eax &C                   ; Set C
+
+	LOADI32_EAX %20                             ; Malloc CURRENT
+	CALL32 %malloc                              ; Get Pointer
+	COPY_EAX_to_EDX                             ; Set CURRENT
+
+	LOADI32_EAX %256                            ; Malloc the string
+	CALL32 %malloc                              ; Get pointer to S
+	COPY_EAX_to_ECX                             ; Set S
+	STORE32_ECX_into_EDX_Immediate8 !8          ; CURRENT->S = S
+:reset
+	STORE32_Absolute32_ecx &string_index        ; S[0]
+	LOAD32_Absolute32_eax &C                    ; Using C
+
+	CALL32 %clear_white_space                   ; Clear WhiteSpace
+	STORE32_Absolute32_eax &C                   ; Set C
+
+	CMPI8_EAX !-4                               ; Check for EOF
+	JE32 %get_token_abort                       ; if EOF abort
+
+	CMPI8_EAX !35                               ; Check for '#'
+	JNE32 %get_token_alpha                      ; Nope
+
+	;; Deal with # line comments
+	CALL32 %purge_macro                         ; Let it handle it
+	STORE32_Absolute32_eax &C                   ; Set C
+	JMP32 %reset                                ; Try again
+
+:get_token_alpha
+	LOAD32_Absolute32_eax &C                    ; Send C
+	LOADI32_EBX &alphas                         ; Get alphanumerics
+	CALL32 %In_Set                              ; See if in set
+	CMPI8_EAX !1                                ; IF TRUE
+	JNE32 %get_token_symbol                     ; Otherwise
+
+	;; Store keywords
+	LOAD32_Absolute32_eax &C                    ; Send C
+	CALL32 %preserve_keyword                    ; Store
+	STORE32_Absolute32_eax &C                   ; Set C
+	JMP32 %get_token_done                       ; Be done with this token
+
+:get_token_symbol
+	LOAD32_Absolute32_eax &C                    ; Send C
+	LOADI32_EBX &symbols                        ; Get symbols
+	CALL32 %In_Set                              ; See if in set
+	CMPI8_EAX !1                                ; IF TRUE
+	JNE32 %get_token_strings                    ; Otherwise
+
+	;; Store symbols
+	LOAD32_Absolute32_eax &C                    ; Send C
+	CALL32 %preserve_symbol                     ; Store
+	STORE32_Absolute32_eax &C                   ; Set C
+	JMP32 %get_token_done                       ; Be done with this token
+
+:get_token_strings
+	LOAD32_Absolute32_eax &C                    ; Send C
+	LOADI32_EBX &strings                        ; Get symbols
+	CALL32 %In_Set                              ; See if in set
+	CMPI8_EAX !1                                ; IF TRUE
+	JNE32 %get_token_comment                    ; Otherwise
+
+	;; Store String
+	LOAD32_Absolute32_eax &C                    ; Send C
+	CALL32 %consume_word                        ; Store
+	STORE32_Absolute32_eax &C                   ; Set C
+	JMP32 %get_token_done                       ; Be done with this token
+
+:get_token_comment
+	LOAD32_Absolute32_eax &C                    ; Send C
+	CMPI8_EAX !47                               ; IF '/' == C
+	JNE32 %get_token_else                       ; Otherwise
+
+	CALL32 %consume_byte                        ; Hope it just is '/'
+	STORE32_Absolute32_eax &C                   ; Set C
+
+	CMPI8_EAX !42                               ; IF '*' we have '/*'
+	JNE32 %get_token_comment_line               ; Check for '//'
+
+	;; Deal with /* block comments */
+	CALL32 %fgetc                               ; get next C
+	STORE32_Absolute32_eax &C                   ; Set C
+:get_token_comment_block_outer
+	LOAD32_Absolute32_eax &C                    ; Using C
+	CMPI8_EAX !47                               ; IF '/' != C
+	JE32 %get_token_comment_block_done          ; be done
+
+:get_token_comment_block_inner
+	LOAD32_Absolute32_eax &C                    ; Using C
+	CMPI8_EAX !42                               ; IF '*' != C
+	JE32 %get_token_comment_block_iter          ; jump over
+
+	;; Deal with inner loop
+	CALL32 %fgetc                               ; get next C
+	STORE32_Absolute32_eax &C                   ; Set C
+	JMP32 %get_token_comment_block_inner        ; keep going
+
+:get_token_comment_block_iter
+	CALL32 %fgetc                               ; get next C
+	STORE32_Absolute32_eax &C                   ; Set C
+	JMP32 %get_token_comment_block_outer
+
+:get_token_comment_block_done
+	CALL32 %fgetc                               ; get next C
+	STORE32_Absolute32_eax &C                   ; Set C
+	JMP32 %reset                                ; throw away, try again
+
+:get_token_comment_line
+	CMPI8_EAX !47                               ; IF '/' we have //
+	JNE32 %get_token_done                       ; keep if just '/'
+
+	;; Deal with // line comment
+	CALL32 %fgetc                               ; drop to match
+	STORE32_Absolute32_eax &C                   ; Set C
+	JMP32 %reset                                ; throw away, try again
+
+:get_token_else
+	LOAD32_Absolute32_eax &C                    ; Send C
+	CALL32 %consume_byte
+	STORE32_Absolute32_eax &C                   ; Set C
+
+:get_token_done
+	LOAD32_Absolute32_eax &Token                ; TOKEN
+	STORE32_EAX_into_EDX_Immediate8 !4          ; CURRENT->PREV = TOKEN
+	STORE32_EAX_into_EDX                        ; CURRENT->NEXT = TOKEN
+	STORE32_Absolute32_edx &Token               ; TOKEN = CURRENT
+
+:get_token_abort
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	LOAD32_Absolute32_eax &C                    ; Return C
+	RETURN
+
+
+;; Malloc isn't actually required if the program being built fits in the initial memory
+;; However, it doesn't take much to add it.
+;; Requires [MALLOC] to be initialized and EAX to have the number of desired bytes
+:malloc
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	LOAD32_Absolute32_ebx &MALLOC               ; Using the current pointer
+	ADD_eax_into_ebx                            ; Request the number of desired bytes
+	LOADI32_EAX %45                             ; the Syscall # for SYS_BRK
+	INT_80                                      ; call the Kernel
+	LOAD32_Absolute32_eax &MALLOC               ; Return pointer
+	STORE32_Absolute32_ebx &MALLOC              ; Update pointer
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; clear_white_space function
+;; Recieves INT C in EAX
+;; Returns first non-whitespace char in EAX
+:clear_white_space
+	CMPI8_EAX !32                               ; Check for ' '
+	JE32 %clear_white_space_wipe                ; wipe it out
+
+	CMPI8_EAX !10                               ; Check for '\n'
+	JE32 %clear_white_space_wipe                ; wipe it output
+
+	CMPI8_EAX !9                                ; Check for '\t'
+	JNE32 %clear_white_space_done               ; looks like non-whitespace
+
+:clear_white_space_wipe
+	CALL32 %fgetc                               ; Read a new byte
+	CMPI8_EAX !-4                               ; Check for EOF
+	JE32 %clear_white_space_done                ; Short circuit
+	JMP32 %clear_white_space                    ; iterate
+
+:clear_white_space_done
+	RETURN
+
+
+;; In_Set function
+;; Recieves Char C in EAX and CHAR* in EBX
+;; Returns 1 if true, zero if false in EAX
+:In_Set
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+:In_Set_loop
+	LOAD8_cl_from_EBX                           ; Read char
+	MOVZX_cl                                    ; Zero extend it
+
+	CMP_EAX_ECX                                 ; See if they match
+	JE32 %In_Set_True                           ; return true
+
+	CMPI8_ECX !0                                ; Check for NULL
+	JE32 %In_Set_False                          ; return false
+
+	ADDI8_EBX !1                                ; s = s + 1
+	JMP32 %In_Set_loop                          ; Keep looping
+
+:In_Set_True
+	LOADI32_EAX %1                              ; Set True
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:In_Set_False
+	LOADI32_EAX %0                              ; Set FALSE
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:alphas  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
+:symbols  "<=>|&!-"
+:strings  '22 27 00'
+
+
+;; purge_macro function
+;; Recieves CH in EAX
+;; Reads chars until Line feed is read
+;; returns line feed
+:purge_macro
+	CALL32 %fgetc                               ; read next char
+	CMPI8_EAX !10                               ; Check for '\n'
+	JNE32 %purge_macro                          ; Keep going
+	RETURN
+
+
+;; preserve_keyword function
+;; Recieves INT C in EAX
+;; collects all chars in keyword
+;; Returns C in EAX
+;; Uses ECX for INT C
+:preserve_keyword
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_ECX                             ; Setup C
+	LOADI32_EBX &alphas                         ; Concerning ourselves with "abc.."
+:preserve_keyword_loop
+	CALL32 %In_Set                              ; Check if alphanumerics
+	CMPI8_EAX !1                                ; IF TRUE
+	JNE32 %preserve_keyword_label               ; Otherwise check for label
+
+	COPY_ECX_to_EAX                             ; Pass C
+	CALL32 %consume_byte                        ; consume that byte
+	COPY_EAX_to_ECX                             ; Update C
+	JMP32 %preserve_keyword_loop                ; keep looping
+
+:preserve_keyword_label
+	COPY_ECX_to_EAX                             ; Fix return
+	CMPI8_EAX !58                               ; Check for ':'
+	JNE32 %preserve_keyword_done                ; be done
+
+	;; Fix our goto label
+	CALL32 %fixup_label                         ; Fix the label
+	LOADI32_EAX %32                             ; Return Whitespace
+
+:preserve_keyword_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; preserve_symbol function
+;; Recieves INT C in EAX
+;; collects all chars in symbol
+;; Returns C in EAX
+;; Uses ECX for INT C
+:preserve_symbol
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_ECX                             ; Setup C
+	LOADI32_EBX &symbols                        ; Concerning ourselves with "<=>.."
+:preserve_symbol_loop
+	CALL32 %In_Set                              ; Check if alphanumerics
+	CMPI8_EAX !1                                ; IF TRUE
+	JNE32 %preserve_symbol_done                 ; Otherwise be done
+
+	COPY_ECX_to_EAX                             ; Pass C
+	CALL32 %consume_byte                        ; consume that byte
+	COPY_EAX_to_ECX                             ; Update C
+	JMP32 %preserve_symbol_loop                 ; keep looping
+
+:preserve_symbol_done
+	COPY_ECX_to_EAX                             ; Fix return
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; consume_word function
+;; recieves INT C in EAX
+;; returns INT C in EAX
+;; Uses EAX for C, EBX for FREQ and ECX for ESCAPE
+:consume_word
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_EBX                             ; FREQ = C
+	LOADI32_ECX %0                              ; ESCAPE = FALSE
+:consume_word_loop
+	CMPI8_ECX !0                                ; IF !ESCAPE
+	JNE32 %consume_word_escape                  ; Enable escape
+
+	CMPI8_EAX !92                               ; if '\\'
+	JNE32 %consume_word_iter                    ; keep state
+
+	LOADI32_ECX %1                              ; ESCAPE = TRUE
+	JMP32 %consume_word_iter                    ; keep going
+
+:consume_word_escape
+	LOADI32_ECX %0                              ; ESCAPE = FALSE
+
+:consume_word_iter
+	CALL32 %consume_byte                        ; read next char
+
+	CMPI8_ECX !0                                ; IF ESCAPE
+	JNE32 %consume_word_loop                    ; keep looping
+
+	CMP_EAX_EBX                                 ; IF C != FREQ
+	JNE32 %consume_word_loop                    ; keep going
+
+	CALL32 %fgetc                               ; return next char
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; consume_byte function
+;; Recieves INT C in EAX
+;; Inserts C into string S, updates String S
+;; Returns Next char in EAX
+:consume_byte
+	PUSH_EBX                                    ; Protect EBX
+	LOAD32_Absolute32_ebx &string_index         ; S[0]
+	STORE8_al_into_Address_EBX                  ; S[0] = C
+	ADDI8_EBX !1                                ; S = S + 1
+	STORE32_Absolute32_ebx &string_index        ; Update S
+	CALL32 %fgetc
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; fixup_label function
+;; Recieves S in ECX
+;; prepends ':' to string and returns registers un changed
+;; Uses EAX for HOLD, EBX for PREV and ECX for S[0]
+:fixup_label
+	PUSH_EAX                                    ; Protect EAX
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOADI32_EAX %58                             ; HOLD = ':'
+	LOAD32_ECX_from_EDX_Immediate8 !8           ; HOLD_STRING[0]
+:fixup_label_loop
+	COPY_EAX_to_EBX                             ; PREV = HOLD
+	LOAD8_al_from_ECX                           ; HOLD = HOLD_STRING[I]
+	MOVZX_al                                    ; make useful
+	STORE8_bl_into_Address_ECX                  ; HOLD_STRING[I] = PREV
+	ADDI8_ECX !1                                ; I = I + 1
+	CMPI8_EAX !0                                ; IF NULL == HOLD
+	JNE32 %fixup_label_loop                     ; Keep looping
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	POP_EAX                                     ; Restore EAX
+	RETURN
+
+
+;; fgetc function
+;; Loads FILE* from [INPUT_FILE]
+;; Returns -4 (EOF) or char in EAX
+:fgetc
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	LOADI32_EAX %-4                             ; Put EOF in eax
+	PUSH_EAX                                    ; Assume bad (If nothing read, value will remain EOF)
+	LEA32_ECX_from_esp                          ; Get stack address
+	LOAD32_Absolute32_ebx &Input_file           ; Where are we reading from
+	LOADI32_EAX %3                              ; the syscall number for read
+	LOADI32_EDX %1                              ; set the size of chars we want
+	INT_80                                      ; call the Kernel
+	POP_EAX                                     ; Get either char or EOF
+	CMPI8_EAX !-4                               ; Check for EOF
+	JE32 %fgetc_done                            ; Return as is
+	MOVZX_al                                    ; Make it useful
+:fgetc_done
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; Reverse_List function
+;; Recieves List in EAX
+;; Returns the list reversed in EAX
+:Reverse_List
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_EBX                             ; Set HEAD
+	LOADI32_EAX %0                              ; ROOT = NULL
+:Reverse_List_Loop
+	CMPI8_EBX !0                                ; WHILE HEAD != NULL
+	JE32 %Reverse_List_Done                     ; Stop otherwise
+
+	LOAD32_ECX_from_EBX                         ; NEXT = HEAD->NEXT
+	STORE32_EAX_into_EBX                        ; HEAD->NEXT = ROOT
+	COPY_EBX_to_EAX                             ; ROOT = HEAD
+	COPY_ECX_to_EBX                             ; HEAD = NEXT
+	JMP32 %Reverse_List_Loop                    ; Keep Going
+
+:Reverse_List_Done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; recursive_output function
+;; Recieves list in EAX
+;; walks the list and prints the I->S for all nodes backwards
+;; Uses EBX for I
+:recursive_output
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	CMPI8_EAX !0                                ; Check for NULL
+	JE32 %recursive_output_done                 ; Skip the work
+	COPY_EAX_to_EBX                             ; I = Head
+
+	LOAD32_EAX_from_EBX                         ; Iterate to next Token
+	CALL32 %recursive_output                    ; Recurse
+
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; Using S
+	CALL32 %File_Print                          ; Print it
+
+:recursive_output_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; File_Print function
+;; Recieves CHAR* in EAX
+;; calls fputc for every non-null char
+:File_Print
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_EBX                             ; Protect S
+	CMPI8_EAX !0                                ; Protect against nulls
+	JE32 %File_Print_Done                       ; Simply don't try to print them
+:File_Print_Loop
+	LOAD8_al_from_EBX                           ; Read byte
+	MOVZX_al                                    ; zero extend
+	CMPI8_EAX !0                                ; Check for NULL
+	JE32 %File_Print_Done                       ; Stop at NULL
+
+	CALL32 %fputc                               ; write it
+	ADDI8_EBX !1                                ; S = S + 1
+	JMP32 %File_Print_Loop                      ; Keep going
+
+:File_Print_Done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; fputc function
+;; recieves CHAR in EAX and load FILE* from [OUTPUT_FILE]
+;; writes char and returns
+:fputc
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	PUSH_EAX                                    ; We are writing eax
+	LEA32_ECX_from_esp                          ; Get stack address
+	LOAD32_Absolute32_ebx &Output_file          ; Write to target file
+	LOADI32_EAX %4                              ; the syscall number for write
+	LOADI32_EDX %1                              ; set the size of chars we want
+	INT_80                                      ; call the Kernel
+	POP_EAX                                     ; Restore stack
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; program function
+;; recieves nothing, returns nothing
+;; Uses EAX for type_size
+:program
+	;; The binary initialized the globals to null, so we can skip those steps
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+
+:new_type
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	CMPI8_EAX !0                                ; Check if NULL
+	JE32 %program_done                          ; Be done if null
+
+	LOAD32_EBX_from_EAX_Immediate8 !8           ; GLOBAL_TOKEN->S
+	LOADI32_EAX &constant                       ; "CONSTANT"
+	CALL32 %match                               ; IF GLOBAL_TOKEN->S == "CONSTANT"
+	CMPI8_EAX !0                                ; If true
+	JNE32 %program_else                         ; Looks like not a constant
+
+	;; Deal with minimal constant case
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOADI32_EBX %0                              ; NULL
+	LOAD32_Absolute32_ecx &global_constant_list ; global_constant_list
+	CALL32 %sym_declare                         ; Declare that constant
+	STORE32_Absolute32_eax &global_constant_list ; global_constant_list = sym_declare(global_token->s, NULL, global_constant_list);
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX                         ; global_token->next
+	STORE32_EBX_into_EAX_Immediate8 !16         ; global_constant_list->arguments = global_token->next
+
+	LOAD32_EBX_from_EBX                         ; global_token->next->next
+	STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next->next
+	JMP32 %new_type                             ; go around again
+
+:program_else
+	CALL32 %type_name                           ; Figure out the type_size
+	CMPI8_EAX !0                                ; IF NULL == type_size
+	JE32 %new_type                              ; it was a new type
+
+	;; Add to global symbol table
+	COPY_EAX_to_EBX                             ; put type_size in the right spot
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD32_Absolute32_ecx &global_symbol_list   ; Using global_symbol_list
+	CALL32 %sym_declare                         ; Declare symbol
+	STORE32_Absolute32_eax &global_symbol_list  ; global_symbol_list = sym_declare(global_token->s, type_size, global_symbol_list);
+	LOAD32_Absolute32_ebx &global_token         ; Using global token
+	LOAD32_EBX_from_EBX                         ; global_token->next
+	STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &semicolon                      ; ";"
+	CALL32 %match                               ; if(match(";", global_token->s))
+	CMPI8_EAX !0                                ; If true
+	JNE32 %program_function                     ; looks like not a match
+
+	;; Deal with the global variable
+	LOAD32_Absolute32_ebx &globals_list         ; Using globals_list
+	LOADI32_EAX &program_string_0               ; ":GLOBAL_"
+	CALL32 %emit                                ; Emit it
+	COPY_EAX_to_EBX                             ; update globals_list
+
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX_Immediate8 !4           ; global token->prev
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global token->prev->s
+	CALL32 %emit                                ; Emit it
+
+	COPY_EAX_to_EBX                             ; update globals_list
+	LOADI32_EAX &program_string_1               ; "\nNOP\n"
+	CALL32 %emit                                ; Emit it
+	STORE32_Absolute32_eax &globals_list        ; update globals_list
+
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+	JMP32 %new_type                             ; go around again
+
+:program_function
+	LOAD32_Absolute32_ebx &global_token         ; Using global token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &open_paren                     ; "("
+	CALL32 %match                               ; if(match(";", global_token->s))
+	CMPI8_EAX !0                                ; If true
+	JNE32 %program_error                        ; Otherwise deal with error case
+
+	;; Deal with function definition
+	CALL32 %declare_function                    ; Lets get the parsing rolling
+	JMP32 %new_type                             ; Keep looping through functions
+
+:program_error
+	;; Deal with the case of something we don't support
+	;; NOT IMPLEMENTED
+
+:program_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+;; Strings needed by the program function
+:program_string_0  ":GLOBAL_"
+:program_string_1  "
+NOP
+"
+
+
+;; declare_function function
+;; Recieves nothing and returns nothing
+;; Sets current function and adds it to the global function list
+:declare_function
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOADI32_EAX %0                              ; Using NULL
+	STORE32_Absolute32_eax &current_count       ; current_count = 0
+
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX_Immediate8 !4           ; global token->prev
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global token->prev->s
+	LOADI32_EBX %0                              ; NULL
+	LOAD32_Absolute32_ecx &global_function_list ; global_function_list
+	CALL32 %sym_declare                         ; sym_declare(global_token->prev->s, NULL, global_function_list);
+	STORE32_Absolute32_eax &function            ; function = sym_declare(global_token->prev->s, NULL, global_function_list);
+	STORE32_Absolute32_eax &global_function_list ; global_function_list = function
+
+	CALL32 %collect_arguments                   ; collect all of the function arguments
+
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global token->s
+	LOADI32_EBX &semicolon                      ; ";"
+	CALL32 %match                               ; IF global token->s == ";"
+	CMPI8_EAX !0                                ; If true
+	JNE32 %declare_function_full                ; It was a prototype
+
+	;; Deal with prototypes
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX                         ; global token->next
+	STORE32_Absolute32_eax &global_token        ; global token = global token->next
+	JMP32 %declare_function_done                ; Move on
+
+:declare_function_full
+	;; Deal will full function definitions
+	LOADI32_EAX &declare_function_string_0      ; "# Defining function "
+	CALL32 %emit_out                            ; emit it
+
+	LOAD32_Absolute32_eax &function             ; function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->s
+	CALL32 %emit_out                            ; emit it
+
+	LOADI32_EAX &declare_function_string_1      ; "\n:FUNCTION_"
+	CALL32 %emit_out                            ; emit it
+
+	LOAD32_Absolute32_eax &function             ; function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->s
+	CALL32 %emit_out                            ; emit it
+
+	LOADI32_EAX &declare_function_string_3      ; "\n"
+	CALL32 %emit_out                            ; emit it
+
+	CALL32 %statement                           ; Recursively get the function pieces
+
+	LOAD32_Absolute32_eax &output_list          ; output
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; output->s
+	LOADI32_EBX &declare_function_string_2      ; "RETURN\n"
+	CALL32 %match                               ; IF output->s == "RETURN\n"
+	CMPI8_EAX !0                                ; If true we can skip adding it
+	JE32 %declare_function_done                 ; otherwise we need to add it
+
+	;; Add the return to the end of a function lacking a return;
+	LOADI32_EAX &declare_function_string_2      ; "RETURN\n"
+	CALL32 %emit_out                            ; emit it
+
+:declare_function_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:declare_function_string_0  "# Defining function "
+:declare_function_string_1  "
+:FUNCTION_"
+:declare_function_string_2  "RETURN
+"
+:declare_function_string_3  "
+"
+
+
+;; collect_arguments function
+;; Recieves nothing
+;; Returns Nothing
+;; Adds arguments to the function definition
+;; holds struct type* type_size in ECX, then replace with struct token_list* a in ECX when type_size is used
+:collect_arguments
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+:collect_arguments_loop
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &close_paren                    ; ")"
+	CALL32 %match                               ; IF global_token->S == ")"
+	CMPI8_EAX !0                                ; we reached the end
+	JE32 %collect_arguments_done                ; be done
+
+	;; deal with the case of there are arguments
+	CALL32 %type_name                           ; Get the type
+	COPY_EAX_to_ECX                             ; put type_size safely out of the way
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &close_paren                    ; ")"
+	CALL32 %match                               ; IF global_token->S == ")"
+	CMPI8_EAX !0                                ; is a foo(int, char,void) case
+	JE32 %collect_arguments_common              ; deal with commas
+
+	;; Trying second else
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &comma                          ; ","
+	CALL32 %match                               ; IF global_token->S == ","
+	CMPI8_EAX !0                                ; then deal with the common
+	JE32 %collect_arguments_common              ; case of commas between arguments
+
+	;; deal with foo(int a, char b)
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	COPY_ECX_to_EBX                             ; put type_size in the right place
+	LOAD32_Absolute32_ecx &function             ; Using function
+	LOAD32_ECX_from_ECX_Immediate8 !16          ; function->args
+	CALL32 %sym_declare                         ; sym_declare(global_token->s, type_size, function->arguments);
+	COPY_EAX_to_ECX                             ; put a in a safe place
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args
+	CMPI8_EAX !0                                ; IF function->args == NULL
+	JNE32 %collect_arguments_another            ; otherwise it isn't the first
+
+	;; Deal with the case of first argument in the function
+	LOADI32_EAX %-4                             ; -4
+	STORE32_EAX_into_ECX_Immediate8 !16         ; a->depth = -4
+	JMP32 %collect_arguments_next               ; get to next
+
+:collect_arguments_another
+	;; deal with the case of non-first arguments
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args
+	LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args->depth
+	SUBI8_EAX !4                                ; function->args->depth - 4
+	STORE32_EAX_into_ECX_Immediate8 !16         ; a->depth = function->args->depth - 4
+
+:collect_arguments_next
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	STORE32_ECX_into_EAX_Immediate8 !16         ; function->args = a
+
+:collect_arguments_common
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &comma                          ; ","
+	CALL32 %match                               ; IF global_token->S == ","
+	CMPI8_EAX !0                                ; then deal with the comma
+	JNE32 %collect_arguments_loop               ; otherwise loop
+
+	;; keep foo(bar(), 1) expressions working
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+	JMP32 %collect_arguments_loop               ; keep going
+
+:collect_arguments_done
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; statement function
+;; Recieves nothing
+;; Returns nothing
+;; Walks down global_token recursively to collect the contents of the function
+:statement
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &open_curly_brace               ; "{"
+	CALL32 %match                               ; IF global_token->S == "{"
+	JNE32 %statement_label                      ; otherwise try label
+
+	;; deal with { statement }
+	CALL32 %recursive_statement                 ; Statements inside of statements for days
+	JMP32 %statement_done                       ; Be done
+
+:statement_label
+	LOAD8_al_from_EBX                           ; global_token->S[0]
+	MOVZX_al                                    ; make it useful
+	CMPI8_EAX !58                               ; IF global_token->S == ':'
+	JNE32 %statement_local                      ; otherwise try locals
+
+	;; deal with labels
+	COPY_EBX_to_EAX                             ; put global_token->S in the right spot
+	CALL32 %emit_out                            ; emit it
+
+	LOADI32_EAX &statement_string_0             ; Using "\t#C goto label\n"
+	CALL32 %emit_out                            ; emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+	JMP32 %statement_done                       ; be done
+
+:statement_local
+	COPY_EBX_to_EAX                             ; put global_token->S in the right place
+	LOADI32_EBX &prim_types                     ; pointer to primative types
+	CALL32 %lookup_type                         ; See if found
+	CMPI8_EAX !0                                ; IF NULL == lookup_type(global_token->S, prim_types)
+	JNE32 %statement_local_success              ; Sweet a new local
+
+	;; Second chance
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &struct                         ; "struct"
+	CALL32 %match                               ; IF global_token->S == "struct"
+	CMPI8_EAX !0                                ; then we are a local
+	JNE32 %statement_if                         ; otherwise try IF
+
+:statement_local_success
+	CALL32 %collect_local                       ; Grab those locals
+	JMP32 %statement_done                       ; be done
+
+:statement_if
+	LOADI32_EAX &if_string                      ; Using "if"
+	CALL32 %match                               ; IF global_token->S == "if"
+	CMPI8_EAX !0                                ; then we have an if statement
+	JNE32 %statement_do                         ; otherwise try DO
+
+	;; Deal with IF statement
+	CALL32 %process_if                          ; DO IT
+	JMP32 %statement_done                       ; be done
+
+:statement_do
+	LOADI32_EAX &do_string                      ; Using "do"
+	CALL32 %match                               ; IF global_token->S == "do"
+	CMPI8_EAX !0                                ; then we have a do statement
+	JNE32 %statement_while                      ; otherwise try WHILE
+
+	;; Deal with DO statement
+	CALL32 %process_do                          ; DO IT
+	JMP32 %statement_done                       ; be done
+
+:statement_while
+	LOADI32_EAX &while_string                   ; Using "while"
+	CALL32 %match                               ; IF global_token->S == "while"
+	CMPI8_EAX !0                                ; then we have a while statement
+	JNE32 %statement_for                        ; otherwise try FOR
+
+	;; Deal with WHILE statement
+	CALL32 %process_while                       ; DO IT
+	JMP32 %statement_done                       ; be done
+
+:statement_for
+	LOADI32_EAX &for_string                     ; Using "for"
+	CALL32 %match                               ; IF global_token->S == "for"
+	CMPI8_EAX !0                                ; then we have a for statement
+	JNE32 %statement_asm                        ; otherwise try ASM
+
+	;; Deal with FOR statement
+	CALL32 %process_for                         ; DO IT
+	JMP32 %statement_done                       ; be done
+
+:statement_asm
+	LOADI32_EAX &asm_string                     ; Using "asm"
+	CALL32 %match                               ; IF global_token->S == "asm"
+	CMPI8_EAX !0                                ; then we have an asm statement
+	JNE32 %statement_goto                       ; otherwise try GOTO
+
+	;; Deal with ASM statement
+	CALL32 %process_asm                         ; Hit it
+	JMP32 %statement_done                       ; be done
+
+:statement_goto
+	LOADI32_EAX &goto_string                    ; Using "goto"
+	CALL32 %match                               ; IF global_token->S == "goto"
+	CMPI8_EAX !0                                ; then we have a goto statement
+	JNE32 %statement_return                     ; Otherwise try RETURN
+
+	;; Deal with GOTO statement
+	LOADI32_EAX &statement_string_1             ; Using "JUMP %"
+	CALL32 %emit_out                            ; emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %emit_out                            ; emit it
+
+	LOADI32_EAX &statement_string_2             ; Using "\n"
+	CALL32 %emit_out                            ; emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+
+	LOADI32_EAX &statement_string_4             ; Using "ERROR in statement\nMissing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure it has the required
+	JMP32 %statement_done                       ; Be done
+
+:statement_return
+	LOADI32_EAX &return_string                  ; Using "return"
+	CALL32 %match                               ; IF global_token->S == "return"
+	CMPI8_EAX !0                                ; then we have a return statement
+	JNE32 %statement_break                      ; Otherwise try BREAK
+
+	;; Deal with RETURN Statement
+	CALL32 %return_result                       ; Return anything they want
+	JMP32 %statement_done                       ; be done
+
+:statement_break
+	LOADI32_EAX &break_string                   ; Using "break"
+	CALL32 %match                               ; IF global_token->S == "break"
+	CMPI8_EAX !0                                ; then we have a break statement
+	JNE32 %statement_continue                   ; Otherwise try CONTINUE
+
+	;; Deal with BREAK statement
+	CALL32 %process_break                       ; Lets do some damage
+	JMP32 %statement_done                       ; be done
+
+:statement_continue
+	LOADI32_EAX &continue_string                ; Using "continue"
+	CALL32 %match                               ; IF global_token->S == "continue"
+	CMPI8_EAX !0                                ; then we have a continue statement
+	JNE32 %statement_else                       ; Otherwise we are punting to an expression
+
+	;; Deal with CONTINUE statement
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+
+	LOADI32_EAX &statement_string_3             ; Using "\n#continue statement\n"
+	CALL32 %emit_out                            ; emit it
+
+	LOADI32_EAX &statement_string_4             ; Using "ERROR in statement\nMissing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Don't forget the ";"
+	JMP32 %statement_done                       ; Be done
+
+:statement_else
+	CALL32 %expression                          ; Collect expression
+	LOADI32_EAX &statement_string_4             ; Using "ERROR in statement\nMissing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; make sure we have it
+
+:statement_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:statement_string_0  "	#C goto label
+"
+:statement_string_1  "JUMP %"
+:statement_string_2  "
+"
+:statement_string_3  "
+#continue statement
+"
+:statement_string_4  "ERROR in statement
+Missing ;
+"
+
+
+;; recursive_statement function
+;; Recieves nothing
+;; Returns nothing
+;; Walks the global_token list to build the contents of statements
+;; Uses struct token_list* frame in ECX
+:recursive_statement
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+
+	LOAD32_Absolute32_ecx &function             ; Using function
+	LOAD32_ECX_from_ECX_Immediate8 !4           ; frame = function->locals
+
+:recursive_statement_loop
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &close_curly_brace              ; Using "}"
+	CALL32 %match                               ; IF global_token->S == "}"
+	CMPI8_EAX !0                                ; Then we are done recuring
+	JE32 %recursive_statement_cleanup           ; and then we clean up
+
+	;; Deal with the recursive calls
+	CALL32 %statement                           ; Deal with another statement
+	JMP32 %recursive_statement_loop             ; loop some more
+
+:recursive_statement_cleanup
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+
+	LOADI32_EAX &recursive_statement_string_0   ; Using "RETURN\n"
+	LOAD32_Absolute32_ebx &output_list          ; Using output
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; output->S
+	CALL32 %match                               ; IF output->S == "RETURN\n"
+	CMPI8_EAX !0                                ; Then we can skip the clean up
+	JE32 %recursive_statement_done              ; and be done
+
+	;; Deal with cleanup
+	LOAD32_Absolute32_ebx &function             ; Using function
+	LOAD32_EBX_from_EBX_Immediate8 !4           ; i = function->locals
+	LOADI32_EAX &recursive_statement_string_1   ; Using "POP_ebx\t# _recursive_statement_locals\n"
+
+:recursive_statement_locals
+	CMP_ECX_EBX                                 ; IF frame != i
+	JE32 %recursive_statement_done              ; Otherwise be done
+
+	;; Lets emit
+	CALL32 %emit_out                            ; emit it
+	LOAD32_EBX_from_EBX                         ; i = i->next
+	JMP32 %recursive_statement_locals           ; keep going
+
+:recursive_statement_done
+	LOAD32_Absolute32_eax &function             ; Using function
+	STORE32_ECX_into_EAX_Immediate8 !4          ; function->locals = frame
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:recursive_statement_string_0  "RETURN
+"
+:recursive_statement_string_1  "POP_ebx	# _recursive_statement_locals
+"
+
+
+;; return_result function
+;; Recieves nothing
+;; Returns nothing
+;; Cleans up function and generates return
+;; Also handles returing expressions
+:return_result
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; make it useful
+	CMPI8_EAX !59                               ; If global_token->S[0] == ';'
+	JE32 %return_result_cleanup                 ; Go straight to cleanup
+
+	CALL32 %expression                          ; get the expression we are returning
+
+:return_result_cleanup
+	LOADI32_EAX &return_result_string_0         ; Using "ERROR in return_result\nMISSING ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOAD32_Absolute32_ebx &function             ; Using function
+	LOAD32_EBX_from_EBX_Immediate8 !4           ; function->locals
+	LOADI32_EAX &return_result_string_1         ; Using "POP_ebx\t# _return_result_locals\n"
+:return_result_locals
+	CMPI8_EBX !0                                ; IF NULL == i
+	JE32 %return_result_done                    ; Be done
+
+	CALL32 %emit_out                            ; Emit out pop
+	LOAD32_EBX_from_EBX                         ; i = i->NEXT
+	JMP32 %return_result_locals                 ; Keep going
+
+:return_result_done
+	LOADI32_EAX &return_result_string_2         ; Using "RETURN\n"
+	CALL32 %emit_out                            ; Emit it
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:return_result_string_0  "ERROR in return_result
+MISSING ;
+"
+:return_result_string_1  "POP_ebx	# _return_result_locals
+"
+:return_result_string_2  "RETURN
+"
+
+
+;; collect_local function
+;; Recieves nothing
+;; Returns nothing
+;; Walks global_token list to create function locals
+;; Uses ECX for struct token_list* A
+:collect_local
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	CALL32 %type_name                           ; Get the local's type
+
+	COPY_EAX_to_EBX                             ; Put struct type* type_size in the right place
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD32_Absolute32_ecx &function             ; Using function
+	LOAD32_ECX_from_ECX_Immediate8 !4           ; function->locals
+	CALL32 %sym_declare                         ; Declare it
+	COPY_EAX_to_ECX                             ; put it away safely
+
+	;; Try for main
+	LOADI32_EAX &main_string                    ; Using "main"
+	LOAD32_Absolute32_ebx &function             ; Using function
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; function->S
+	CALL32 %match                               ; IF match("main", function->s)
+	CMPI8_EAX !0                                ; possible
+	JNE32 %collect_local_fresh                  ; try to see if fresh function
+
+	;; Ok we are in main, now to see if main is fresh
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !4           ; function->locals
+	CMPI8_EAX !0                                ; IF NULL == function->locals
+	JNE32 %collect_local_fresh                  ; try to see if fresh function
+
+	;; Sweet we are in a fresh main
+	LOADI32_EAX %-20                            ; We start at -20
+	STORE32_EAX_into_ECX_Immediate8 !16         ; a->DEPTH = -20
+	JMP32 %collect_local_common                 ; Go to the commons
+
+:collect_local_fresh
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args
+	CMPI8_EAX !0                                ; IF NULL == function->locals
+	JNE32 %collect_local_first                  ; Otherwise see if first
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !4           ; function->locals
+	CMPI8_EAX !0                                ; IF NULL == function->locals
+	JNE32 %collect_local_first                  ; Otherwise try first
+
+	;; Sweet we are in a fresh function
+	LOADI32_EAX %-8                             ; We start at -8
+	STORE32_EAX_into_ECX_Immediate8 !16         ; a->DEPTH = -8
+	JMP32 %collect_local_common                 ; Go to the commons
+
+:collect_local_first
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !4           ; function->locals
+	CMPI8_EAX !0                                ; IF NULL == function->locals
+	JNE32 %collect_local_else                   ; Looks like we are just another local
+
+	;; Ok we are the first local
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args
+	LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args->depth
+	SUBI8_EAX !8                                ; function->arguments->depth - 8
+	STORE32_EAX_into_ECX_Immediate8 !16         ; a->DEPTH = function->arguments->depth - 8
+	JMP32 %collect_local_common                 ; Go to the commons
+
+:collect_local_else
+	;; Always the last to know
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !4           ; function->locals
+	LOAD32_EAX_from_EAX_Immediate8 !16          ; function->locals->depth
+	SUBI8_EAX !4                                ; function->locals->depth - 4
+	STORE32_EAX_into_ECX_Immediate8 !16         ; a->DEPTH = function->locals->depth - 4
+
+:collect_local_common
+	LOAD32_Absolute32_eax &function             ; Using function
+
+	STORE32_ECX_into_EAX_Immediate8 !4          ; function->locals = a
+	LOAD32_ECX_from_ECX_Immediate8 !8           ; a->S
+
+	LOADI32_EAX &collect_local_string_0         ; Using "# Defining local "
+	CALL32 %emit_out                            ; emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %emit_out                            ; emit it
+
+	LOADI32_EAX &collect_local_string_1         ; Using "\n"
+	CALL32 %emit_out                            ; emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &equal                          ; Using "="
+	CALL32 %match                               ; IF match("=", global_token->s)
+	CMPI8_EAX !0                                ; Deal with assignment
+	JNE32 %collect_local_done                   ; Otherwise finish it
+
+	;; Deal with assignment
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	CALL32 %expression                          ; Recurse
+
+:collect_local_done
+	LOADI32_EAX &collect_local_string_2         ; Using "ERROR in collect_local\nMissing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOADI32_EAX &collect_local_string_3         ; Using "PUSH_eax\t#"
+	CALL32 %emit_out                            ; emit it
+
+	COPY_ECX_to_EAX                             ; put A->S where it belongs
+	CALL32 %emit_out                            ; emit it
+
+	LOADI32_EAX &collect_local_string_1         ; Using "\n"
+	CALL32 %emit_out                            ; emit it
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:collect_local_string_0  "# Defining local "
+:collect_local_string_1  "
+"
+:collect_local_string_2  "ERROR in collect_local
+Missing ;
+"
+:collect_local_string_3  "PUSH_eax	#"
+
+
+;; process_asm function
+;; Recieves nothing
+;; Returns nothing
+;; Simply inlines the asm statements
+;; Uses EBX for global_token temp storage
+:process_asm
+	PUSH_EBX                                    ; Protect EBX
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &process_asm_string_0           ; Using "ERROR in process_asm\nMISSING (\n"
+	LOADI32_EBX &open_paren                     ; Using "("
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+:process_asm_iter
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !34                               ; IF global_token->S[0] == '\"'
+	JNE32 %process_asm_done                     ; Otherwise be done
+
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; global_token->S
+	ADDI8_EAX !1                                ; global_token->S + 1
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &process_asm_string_1           ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_EBX_from_EBX                         ; global_token->NEXT
+	STORE32_Absolute32_ebx &global_token        ; global_token = global_token->NEXT
+	JMP32 %process_asm_iter                     ; keep going
+
+:process_asm_done
+	LOADI32_EAX &process_asm_string_2           ; Using "ERROR in process_asm\nMISSING )\n"
+	LOADI32_EBX &close_paren                    ; Using ")"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOADI32_EAX &process_asm_string_3           ; Using "ERROR in process_asm\nMISSING ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:process_asm_string_0  "ERROR in process_asm
+MISSING (
+"
+:process_asm_string_1  "
+"
+:process_asm_string_2  "ERROR in process_asm
+MISSING )
+"
+:process_asm_string_3  "ERROR in process_asm
+MISSING ;
+"
+
+
+;; process_if function
+;; Recieves nothing
+;; Returns Nothing
+;; Increments current_count recurses into expression + statement
+;; Uses ECX for char* NUMBER_STRING
+:process_if
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_eax &current_count        ; Using current count
+	COPY_EAX_to_EBX                             ; Preparing for update
+	ADDI8_EBX !1                                ; current_count + 1
+	STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
+	CALL32 %numerate_number                     ; convert to string
+	COPY_EAX_to_ECX                             ; put NUMBER_STRING in place
+
+	LOADI32_EAX &process_if_string_0            ; Using "# IF_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &process_if_string_1            ; Using "ERROR in process_if\nMISSING (\n"
+	LOADI32_EBX &open_paren                     ; Using "("
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %expression                          ; Recurse to get the IF(...) part
+
+	LOADI32_EAX &process_if_string_2            ; Using "TEST\nJUMP_EQ %ELSE_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_if_string_3            ; Using "ERROR in process_if\nMISSING )\n"
+	LOADI32_EBX &close_paren                    ; Using ")"
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %statement                           ; Recursive to get the IF(){...} part
+
+	LOADI32_EAX &process_if_string_4            ; Using "JUMP %_END_IF_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_if_string_5            ; Using ":ELSE_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &else_string                    ; Using "else"
+	CALL32 %match                               ; IF global_token->S == "else"
+	CMPI8_EAX !0                                ; Then we need to collect the else too
+	JNE32 %process_if_done                      ; Otherwise finish up
+
+	;; deal with else statement
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	CALL32 %statement                           ; Recurse to get the ELSE {...} part
+
+:process_if_done
+	LOADI32_EAX &process_if_string_6            ; Using ":_END_IF_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:process_if_string_0  "# IF_"
+:process_if_string_1  "ERROR in process_if
+MISSING (
+"
+:process_if_string_2  "TEST
+JUMP_EQ %ELSE_"
+:process_if_string_3  "ERROR in process_if
+MISSING )
+"
+:process_if_string_4  "JUMP %_END_IF_"
+:process_if_string_5  ":ELSE_"
+:process_if_string_6  ":_END_IF_"
+
+
+;; save_break_frame microfunction
+;; Overwrites EAX abd EBX
+;; Saves break frame on stack
+;; Returns to caller
+:save_break_frame
+	POP_EBX                                     ; Save return Address
+	LOAD32_Absolute32_eax &break_frame          ; Get break_frame
+	PUSH_EAX                                    ; Store as nested_locals
+	LOAD32_Absolute32_eax &break_target_head    ; Get break_target_head
+	PUSH_EAX                                    ; Store as nested_break_head
+	LOAD32_Absolute32_eax &break_target_func    ; Get break_target_func
+	PUSH_EAX                                    ; Store as nested_break_func
+	LOAD32_Absolute32_eax &break_target_num     ; Get break_target_num
+	PUSH_EAX                                    ; Store as nested_break_num
+	PUSH_EBX                                    ; Put return back in place
+	RETURN                                      ; Return to caller
+
+
+;; restore_break_frame microfunction
+;; Overwrites EAX and EBX
+;; Restores break frame from stack
+;; Returns to caller
+:restore_break_frame
+	POP_EBX                                     ; Save return Address
+	POP_EAX                                     ; Get nested_break_num
+	STORE32_Absolute32_eax &break_target_num    ; Restore break_target_num
+	POP_EAX                                     ; Get nested_break_func
+	STORE32_Absolute32_eax &break_target_func   ; Restore break_target_func
+	POP_EAX                                     ; Get nested_break_head
+	STORE32_Absolute32_eax &break_target_head   ; Restore break_target_head
+	POP_EAX                                     ; Get nested_locals
+	STORE32_Absolute32_eax &break_frame         ; Restore break_frame
+	PUSH_EBX                                    ; Put return back in place
+	RETURN                                      ; Return to caller
+
+
+;; set_break_frame microfunction
+;; Recieves char* head in EAX and char* num in EBX
+;; Overwrites EAX and EBX
+;; Returns to calling function
+:set_break_frame
+	STORE32_Absolute32_eax &break_target_head   ; update break_target_head
+	STORE32_Absolute32_ebx &break_target_num    ; update break_target_num
+	LOAD32_Absolute32_ebx &function             ; Using function
+	LOAD32_EAX_from_EBX_Immediate8 !4           ; function->LOCALS
+	STORE32_Absolute32_eax &break_frame         ; break_frame = function->LOCALS
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; function->S
+	STORE32_Absolute32_eax &break_target_func   ; break_target_func = function->S
+	RETURN                                      ; Return to sender
+
+
+;; process_do function
+;; Recieves Nothing
+;; Returns Nothing
+;; Increments current_count and leverages save/restore_break_frame pieces
+;; Uses ECX for char* NUMBER_STRING
+:process_do
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	CALL32 %save_break_frame                    ; Save the frame
+
+	LOAD32_Absolute32_eax &current_count        ; Using current count
+	COPY_EAX_to_EBX                             ; Preparing for update
+	ADDI8_EBX !1                                ; current_count + 1
+	STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
+	CALL32 %numerate_number                     ; convert to string
+	COPY_EAX_to_ECX                             ; put NUMBER_STRING in place
+
+	LOADI32_EAX &process_do_string_0            ; Using "DO_END_"
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %set_break_frame                     ; Set the frame
+
+	LOADI32_EAX &process_do_string_1            ; Using ":DO_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	CALL32 %statement                           ; Do the DO {...} part
+
+	LOADI32_EAX &process_do_string_2            ; Using "ERROR in process_do\nMISSING while\n"
+	LOADI32_EBX &while_string                   ; Using "while"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOADI32_EAX &process_do_string_3            ; Using "ERROR in process_do\nMISSING (\n"
+	LOADI32_EBX &open_paren                     ; Using "("
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %expression                          ; Do the WHILE (...) part
+
+	LOADI32_EAX &process_do_string_4            ; Using "ERROR in process_do\nMISSING )\n"
+	LOADI32_EBX &close_paren                    ; Using ")"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOADI32_EAX &process_do_string_5            ; Using "ERROR in process_do\nMISSING ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOADI32_EAX &process_do_string_6            ; Using "TEST\nJUMP_NE %DO_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_do_string_7            ; Using ":DO_END_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	CALL32 %restore_break_frame                 ; Restore the old break frame
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:process_do_string_0  "DO_END_"
+:process_do_string_1  ":DO_"
+:process_do_string_2  "ERROR in process_do
+MISSING while
+"
+:process_do_string_3  "ERROR in process_do
+MISSING (
+"
+:process_do_string_4  "ERROR in process_do
+MISSING )
+"
+:process_do_string_5  "ERROR in process_do
+MISSING ;
+"
+:process_do_string_6  "TEST
+JUMP_NE %DO_"
+:process_do_string_7  ":DO_END_"
+
+
+;; process_while function
+;; Recieves nothing
+;; Returns nothing
+;; Increments current_count and leverages save/restore_break_frame pieces
+;; Uses ECX for char* NUMBER_STRING
+:process_while
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	CALL32 %save_break_frame                    ; Save break_frame
+
+	LOAD32_Absolute32_eax &current_count        ; Using current count
+	COPY_EAX_to_EBX                             ; Preparing for update
+	ADDI8_EBX !1                                ; current_count + 1
+	STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
+	CALL32 %numerate_number                     ; convert to string
+	COPY_EAX_to_ECX                             ; put NUMBER_STRING in place
+
+	LOADI32_EAX &process_while_string_0         ; Using "END_WHILE_"
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %set_break_frame                     ; Set it and forget it
+
+	LOADI32_EAX &process_while_string_1         ; Using ":WHILE_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &process_while_string_2         ; Using "ERROR in process_while\nMISSING (\n"
+	LOADI32_EBX &open_paren                     ; Using "("
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %expression                          ; Deal with the WHILE (...) part
+
+	LOADI32_EAX &process_while_string_3         ; Using "TEST\nJUMP_EQ %END_WHILE_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_while_string_4         ; Using "# THEN_while_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_while_string_5         ; Using "ERROR in process_while\nMISSING )\n"
+	LOADI32_EBX &close_paren                    ; Using ")"
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %statement                           ; Deal with the {....} part
+
+	LOADI32_EAX &process_while_string_6         ; Using "JUMP %WHILE_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_while_string_7         ; Using ":END_WHILE_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	CALL32 %restore_break_frame                 ; Restore the old break frame
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:process_while_string_0  "END_WHILE_"
+:process_while_string_1  ":WHILE_"
+:process_while_string_2  "ERROR in process_while
+MISSING (
+"
+:process_while_string_3  "TEST
+JUMP_EQ %END_WHILE_"
+:process_while_string_4  "# THEN_while_"
+:process_while_string_5  "ERROR in process_while
+MISSING )
+"
+:process_while_string_6  "JUMP %WHILE_"
+:process_while_string_7  ":END_WHILE_"
+
+
+;; process_for function
+;; Recieves Nothing
+;; Returns Nothing
+;; Increments current_count and leverages save/restore_break_frame pieces
+;; Uses ECX for char* NUMBER_STRING
+:process_for
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	CALL32 %save_break_frame                    ; Save the frame
+
+	LOAD32_Absolute32_eax &current_count        ; Using current count
+	COPY_EAX_to_EBX                             ; Preparing for update
+	ADDI8_EBX !1                                ; current_count + 1
+	STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
+	CALL32 %numerate_number                     ; convert to string
+	COPY_EAX_to_ECX                             ; put NUMBER_STRING in place
+
+	LOADI32_EAX &process_for_string_0           ; Using "FOR_END_"
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %set_break_frame                     ; Set it and forget it
+
+	LOADI32_EAX &process_for_string_1           ; Using "# FOR_initialization_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &process_for_string_2           ; Using "ERROR in process_for\nMISSING (\n"
+	LOADI32_EBX &open_paren                     ; Using "("
+	CALL32 %require_match                       ; Make Sure we have it
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &semicolon                      ; Using ";"
+	CALL32 %match                               ; IF global_token->S == ";"
+	CMPI8_EAX !0                                ; Then no initializer
+	JE32 %process_for_terminator                ; And skip getting the expression
+
+	;; Deal with FOR (...; case
+	CALL32 %expression                          ; Get the FOR ( ... ; part
+
+:process_for_terminator
+	LOADI32_EAX &process_for_string_3           ; Using ":FOR_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_for_string_4           ; Using "ERROR in process_for\nMISSING ;1\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %expression                          ; Get the FOR ( ; ... ; Part
+
+	LOADI32_EAX &process_for_string_5           ; Using "TEST\nJUMP_EQ %FOR_END_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_for_string_6           ; Using "JUMP %FOR_THEN_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_for_string_7           ; Using ":FOR_ITER_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_for_string_8           ; Using "ERROR in process_for\nMISSING ;2\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %expression                          ; Get the FOR (;;...) part
+
+	LOADI32_EAX &process_for_string_9           ; Using "JUMP %FOR_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_for_string_10          ; Using ":FOR_THEN_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_for_string_11          ; Using "ERROR in process_for\nMISSING )\n"
+	LOADI32_EBX &close_paren                    ; Using ")"
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %statement                           ; Get FOR (;;) {...} part
+
+	LOADI32_EAX &process_for_string_12          ; Using "JUMP %FOR_ITER_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	LOADI32_EAX &process_for_string_13          ; Using ":FOR_END_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)
+
+	CALL32 %restore_break_frame                 ; Restore the old break frame
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:process_for_string_0  "FOR_END_"
+:process_for_string_1  "# FOR_initialization_"
+:process_for_string_2  "ERROR in process_for
+MISSING (
+"
+:process_for_string_3  ":FOR_"
+:process_for_string_4  "ERROR in process_for
+MISSING ;1
+"
+:process_for_string_5  "TEST
+JUMP_EQ %FOR_END_"
+:process_for_string_6  "JUMP %FOR_THEN_"
+:process_for_string_7  ":FOR_ITER_"
+:process_for_string_8  "ERROR in process_for
+MISSING ;2
+"
+:process_for_string_9  "JUMP %FOR_"
+:process_for_string_10 ":FOR_THEN_"
+:process_for_string_11 "ERROR in process_for
+MISSING )
+"
+:process_for_string_12 "JUMP %FOR_ITER_"
+:process_for_string_13 ":FOR_END_"
+
+
+;; process_break function
+;; Recieves nothing
+;; Returns nothing
+;; Handles the break out of loops case
+;; Uses EBX for struct token_list* break_frame and ECX for struct token_list* I
+:process_break
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_eax &break_target_head    ; Catch big error
+	CMPI8_EAX !0                                ; IF(NULL == break_target_head)
+	JE32 %process_break_bad                     ; I'm sorry Mr White but you have stage-3 lung cancer
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_ECX_from_EAX_Immediate8 !4           ; I = function->LOCALS
+	LOAD32_Absolute32_ebx &break_frame          ; Put break_frame in the right spot
+	LOADI32_EAX &process_break_string_1         ; Using "POP_ebx\t# break_cleanup_locals\n"
+
+:process_break_iter
+	CMPI8_ECX !0                                ; IF (NULL == I)
+	JE32 %process_break_cleaned                 ; We are done
+
+	CMP_EBX_ECX                                 ; IF I != break_frame
+	JE32 %process_break_cleaned                 ; We are done
+
+	CALL32 %emit_out                            ; Emit it
+	LOAD32_ECX_from_ECX                         ; I = I->NEXT
+	JMP32 %process_break_iter                   ; Keep looping
+
+:process_break_cleaned
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &process_break_string_2         ; Using "JUMP %"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &break_target_head    ; Get what we are in
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &break_target_func    ; Get what function we are in
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &underline                      ; Using "_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &break_target_num     ; Get dem digits
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &process_break_string_3         ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &process_break_string_4         ; Using "ERROR in break statement\nMissing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:process_break_bad
+	;; Breaking badly
+	LOADI32_EAX %2                              ; Using standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+;	CALL32 %line_error                          ; Write useful debug info
+	COPY_ECX_to_EAX                             ; put S in the right place
+	CALL32 %File_Print                          ; print it
+
+	LOADI32_EAX &process_break_string_0         ; Ending string
+	CALL32 %File_Print                          ; print it
+	JMP32 %Exit_Failure                         ; Abort Hard
+
+:process_break_string_0  "Not inside of a loop or case statement"
+:process_break_string_1  "POP_ebx	# break_cleanup_locals
+"
+:process_break_string_2  "JUMP %"
+:process_break_string_3  "
+"
+:process_break_string_4  "ERROR in break statement
+Missing ;
+"
+
+
+;; expression function
+;; Recieves Nothing
+;; Returns Nothing
+;; Walks global_token and updates output_list
+;; Uses EAX and EBX for match and ECX for char* store
+:expression
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	CALL32 %bitwise_expr                        ; Collect bitwise expressions
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &equal                          ; "="
+	CALL32 %match                               ; IF global_token->S == "="
+	CMPI8_EAX !0                                ; We have to deal with assignment
+	JNE32 %expression_done                      ; Looks like nope
+
+	;; Deal with possible assignment
+	LOADI32_ECX &expression_string_1            ; Assume "STORE_CHAR\n" by default
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !4           ; global_token->PREV
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->PREV->S
+	LOADI32_EAX &close_bracket                  ; Using "]"
+	CALL32 %match                               ; IF global_token->S == "]"
+	CMPI8_EAX !0                                ; Then we might have a char
+	JNE32 %expression_int                       ; Otherwise INT
+
+	LOAD32_Absolute32_ebx &current_target       ; Using current_target
+	LOAD32_EBX_from_EBX_Immediate8 !24          ; current_target->NAME
+	LOADI32_EAX &type_char_indirect_name        ; Using "char*"
+	CALL32 %match                               ; Intensional inefficency because I feel like it
+	CMPI8_EAX !0                                ; IF current_target->NAME == "char*"
+	JNE32 %expression_int                       ; Do char anyway
+
+	JMP32 %expression_common                    ; Looks like we have to use "STORE_CHAR\n"
+
+:expression_int
+	LOADI32_ECX &expression_string_0            ; Use "STORE_INTEGER\n"
+
+:expression_common
+	LOADI32_EAX &expression                     ; Passing expression
+	CALL32 %common_recursion                    ; Recurse
+	COPY_ECX_to_EAX                             ; Using Store
+	CALL32 %emit_out                            ; Emit it
+	LOADI32_EAX %0                              ; Using NULL
+	STORE32_Absolute32_eax &current_target      ; current_target = NULL
+
+:expression_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:expression_string_0  "STORE_INTEGER
+"
+:expression_string_1  "STORE_CHAR
+"
+
+
+;; bitwise_expr function
+;; Recieves nothing
+;; Returns nothing
+;; Walks global_token list and updates output list
+;; Just calls other functions
+:bitwise_expr
+	CALL32 %relational_expr                     ; Walk up the tree
+	CALL32 %bitwise_expr_stub                   ; Let general recursion do the work
+	RETURN
+
+
+;; bitwise_expr_stub function
+;; Recieves nothing
+;; Returns Nothing
+;; Just calls general_recursion a bunch
+;; Uses EAX, EBX, ECX and EDX for passing constants to general recursion
+:bitwise_expr_stub
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+
+	LOADI32_EAX &relational_expr                ; Using relational_expr
+	LOADI32_EBX &bitwise_expr_stub_string_0     ; Using "AND_eax_ebx\n"
+	LOADI32_ECX &bitwise_and                    ; Using "&"
+	LOADI32_EDX &bitwise_expr_stub              ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &relational_expr                ; Using relational_expr
+	LOADI32_EBX &bitwise_expr_stub_string_0     ; Using "AND_eax_ebx\n"
+	LOADI32_ECX &logical_and                    ; Using "&&"
+	LOADI32_EDX &bitwise_expr_stub              ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &relational_expr                ; Using relational_expr
+	LOADI32_EBX &bitwise_expr_stub_string_1     ; Using "OR_eax_ebx\n"
+	LOADI32_ECX &bitwise_or                     ; Using "|"
+	LOADI32_EDX &bitwise_expr_stub              ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &relational_expr                ; Using relational_expr
+	LOADI32_EBX &bitwise_expr_stub_string_1     ; Using "OR_eax_ebx\n"
+	LOADI32_ECX &logical_or                     ; Using "||"
+	LOADI32_EDX &bitwise_expr_stub              ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &relational_expr                ; Using relational_expr
+	LOADI32_EBX &bitwise_expr_stub_string_2     ; Using "XOR_ebx_eax_into_eax\n"
+	LOADI32_ECX &bitwise_xor                    ; Using "^"
+	LOADI32_EDX &bitwise_expr_stub              ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:bitwise_expr_stub_string_0  "AND_eax_ebx
+"
+:bitwise_expr_stub_string_1  "OR_eax_ebx
+"
+:bitwise_expr_stub_string_2  "XOR_ebx_eax_into_eax
+"
+
+
+;; relational_expr function
+;; Recieves nothing
+;; Returns Nothing
+;; Walks global_token list and updates output list
+;; just calls other function
+:relational_expr
+	CALL32 %additive_expr                       ; Walk up the tree
+	CALL32 %relational_expr_stub                ; Recurse
+	RETURN
+
+
+;; relational_expr_stub function
+;; Recieves nothing
+;; Returns Nothing
+;; Just calls general_recursion a bunch
+;; Uses EAX, EBX, ECX and EDX for passing constants to general recursion
+:relational_expr_stub
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+
+	LOADI32_EAX &additive_expr                  ; Using additive_expr
+	LOADI32_EBX &relational_expr_stub_string_0  ; Using "CMP\nSETL\nMOVEZBL\n"
+	LOADI32_ECX &less_than_string               ; Using "<"
+	LOADI32_EDX &relational_expr_stub           ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &additive_expr                  ; Using additive_expr
+	LOADI32_EBX &relational_expr_stub_string_1  ; Using "CMP\nSETLE\nMOVEZBL\n"
+	LOADI32_ECX &less_than_equal_string         ; Using "<="
+	LOADI32_EDX &relational_expr_stub           ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &additive_expr                  ; Using additive_expr
+	LOADI32_EBX &relational_expr_stub_string_2  ; Using "CMP\nSETGE\nMOVEZBL\n"
+	LOADI32_ECX &greater_than_equal_string      ; Using ">="
+	LOADI32_EDX &relational_expr_stub           ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &additive_expr                  ; Using additive_expr
+	LOADI32_EBX &relational_expr_stub_string_3  ; Using "CMP\nSETG\nMOVEZBL\n"
+	LOADI32_ECX &greater_than_string            ; Using ">"
+	LOADI32_EDX &relational_expr_stub           ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &additive_expr                  ; Using additive_expr
+	LOADI32_EBX &relational_expr_stub_string_4  ; Using "CMP\nSETE\nMOVEZBL\n"
+	LOADI32_ECX &equal_to_string                ; Using "=="
+	LOADI32_EDX &relational_expr_stub           ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &additive_expr                  ; Using additive_expr
+	LOADI32_EBX &relational_expr_stub_string_5  ; Using "CMP\nSETNE\nMOVEZBL\n"
+	LOADI32_ECX &not_equal_string               ; Using "!="
+	LOADI32_EDX &relational_expr_stub           ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:relational_expr_stub_string_0  "CMP
+SETL
+MOVEZBL
+"
+:relational_expr_stub_string_1  "CMP
+SETLE
+MOVEZBL
+"
+:relational_expr_stub_string_2  "CMP
+SETGE
+MOVEZBL
+"
+:relational_expr_stub_string_3  "CMP
+SETG
+MOVEZBL
+"
+:relational_expr_stub_string_4  "CMP
+SETE
+MOVEZBL
+"
+:relational_expr_stub_string_5  "CMP
+SETNE
+MOVEZBL
+"
+
+
+;; additive_expr function
+;; Recieves nothing
+;; Returns Nothing
+;; Walks global_token list and updates output list
+;; just calls other function
+:additive_expr
+	CALL32 %postfix_expr                        ; Walk up the tree
+	CALL32 %additive_expr_stub                  ; Recurse
+	RETURN
+
+
+;; additive_expr_stub function
+;; Recieves nothing
+;; Returns Nothing
+;; Just calls general_recursion a bunch
+;; Uses EAX, EBX, ECX and EDX for passing constants to general recursion
+:additive_expr_stub
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+
+	LOADI32_EAX &postfix_expr                   ; Using postfix_expr
+	LOADI32_EBX &additive_expr_stub_string_0    ; Using "ADD_ebx_to_eax\n"
+	LOADI32_ECX &plus_string                    ; Using "+"
+	LOADI32_EDX &additive_expr_stub             ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &postfix_expr                   ; Using postfix_expr
+	LOADI32_EBX &additive_expr_stub_string_1    ; Using "SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n"
+	LOADI32_ECX &minus_string                   ; Using "-"
+	LOADI32_EDX &additive_expr_stub             ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &postfix_expr                   ; Using postfix_expr
+	LOADI32_EBX &additive_expr_stub_string_2    ; Using "MULTIPLY_eax_by_ebx_into_eax\n"
+	LOADI32_ECX &multiply_string                ; Using "*"
+	LOADI32_EDX &additive_expr_stub             ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &postfix_expr                   ; Using postfix_expr
+	LOADI32_EBX &additive_expr_stub_string_3    ; Using "XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nDIVIDE_eax_by_ebx_into_eax\n"
+	LOADI32_ECX &divide_string                  ; Using "/"
+	LOADI32_EDX &additive_expr_stub             ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &postfix_expr                   ; Using postfix_expr
+	LOADI32_EBX &additive_expr_stub_string_4    ; Using "XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nMODULUS_eax_from_ebx_into_ebx\nMOVE_edx_to_eax\n"
+	LOADI32_ECX &modulus_string                 ; Using "%"
+	LOADI32_EDX &additive_expr_stub             ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &postfix_expr                   ; Using postfix_expr
+	LOADI32_EBX &additive_expr_stub_string_5    ; Using "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSAL_eax_cl\n"
+	LOADI32_ECX &left_shift_string              ; Using "<<"
+	LOADI32_EDX &additive_expr_stub             ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	LOADI32_EAX &postfix_expr                   ; Using postfix_expr
+	LOADI32_EBX &additive_expr_stub_string_6    ; Using "COPY_eax_to_ecx\nCOPY_ebx_to_eax\nSAR_eax_cl\n"
+	LOADI32_ECX &right_shift_string             ; Using ">>"
+	LOADI32_EDX &additive_expr_stub             ; And recurse
+	CALL32 %general_recursion                   ; Hit it
+
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:additive_expr_stub_string_0  "ADD_ebx_to_eax
+"
+:additive_expr_stub_string_1  "SUBTRACT_eax_from_ebx_into_ebx
+MOVE_ebx_to_eax
+"
+:additive_expr_stub_string_2  "MULTIPLY_eax_by_ebx_into_eax
+"
+:additive_expr_stub_string_3  "XCHG_eax_ebx
+LOAD_IMMEDIATE_edx %0
+DIVIDE_eax_by_ebx_into_eax
+"
+:additive_expr_stub_string_4  "XCHG_eax_ebx
+LOAD_IMMEDIATE_edx %0
+MODULUS_eax_from_ebx_into_ebx
+MOVE_edx_to_eax
+"
+:additive_expr_stub_string_5  "COPY_eax_to_ecx
+COPY_ebx_to_eax
+SAL_eax_cl
+"
+:additive_expr_stub_string_6  "COPY_eax_to_ecx
+COPY_ebx_to_eax
+SAR_eax_cl
+"
+
+
+;; postfix_expr function
+;; Recieves nothing
+;; Returns Nothing
+;; Walks global_token list and updates output list
+;; just calls other function
+:postfix_expr
+	CALL32 %primary_expr                        ; Walk up the tree
+	CALL32 %postfix_expr_stub                   ; Recurse
+	RETURN
+
+
+;; postfix_expr_stub function
+;; Recieves nothing
+;; Returns Nothing
+;; Checks for "[" and "->" and deals with them otherwise does nothing
+;; Uses EAX, EBX, ECX and EDX for passing constants to general recursion
+:postfix_expr_stub
+	PUSH_EBX                                    ; Protect EBX
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &open_bracket                   ; Using "["
+	CALL32 %match                               ; IF global_token->S == "["
+	CMPI8_EAX !0                                ; then we have an array
+	JNE32 %postfix_expr_stub_arrow              ; Otherwise try arrow
+
+	;; Deal with array
+	CALL32 %postfix_expr_array                  ; Get it
+	CALL32 %postfix_expr_stub                   ; Recurse
+
+:postfix_expr_stub_arrow
+	LOADI32_EAX &arrow_string                   ; Using "->"
+	CALL32 %match                               ; IF global_token->S == "->"
+	CMPI8_EAX !0                                ; Then we need to deal with struct offsets
+	JNE32 %postfix_expr_stub_done               ; Otherwise be done
+
+	;; Deal with arrow
+	CALL32 %postfix_expr_arrow                  ; Get it
+	CALL32 %postfix_expr_stub                   ; Recurse
+
+:postfix_expr_stub_done
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; unary_expr_sizeof function
+;; Recieves nothing
+;; Returns nothing
+;; Uses ECX for A->SIZE
+:unary_expr_sizeof
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &unary_expr_sizeof_string_0     ; Using "ERROR in unary_expr\nMissing (\n"
+	LOADI32_EBX &open_paren                     ; Using "("
+	CALL32 %require_match                       ; Make sure we have it
+
+	CALL32 %type_name                           ; Get the type
+	LOAD32_ECX_from_EAX_Immediate8 !4           ; Set A->TYPE
+
+	LOADI32_EAX &unary_expr_sizeof_string_1     ; Using "ERROR in unary_expr\nMissing )\n"
+	LOADI32_EBX &close_paren                    ; Using ")"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOADI32_EAX &unary_expr_sizeof_string_2     ; Using "LOAD_IMMEDIATE_eax %"
+	CALL32 %emit_out                            ; Emit it
+
+	COPY_ECX_to_EAX                             ; Put A->SIZE in the right place
+	CALL32 %numerate_number                     ; Turn into string
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &unary_expr_sizeof_string_3     ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:unary_expr_sizeof_string_0  "ERROR in unary_expr
+Missing (
+"
+:unary_expr_sizeof_string_1  "ERROR in unary_expr
+Missing )
+"
+:unary_expr_sizeof_string_2  "LOAD_IMMEDIATE_eax %"
+:unary_expr_sizeof_string_3  "
+"
+
+
+;; postfix_expr_array function
+;; Recieves Nothing
+;; Returns Nothing
+;; Uses EBX for struct type* ARRAY and ECX for char* ASSIGN
+:postfix_expr_array
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_eax &current_target       ; ARRAY = current_target
+	PUSH_EAX                                    ; Protect it
+
+	LOADI32_EAX &expression                     ; Using expression
+	CALL32 %common_recursion                    ; Recurse
+
+	POP_EBX                                     ; Restore array
+	STORE32_Absolute32_ebx &current_target      ; current_target = ARRAY
+
+	LOADI32_ECX &postfix_expr_array_string_0    ; ASSIGN = "LOAD_INTEGER\n"
+
+	LOADI32_EAX &type_char_indirect_name        ; Using "char*"
+	LOAD32_EBX_from_EBX_Immediate8 !24          ; current_target->NAME
+	CALL32 %match                               ; IF current_target->NAME == "char*"
+	CMPI8_EAX !0                                ; load a byte
+	JNE32 %postfix_expr_array_large             ; Otherwise adjust
+
+	;; Deal with loading byte
+	LOADI32_ECX &postfix_expr_array_string_1    ; ASSIGN = "LOAD_BYTE\n"
+	JMP32 %postfix_expr_array_common            ; Do the next bit
+
+:postfix_expr_array_large
+	;; deal with arrays made of things other than chars
+	LOADI32_EAX &postfix_expr_array_string_2    ; Using "SAL_eax_Immediate8 !"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &current_target       ; Using current_target
+	LOAD32_EAX_from_EAX_Immediate8 !12          ; current_target->INDIRECT
+	LOAD32_EAX_from_EAX_Immediate8 !4           ; current_target->INDIRECT->SIZE
+	CALL32 %ceil_log2                           ; ceil_log2(current_target->indirect->size)
+	CALL32 %numerate_number                     ; numerate_number(ceil_log2(current_target->indirect->size))
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &postfix_expr_array_string_3    ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+:postfix_expr_array_common
+	LOADI32_EAX &postfix_expr_array_string_4    ; Using "ADD_ebx_to_eax\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &postfix_expr_array_string_5    ; Using "ERROR in postfix_expr\nMissing ]\n"
+	LOADI32_EBX &close_bracket                  ; Using "]"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &equal                          ; Using "="
+	CALL32 %match                               ; IF global_token->S == "="
+	CMPI8_EAX !0                                ; We need to preserve address
+	JNE32 %postfix_expr_array_done              ; Otherwise be done
+
+	;; Clearing out assign
+	LOADI32_ECX &postfix_expr_array_string_6    ; ASSIGN = ""
+
+:postfix_expr_array_done
+	COPY_ECX_to_EAX                             ; Using ASSIGN
+	CALL32 %emit_out                            ; Emit it
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:postfix_expr_array_string_0  "LOAD_INTEGER
+"
+:postfix_expr_array_string_1  "LOAD_BYTE
+"
+:postfix_expr_array_string_2  "SAL_eax_Immediate8 !"
+:postfix_expr_array_string_3  "
+"
+:postfix_expr_array_string_4  "ADD_ebx_to_eax
+"
+:postfix_expr_array_string_5  "ERROR in postfix_expr
+Missing ]
+"
+:postfix_expr_array_string_6  ""
+
+
+;; ceil_log2 function
+;; Recieves int a in EAX
+;; Performs log2 on A and
+;; Returns result in EAX
+;; Uses EBX for INT A and ECX for INT RESULT
+:ceil_log2
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOADI32_ECX %0                              ; RESULT = 0
+
+	COPY_EAX_to_EBX                             ; put A in right place
+	SUBI8_EAX !1                                ; (A - 1)
+	AND_EAX_EBX                                 ; A & (A - 1)
+	CMPI8_EAX !0                                ; IF 0 == (A & (A - 1))
+	JNE32 %ceil_log2_iter                       ; Starting from -1
+
+	LOADI32_ECX %-1                             ; RESULT = -1
+
+:ceil_log2_iter
+	CMPI8_EBX !0                                ; IF A > 0
+	JLE32 %ceil_log2_done                       ; Otherwise be done
+
+	ADDI8_ECX !1                                ; RESULT = RESULT + 1
+	SHRI8_EBX !1                                ; A = A >> 1
+	JMP32 %ceil_log2_iter                       ; Keep looping
+
+:ceil_log2_done
+	COPY_ECX_to_EAX                             ; Return RESULT
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; postfix_expr_arrow function
+;; Recieves nothing
+;; Returns nothing
+;; Emits a bunch and updates current_target
+;; Uses EBX for struct type* I
+:postfix_expr_arrow
+	PUSH_EBX                                    ; Protect EBX
+	LOADI32_EAX &postfix_expr_arrow_string_0    ; Using "# looking up offset\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOAD32_EBX_from_EAX_Immediate8 !8           ; Using global_token->S
+	LOAD32_Absolute32_eax &current_target       ; Using current_target
+	CALL32 %lookup_member                       ; lookup_member(current_target, global_token->s)
+	COPY_EAX_to_EBX                             ; struct type* I = lookup_member(current_target, global_token->s)
+
+	LOAD32_EAX_from_EAX_Immediate8 !20          ; I->TYPE
+	STORE32_Absolute32_eax &current_target      ; current_target = I->TYPE
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; I->OFFSET
+	CMPI8_EAX !0                                ; IF 0 != I->OFFSET
+	JE32 %postfix_expr_arrow_first              ; Then we don't need to do an offset
+
+	;; Deal with needing an offset
+	LOADI32_EAX &postfix_expr_arrow_string_1    ; Using "# -> offset calculation\nLOAD_IMMEDIATE_ebx %"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; I->OFFSET
+	CALL32 %numerate_number                     ; Convert to string
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &postfix_expr_arrow_string_2    ; Using "\nADD_ebx_to_eax\n"
+	CALL32 %emit_out                            ; Emit it
+
+:postfix_expr_arrow_first
+	LOAD32_EAX_from_EBX_Immediate8 !4           ; I->SIZE
+	CMPI8_EAX !4                                ; IF I->SIZE >= 4
+	JL32 %postfix_expr_arrow_done               ; Otherwise be done
+
+	;; Last chance for load
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &equal                          ; Using "="
+	CALL32 %match                               ; IF global_token->S == "="
+	CMPI8_EAX !0                                ; Then we have assignment and should not load
+	JE32 %postfix_expr_arrow_done               ; Be done
+
+	;; Deal with load case
+	LOADI32_EAX &postfix_expr_arrow_string_3    ; Using "LOAD_INTEGER\n"
+	CALL32 %emit_out                            ; Emit it
+
+:postfix_expr_arrow_done
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:postfix_expr_arrow_string_0  "# looking up offset
+"
+:postfix_expr_arrow_string_1  "# -> offset calculation
+LOAD_IMMEDIATE_ebx %"
+:postfix_expr_arrow_string_2  "
+ADD_ebx_to_eax
+"
+:postfix_expr_arrow_string_3  "LOAD_INTEGER
+"
+
+
+;; primary_expr function
+;; Recieves nothing
+;; Returns nothing
+:primary_expr
+	PUSH_EBX                                    ; Protect EBX
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &sizeof_string                  ; Using "sizeof"
+	CALL32 %match                               ; See if match
+	CMPI8_EAX !0                                ; IF match
+	JNE32 %primary_expr_neg                     ; Otherwise try negatives
+
+	;; Deal with sizeof
+	CALL32 %unary_expr_sizeof                   ; Lets do this
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_neg
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !45                               ; IF global_token->S[0] == "-"
+	JNE32 %primary_expr_not                     ; Otherwise try logical NOT
+
+	;; Deal with negative numbers
+	LOADI32_EAX &primary_expr_string_0          ; Using "LOAD_IMMEDIATE_eax %0\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &postfix_expr                   ; Passing postfix_expr
+	CALL32 %common_recursion                    ; Get what it is notting
+
+	LOADI32_EAX &primary_expr_string_1          ; Using "SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n"
+	CALL32 %emit_out                            ; Emit it
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_not
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !33                               ; IF global_token->S[0] == "!"
+	JNE32 %primary_expr_bin                     ; Otherwise try '~'
+
+	;; Deal with logical not
+	LOADI32_EAX &primary_expr_string_2          ; Using "LOAD_IMMEDIATE_eax %1\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &postfix_expr                   ; Passing postfix_expr
+	CALL32 %common_recursion                    ; Get what it is notting
+
+	LOADI32_EAX &primary_expr_string_3          ; Using "XOR_ebx_eax_into_eax\n"
+	CALL32 %emit_out                            ; Emit it
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_bin
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !126                              ; IF global_token->S[0] == "~"
+	JNE32 %primary_expr_paren                   ; Otherwise try paren
+
+	;; Deal with binary NOT
+	LOADI32_EAX &postfix_expr                   ; Passing postfix_expr
+	CALL32 %common_recursion                    ; Get what it is notting
+	LOADI32_EAX &primary_expr_string_4          ; Using "NOT_eax\n"
+	CALL32 %emit_out                            ; Emit it
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_paren
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !40                               ; IF global_token->S[0] == "("
+	JNE32 %primary_expr_ch                      ; Otherwise try char
+
+	;; deal with nesting
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+	CALL32 %expression                          ; Lets recurse
+	LOADI32_EAX &primary_expr_string_5          ; Using "Error in Primary expression\nDidn't get )\n"
+	LOADI32_EBX &close_paren                    ; Using ")"
+	CALL32 %require_match                       ; Make sure we have it
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_ch
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !39                               ; Using "'"
+	JNE32 %primary_expr_str                     ; Otherwise try string
+
+	;; Deal with chars
+	CALL32 %primary_expr_char                   ; Handle that char
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_str
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !34                               ; Using '\"'
+	JNE32 %primary_expr_var                     ; Otherwise try a variable
+
+	;; Deal with strings
+	CALL32 %primary_expr_string                 ; Handle that string
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_var
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	LOADI32_EBX &primary_expr_string_6          ; Using "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
+	CALL32 %In_Set                              ; See if we have a match
+	CMPI8_EAX !1                                ; IF match
+	JNE32 %primary_expr_num                     ; otherwise try number
+
+	;; Deal with variables
+	CALL32 %primary_expr_variable               ; Deal with variable
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_num
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	LOADI32_EBX &primary_expr_string_7          ; Using "0123456789"
+	CALL32 %In_Set                              ; See if we have a match
+	CMPI8_EAX !1                                ; IF match
+	JNE32 %primary_expr_fail                    ; otherwise we failed hard
+
+	;; Deal with numbers
+	CALL32 %primary_expr_number                 ; Collect the number
+	JMP32 %primary_expr_done                    ; Be done
+
+:primary_expr_fail
+	;; looks like we hit bad input
+	;; abort before it gets bad
+	CALL32 %primary_expr_failure                ; No match means failure
+:primary_expr_done
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:primary_expr_string_0  "LOAD_IMMEDIATE_eax %0
+"
+:primary_expr_string_1  "SUBTRACT_eax_from_ebx_into_ebx
+MOVE_ebx_to_eax
+"
+:primary_expr_string_2  "LOAD_IMMEDIATE_eax %1
+"
+:primary_expr_string_3  "XOR_ebx_eax_into_eax
+"
+:primary_expr_string_4  "NOT_eax
+"
+:primary_expr_string_5  "Error in Primary expression
+Didn't get )
+"
+:primary_expr_string_6  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
+:primary_expr_string_7  "0123456789"
+
+
+;; primary_expr_variable function
+;; Recieves nothing
+;; Returns nothing
+;; Walks global and updates output
+;; Uses EAX for struct token_list* a and ECX for char* S
+:primary_expr_variable
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_ECX_from_EAX_Immediate8 !8           ; S = global_token->S
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	COPY_ECX_to_EAX                             ; Using S
+	LOAD32_Absolute32_ebx &global_constant_list ; Using global_constant_list
+	CALL32 %sym_lookup                          ; sym_lookup(s, global_constant_list)
+	CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_constant_list)
+	JE32 %primary_expr_variable_local           ; Try locals next
+
+	;; Deal with constant load
+	LOAD32_EBX_from_EAX_Immediate8 !16          ; a->ARGS
+	LOADI32_EAX &primary_expr_variable_string_2 ; Using "LOAD_IMMEDIATE_eax %"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; a->ARGS->S
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &primary_expr_variable_string_1 ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+	JMP32 %primary_expr_variable_done           ; Be done
+
+:primary_expr_variable_local
+	COPY_ECX_to_EAX                             ; Using S
+	LOAD32_Absolute32_ebx &function             ; Using function
+	LOAD32_EBX_from_EBX_Immediate8 !4           ; function->locals
+	CALL32 %sym_lookup                          ; sym_lookup(s, function->locals)
+	CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_constant_list)
+	JE32 %primary_expr_variable_arguments       ; try arguments next
+
+	;; Deal with local load
+	CALL32 %variable_load                       ; Collect it
+	JMP32 %primary_expr_variable_done           ; Be done
+
+:primary_expr_variable_arguments
+	COPY_ECX_to_EAX                             ; Using S
+	LOAD32_Absolute32_ebx &function             ; Using function
+	LOAD32_EBX_from_EBX_Immediate8 !16          ; function->args
+	CALL32 %sym_lookup                          ; sym_lookup(s, function->args)
+	CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_constant_list)
+	JE32 %primary_expr_variable_function        ; try functions next
+
+	;; Deal with argument load
+	CALL32 %variable_load                       ; Collect it
+	JMP32 %primary_expr_variable_done           ; Be done
+
+:primary_expr_variable_function
+	COPY_ECX_to_EAX                             ; Using S
+	LOAD32_Absolute32_ebx &global_function_list ; Using global_function_list
+	CALL32 %sym_lookup                          ; sym_lookup(s, global_function_list)
+	CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_function_list)
+	JE32 %primary_expr_variable_global          ; try globals next
+
+	;; Deal with functions
+	CALL32 %function_load                       ; Deal with the function
+	JMP32 %primary_expr_variable_done           ; Be done
+
+:primary_expr_variable_global
+	COPY_ECX_to_EAX                             ; Using S
+	LOAD32_Absolute32_ebx &global_symbol_list   ; Using global_symbol_list
+	CALL32 %sym_lookup                          ; sym_lookup(s, global_symbol_list)
+	CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_symbol_list)
+	JE32 %primary_expr_variable_error           ; Give up
+
+	;; Deal with globals
+	CALL32 %global_load                         ; Collect that global
+	JMP32 %primary_expr_variable_done           ; Be done
+
+:primary_expr_variable_error
+	LOADI32_EAX %2                              ; Using standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+;	CALL32 %line_error                          ; Write useful debug info
+	COPY_ECX_to_EAX                             ; put S in the right place
+	CALL32 %File_Print                          ; print it
+
+	LOADI32_EAX &primary_expr_variable_string_0 ; Ending string
+	CALL32 %File_Print                          ; print it
+	JMP32 %Exit_Failure                         ; Abort Hard
+
+:primary_expr_variable_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:primary_expr_variable_string_0  " is not a defined symbol
+"
+:primary_expr_variable_string_1  "
+"
+:primary_expr_variable_string_2  "LOAD_IMMEDIATE_eax %"
+
+
+;; function_call function
+;; Recieves char* S in EAX and int BOOL in EBX
+;; Builds stack frames before and tears them down after function calls
+;; Uses ECX for char* S, EDX for int BOOL, ESI for PASSED
+:function_call
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	PUSH_ESI                                    ; Protect ESI
+	COPY_EAX_to_ECX                             ; Put S in place
+	COPY_EBX_to_EDX                             ; Put BOOL in place
+	LOADI32_ESI %0                              ; PASSED = 0
+
+	LOADI32_EAX &function_call_string_0         ; Using "ERROR in process_expression_list\nNo ( was found\n"
+	LOADI32_EBX &open_paren                     ; Using "("
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOADI32_EAX &function_call_string_1         ; Using "PUSH_edi\t# Prevent overwriting in recursion\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_2         ; Using "PUSH_ebp\t# Protect the old base pointer\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_3         ; Using "COPY_esp_to_edi\t# Copy new base pointer\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !41                               ; IF global_token->S[0] == ")"
+	JE32 %function_call_gen_done                ; Then no arguments to send
+
+	;; looks like we have arguments to collect
+	CALL32 %expression                          ; Collect the argument
+
+	LOADI32_EAX &function_call_string_4         ; Using "PUSH_eax\t#_process_expression1\n"
+	CALL32 %emit_out                            ; Emit it
+	LOADI32_ESI %1                              ; PASSED = 1
+
+:function_call_gen_iter
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !44                               ; IF global_token->S[0] == ","
+	JNE32 %function_call_gen_done               ; Otherwise we are done
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	CALL32 %expression                          ; Collect the argument
+
+	LOADI32_EAX &function_call_string_5         ; Using "PUSH_eax\t#_process_expression2\n"
+	CALL32 %emit_out                            ; Emit it
+	ADDI8_ESI !1                                ; PASSED = PASSED + 1
+	JMP32 %function_call_gen_iter               ; Keep trying
+
+:function_call_gen_done
+	;; All is collected
+	LOADI32_EAX &function_call_string_6         ; Using "ERROR in process_expression_list\nNo ) was found\n"
+	LOADI32_EBX &close_paren                    ; Using ")"
+	CALL32 %require_match                       ; Make sure we have it
+
+	CMPI8_EDX !0                                ; IF(BOOL == TRUE)
+	JNE32 %function_call_static                 ; Otherwise it is a static call
+
+	;; Deal with a passed function pointer
+	LOADI32_EAX &function_call_string_7         ; Using "LOAD_BASE_ADDRESS_eax %"
+	CALL32 %emit_out                            ; Emit it
+
+	COPY_ECX_to_EAX                             ; Using S
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_8         ; Using "\nLOAD_INTEGER\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_9         ; Using "COPY_edi_to_ebp\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_10        ; Using "CALL_eax\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_13        ; Using "POP_ebx\t# _process_expression_locals\n"
+	JMP32 %function_call_cleanup                ; Clean up
+
+:function_call_static
+	;; Deal with fixed function name
+	LOADI32_EAX &function_call_string_9         ; Using "COPY_edi_to_ebp\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_11        ; Using "CALL_IMMEDIATE %FUNCTION_"
+	CALL32 %emit_out                            ; Emit it
+
+	COPY_ECX_to_EAX                             ; Using S
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_12        ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_13        ; Using "POP_ebx\t# _process_expression_locals\n"
+
+:function_call_cleanup
+	CMPI8_ESI !0                                ; IF PASSED > 0
+	JLE32 %function_call_done                   ; Otherwise be done
+
+	;; The desired string is already in EAX
+	CALL32 %emit_out                            ; Emit it
+
+	SUBI8_ESI !1                                ; PASSED = PASSED - 1
+	JMP32 %function_call_cleanup                ; Keep going
+
+:function_call_done
+	LOADI32_EAX &function_call_string_14        ; Using "POP_ebp\t# Restore old base pointer\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_call_string_15        ; Using "POP_edi\t# Prevent overwrite\n"
+	CALL32 %emit_out                            ; Emit it
+
+	POP_ESI                                     ; Restore ESI
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:function_call_string_0  "ERROR in process_expression_list
+No ( was found
+"
+:function_call_string_1  "PUSH_edi	# Prevent overwriting in recursion
+"
+:function_call_string_2  "PUSH_ebp	# Protect the old base pointer
+"
+:function_call_string_3  "COPY_esp_to_edi	# Copy new base pointer
+"
+:function_call_string_4  "PUSH_eax	#_process_expression1
+"
+:function_call_string_5  "PUSH_eax	#_process_expression2
+"
+:function_call_string_6  "ERROR in process_expression_list
+No ) was found
+"
+:function_call_string_7  "LOAD_BASE_ADDRESS_eax %"
+:function_call_string_8  "
+LOAD_INTEGER
+"
+:function_call_string_9  "COPY_edi_to_ebp
+"
+:function_call_string_10 "CALL_eax
+"
+:function_call_string_11 "CALL_IMMEDIATE %FUNCTION_"
+:function_call_string_12 "
+"
+:function_call_string_13 "POP_ebx	# _process_expression_locals
+"
+:function_call_string_14 "POP_ebp	# Restore old base pointer
+"
+:function_call_string_15 "POP_edi	# Prevent overwrite
+"
+
+
+;; variable_load function
+;; Recieves struct token_list* A in EAX
+;; Returns nothing
+;; Updates output and current_target
+;; Uses ECX for A
+:variable_load
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_ECX                             ; Protect A
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &open_paren                     ; Using "("
+	CALL32 %match                               ; IF global_token->S == "("
+	CMPI8_EAX !0                                ; Then it might be a function
+	JNE32 %variable_load_regular                ; Otherwise it is regular
+
+	LOAD32_EBX_from_ECX_Immediate8 !12          ; A->TYPE
+	LOAD32_EBX_from_EBX_Immediate8 !24          ; A->TYPE->NAME
+	LOADI32_EAX &type_function_name             ; Using "FUNCTION"
+	CALL32 %match                               ; IF A->TYPE->NAME == "FUNCTION"
+	CMPI8_EAX !0                                ; Then it must be a function
+	JNE32 %variable_load_regular                ; otherwise just another regular
+
+	;; deal with function
+	LOAD32_EAX_from_ECX_Immediate8 !16          ; A->DEPTH
+	CALL32 %numerate_number                     ; Convert to string
+	LOADI32_EBX %0                              ; pass 0 for true
+	CALL32 %function_call                       ; Create the function call
+	JMP32 %variable_load_done                   ; Be done
+
+:variable_load_regular
+	LOAD32_EAX_from_ECX_Immediate8 !12          ; A->TYPE
+	STORE32_Absolute32_eax &current_target      ; current_target = A->TYPE
+
+	LOADI32_EAX &variable_load_string_0         ; Using "LOAD_BASE_ADDRESS_eax %"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_EAX_from_ECX_Immediate8 !16          ; A->DEPTH
+	CALL32 %numerate_number                     ; Convert to string
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &variable_load_string_1         ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+	;; Check for special case of assignment
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &equal                          ; Using "="
+	CALL32 %match                               ; IF global_token->S == "="
+	CMPI8_EAX !0                                ; Then we skip loading
+	JE32 %variable_load_done                    ; And be done
+
+	;; Deal with common case
+	LOADI32_EAX &variable_load_string_2         ; Using "LOAD_INTEGER\n"
+	CALL32 %emit_out                            ; Emit it
+
+:variable_load_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:variable_load_string_0  "LOAD_BASE_ADDRESS_eax %"
+:variable_load_string_1  "
+"
+:variable_load_string_2  "LOAD_INTEGER
+"
+
+
+;; function_load function
+;; Recieves struct token_list* a in EAX
+;; Returns nothing
+;; Uses ECX to hold A->S
+:function_load
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; A->S
+	COPY_EAX_to_ECX                             ; Protect A->S
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &open_paren                     ; Using "("
+	CALL32 %match                               ; IF global_token->S == "("
+	CMPI8_EAX !0                                ; The we need to do a function call
+	JNE32 %function_load_regular                ; Otherwise just load it's address
+
+	;; Deal with function call
+	COPY_ECX_to_EAX                             ; Using A->S
+	LOADI32_EBX %1                              ; Using FALSE
+	CALL32 %function_call                       ; Deal with it
+	JMP32 %function_load_done                   ; Be done
+
+:function_load_regular
+	LOADI32_EAX &function_load_string_0         ; Using "LOAD_IMMEDIATE_eax &FUNCTION_"
+	CALL32 %emit_out                            ; Emit it
+
+	COPY_ECX_to_EAX                             ; Using A->S
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &function_load_string_1         ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+:function_load_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:function_load_string_0  "LOAD_IMMEDIATE_eax &FUNCTION_"
+:function_load_string_1  "
+"
+
+
+;; global_load function
+;; Recieves struct token_list* A in EAX
+;; Returns nothing
+;; Uses EBX to hold A->S
+:global_load
+	PUSH_EBX                                    ; Protect EBX
+	COPY_EAX_to_EBX                             ; Set as A
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; Set as A->S
+
+	LOAD32_EAX_from_EAX_Immediate8 !12          ; A->TYPE
+	STORE32_Absolute32_eax &current_target      ; current_target = A->TYPE
+
+	LOADI32_EAX &global_load_string_0           ; Using "LOAD_IMMEDIATE_eax &GLOBAL_"
+	CALL32 %emit_out                            ; Emit it
+
+	COPY_EBX_to_EAX                             ; Using A->S
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &global_load_string_1           ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &equal                          ; "="
+	CALL32 %match                               ; IF global_token->S == "="
+	CMPI8_EAX !0                                ; We need to skip for assignment
+	JE32 %global_load_done                      ; and be done
+
+	;; Otherwise we are loading the contents
+	LOADI32_EAX &global_load_string_2           ; Using "LOAD_INTEGER\n"
+	CALL32 %emit_out                            ; Emit it
+
+:global_load_done
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:global_load_string_0  "LOAD_IMMEDIATE_eax &GLOBAL_"
+:global_load_string_1  "
+"
+:global_load_string_2  "LOAD_INTEGER
+"
+
+
+;; sym_lookup function
+;; Recieves char* S in EAX and struct token_list* symbol_list in EBX
+;; Uses I->S in EAX, S in EBX and I in ECX
+;; Returns match or NULL
+:sym_lookup
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EBX_to_ECX                             ; I = symbol_list
+	COPY_EAX_to_EBX                             ; Put S in the right place
+:sym_lookup_iter
+	CMPI8_ECX !0                                ; IF NULL == I
+	JE32 %sym_lookup_done                       ; We failed to find match
+
+	LOAD32_EAX_from_ECX_Immediate8 !8           ; Using I->S
+	CALL32 %match                               ; IF I->S == S
+	CMPI8_EAX !0                                ; then be done
+	JE32 %sym_lookup_done                       ; Failed
+
+	LOAD32_ECX_from_ECX                         ; I = I->NEXT
+	JMP32 %sym_lookup_iter                      ; otherwise keep looping
+
+:sym_lookup_done
+	COPY_ECX_to_EAX                             ; Return I
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; primary_expr_number function
+;; Recieves nothing
+;; Returns nothing
+;; Simply uses current global token to update output and then steps to next global_token
+:primary_expr_number
+	LOADI32_EAX &primary_expr_number_string_0   ; Using "LOAD_IMMEDIATE_eax %"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %emit_out                            ; Emit it
+
+	LOADI32_EAX &primary_expr_number_string_1   ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+	RETURN
+
+:primary_expr_number_string_0  "LOAD_IMMEDIATE_eax %"
+:primary_expr_number_string_1  "
+"
+
+
+;; primary_expr_string function
+;; recieves nothing
+;; Returns nothing
+;; creates entries for string and calls to generate string output
+;; uses ECX for char* number_string
+:primary_expr_string
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_ebx &current_count        ; Using current_count
+	COPY_EBX_to_EAX                             ; And putting it in the right place
+	CALL32 %numerate_number                     ; Get the string
+	COPY_EAX_to_ECX                             ; protect number_string
+
+	ADDI8_EBX !1                                ; current_count + 1
+	STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
+
+	LOADI32_EAX &primary_expr_string_string_0   ; Using "LOAD_IMMEDIATE_eax &STRING_"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	COPY_ECX_to_EBX                             ; Put number_string in the right place
+	CALL32 %uniqueID_out                        ; Make it unique
+
+	;; Generate the target
+	LOADI32_EAX &primary_expr_string_string_1   ; Using ":STRING_"
+	LOAD32_Absolute32_ebx &strings_list         ; Using strings_list
+	CALL32 %emit                                ; Emit it
+	COPY_EAX_to_EBX                             ; put new strings_list in place
+
+	LOAD32_Absolute32_eax &function             ; Using function
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
+	CALL32 %uniqueID                            ; Make it unique
+	COPY_EAX_to_EBX                             ; put new strings_list in place
+
+	;; Parse the string
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %parse_string                        ; convert to useful form
+	CALL32 %emit                                ; Emit it
+	STORE32_Absolute32_eax &strings_list        ; Update Strings _list
+
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:primary_expr_string_string_0  "LOAD_IMMEDIATE_eax &STRING_"
+:primary_expr_string_string_1  ":STRING_"
+
+
+;; primary_expr_char function
+;; Recieves nothing
+;; Returns nothing
+;; Updates output_list using global_token
+:primary_expr_char
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOADI32_EAX &primary_expr_char_string_0     ; Using "LOAD_IMMEDIATE_eax %"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	ADDI8_EAX !1                                ; global_token->S + 1
+	CALL32 %escape_lookup                       ; Get the char
+	CALL32 %numerate_number                     ; Convert to string
+	CALL32 %emit_out                            ; emit it
+
+	LOADI32_EAX &primary_expr_char_string_1     ; Using "\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:primary_expr_char_string_0  "LOAD_IMMEDIATE_eax %"
+:primary_expr_char_string_1  "
+"
+
+
+;; primary_expr_failure function
+;; Recieves nothing
+;; Does not return but aborts hard
+;; Complains about the bad input
+:primary_expr_failure
+;	CALL32 %line_error                          ; Get line of issue
+	LOADI32_EAX %2                              ; Using Standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+	LOADI32_EAX &primary_expr_failure_string_0  ; Using "Recieved "
+	CALL32 %File_Print                          ; Print it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %File_Print                          ; Print it
+
+	LOADI32_EAX &primary_expr_failure_string_1  ; Using " in primary_expr\n"
+	CALL32 %File_Print                          ; Print it
+	JMP32 %Exit_Failure                         ; Abort Hard
+
+:primary_expr_failure_string_0  "Recieved "
+:primary_expr_failure_string_1  " in primary_expr
+"
+
+
+;; general_recursion function
+;; Recieves FUNCTION F in EAX, char* S in EBX, char* name in ECX and FUNCTION iterate in EDX
+;; Returns nothing
+;; Uses ECX for char* S, EDX for FUNCTION iterate and EBP for FUNCTION F
+;; But generally recurses a shitload
+:general_recursion
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	PUSH_EBP                                    ; Protect EBP
+	COPY_EAX_to_EBP                             ; Protect F
+	COPY_ECX_to_EAX                             ; Put name in the right place
+	COPY_EBX_to_ECX                             ; Protect S
+
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	CALL32 %match                               ; IF match(name, global_token->s)
+	CMPI8_EAX !0                                ; If true we do
+	JNE32 %general_recursion_done               ; Otherwise skip it
+
+	;; Deal with the recursion
+	COPY_EBP_to_EAX                             ; Put F in the right place
+	CALL32 %common_recursion                    ; Recurse
+
+	COPY_ECX_to_EAX                             ; Put S in the right place
+	CALL32 %emit_out                            ; Emit it
+
+	COPY_EDX_to_EAX                             ; Put iterate in the right place
+	CALL_EAX                                    ; Down the rabbit hole
+
+:general_recursion_done
+	POP_EBP                                     ; Restore EBP
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; promote_type function
+;; Recieves struct type* a in EAX and struct type* b in EBX
+;; Returns the most recent type in EAX
+;; Uses EAX for struct type* I, ECX for struct type* A and EDX for struct type* B
+:promote_type
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	CMPI8_EBX !0                                ; IF NULL == A
+	JE32 %promote_type_done                     ; Just return A
+
+	COPY_EAX_to_ECX                             ; Put A in place
+	COPY_EBX_to_EDX                             ; Put B in place
+	COPY_EBX_to_EAX                             ; IF NULL == A
+	CMPI8_ECX !0                                ; Then we just return B
+	JE32 %promote_type_done                     ; Be done
+
+	;; Looks like we need to walk the list
+	LOAD32_ECX_from_ECX_Immediate8 !24          ; A->NAME
+	LOAD32_EDX_from_EDX_Immediate8 !24          ; B->NAME
+	LOAD32_Absolute32_eax &global_types         ; I = global_types
+:promote_type_iter
+	CMPI8_EAX !0                                ; IF NULL == I
+	JE32 %promote_type_done                     ; Just be done
+
+	LOAD32_EBX_from_EAX_Immediate8 !24          ; I->NAME
+	CMP_ECX_EBX                                 ; IF(A->NAME == I->NAME)
+	JE32 %promote_type_done                     ; Be done
+
+	CMP_EBX_EDX                                 ; IF(B->NAME == I->NAME)
+	JE32 %promote_type_done                     ; Be done
+
+	LOAD32_EBX_from_EAX_Immediate8 !12          ; I->INDIRECT
+	LOAD32_EBX_from_EBX_Immediate8 !24          ; I->INDIRECT->NAME
+
+	CMP_ECX_EBX                                 ; IF(A->NAME == I->INDIRECT->NAME)
+	JE32 %promote_type_done                     ; Be done
+
+	CMP_EBX_EDX                                 ; IF(B->NAME == I->INDIRECT->NAME)
+	JE32 %promote_type_done                     ; Be done
+
+	LOAD32_EAX_from_EAX                         ; I = I->NEXT
+	JMP32 %promote_type_iter                    ; Keep going
+
+:promote_type_done
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; common_recursion function
+;; Recieves FUNCTION F in EAX
+;; Returns Nothing
+;; Walks global_token list and update output_list
+;; Updates current_target
+;; Uses EBX to hold FUNCTION F and struct type* last_type
+:common_recursion
+	PUSH_EBX                                    ; Protect EBX
+	COPY_EAX_to_EBX                             ; Put FUNCTION F safely out of the way
+	LOADI32_EAX &common_recursion_string_0      ; Using "PUSH_eax\t#_common_recursion\n"
+	CALL32 %emit_out                            ; Emit it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	COPY_EBX_to_EAX                             ; Prepare for function call
+	LOAD32_Absolute32_ebx &current_target       ; Get last type
+	CALL_EAX                                    ; F();
+	LOAD32_Absolute32_eax &current_target       ; Get current_target
+	CALL32 %promote_type                        ; get the right type
+	STORE32_Absolute32_eax &current_target      ; Set new current_target
+
+	LOADI32_EAX &common_recursion_string_1      ; Using "POP_ebx\t# _common_recursion\n"
+	CALL32 %emit_out                            ; Emit it
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:common_recursion_string_0  "PUSH_eax	#_common_recursion
+"
+:common_recursion_string_1  "POP_ebx	# _common_recursion
+"
+
+
+;; require_match function
+;; Recieves char* message in EAX and char* required in EBX
+;; Returns nothing
+;; Uses ECX to hold message and updates global_token
+:require_match
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_ECX                             ; put the message somewhere safe
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %match                               ; IF required == global_token->S
+	CMPI8_EAX !0                                ; we are fine
+	JE32 %require_match_good                    ; otherwise pain
+
+	;; Deal will bad times
+;	CALL32 %line_error                          ; Tell user what went wrong
+	LOADI32_EAX %2                              ; Using standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+	COPY_ECX_to_EAX                             ; using our message
+	CALL32 %File_Print                          ; Print it
+	JMP32 %Exit_Failure                         ; Abort HARD
+
+:require_match_good
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->next
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; uniqueID Function
+;; Recieves char*S in EAX, struct token_list* l in EBX snd char* num in ECX
+;; Returns updated struct token_list* L in EAX
+:uniqueID
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	CALL32 %emit                                ; emit(s, l)
+	COPY_EAX_to_EBX                             ; Put L in correct place
+	LOADI32_EAX &underline                      ; Usinf "_"
+	CALL32 %emit                                ; emit("_", l)
+	COPY_EAX_to_EBX                             ; Put L in correct place
+	COPY_ECX_to_EAX                             ; Put num in correct place
+	CALL32 %emit                                ; emit(num, l)
+	COPY_EAX_to_EBX                             ; Put L in correct place
+	LOADI32_EAX &uniqueID_string_0              ; Using "\n"
+	CALL32 %emit                                ; emit("\n", l)
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:uniqueID_string_0  "
+"
+
+
+;; uniqueID_out function
+;; Recieves char* S in EAX and char* num in EBX
+;; Returns nothing
+:uniqueID_out
+	PUSH_EAX                                    ; Protect EAX
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EBX_to_ECX                             ; Put num in right spot
+	LOAD32_Absolute32_ebx &output_list          ; Using output_list
+	CALL32 %uniqueID                            ; Get updated list
+	STORE32_Absolute32_eax &output_list         ; output_list = uniqueID(s, output_list, num)
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	POP_EAX                                     ; Restore EAX
+	RETURN
+
+
+;; emit_out function
+;; Recieves char* S in EAX
+;; Returns nothing
+;; Updates output_list
+;; MUST NOT ALTER REGISTERS
+:emit_out
+	PUSH_EAX                                    ; Protect EAX
+	PUSH_EBX                                    ; Protect EBX
+	LOAD32_Absolute32_ebx &output_list          ; Using output_list
+	CALL32 %emit                                ; emit it
+	STORE32_Absolute32_eax &output_list         ; update it
+	POP_EBX                                     ; Restore EBX
+	POP_EAX                                     ; Restore EAX
+	RETURN
+
+
+;; emit function
+;; Recieves char *s in EAX and struct token_list* head in EBX
+;; Returns struct token_list* T in EAX
+:emit
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_ECX                             ; put S out of the way
+	LOADI32_EAX %20                             ; sizeof(struct token_list)
+	CALL32 %malloc                              ; get T
+	STORE32_EBX_into_EAX                        ; t->next = head;
+	STORE32_ECX_into_EAX_Immediate8 !8          ; t->s = s;
+	POP_ECX                                     ; Restore ECX
+	RETURN
+
+
+;; escape_lookup function
+;; Recieves char* c in EAX
+;; Returns integer value of char in EAX
+;; Aborts hard if unknown escape is recieved
+;; Uses ECX to hold char* C
+:escape_lookup
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_ECX                             ; Put char* C in safe place
+	LOAD8_al_from_ECX                           ; Load c[0]
+	MOVZX_al                                    ; make it useful
+	CMPI8_EAX !92                               ; If '\\' != c[0]
+	JNE32 %escape_lookup_done                   ; Be done
+
+	COPY_ECX_to_EBX                             ; Prepare for walk
+	ADDI8_EBX !1                                ; increment
+	LOAD8_bl_from_EBX                           ; load c[1]
+	MOVZX_bl                                    ; make it useful
+
+	CMPI8_EBX !120                              ; Check if \x??
+	JE32 %escape_lookup_hex                     ; Deal with hex
+
+	;; Deal with \? escapes
+	LOADI32_EAX %10                             ; Guess "\n"
+	CMPI8_EBX !110                              ; If n
+	JE32 %escape_lookup_done                    ; Be done
+
+	LOADI32_EAX %9                              ; Guess "\t"
+	CMPI8_EBX !116                              ; If t
+	JE32 %escape_lookup_done                    ; Be done
+
+	COPY_EBX_to_EAX                             ; "\\", "'" and '\"' all encode as themselves
+	CMPI8_EBX !92                               ; If "\\"
+	JE32 %escape_lookup_done                    ; Be done
+	CMPI8_EBX !39                               ; IF "'"
+	JE32 %escape_lookup_done                    ; Be done
+	CMPI8_EBX !34                               ; IF '\"'
+	JE32 %escape_lookup_done                    ; Be done
+
+	LOADI32_EAX %13                             ; Guess "\r"
+	CMPI8_EBX !114                              ; IF r
+	JE32 %escape_lookup_done                    ; Be done
+
+	;; Looks like we have no clue what we are doing
+	;; Aborting hard
+	LOADI32_EAX %2                              ; Using Standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+	LOADI32_EAX &escape_lookup_string_0         ; Using "Unknown escape recieved: "
+	CALL32 %File_Print                          ; Print it
+	COPY_ECX_to_EAX                             ; Using C
+	CALL32 %File_Print                          ; Print it
+	LOADI32_EAX &escape_lookup_string_1         ; Using " Unable to process\n"
+	CALL32 %File_Print                          ; Print it
+	JMP32 %Exit_Failure                         ; Abort Hard
+
+:escape_lookup_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:escape_lookup_hex
+	;; Give up on C and just assume they know what they are doing
+	ADDI8_ECX !2                                ; increment
+	LOAD8_al_from_ECX                           ; c[2]
+	MOVZX_al                                    ; make it useful
+	ADDI8_ECX !1                                ; increment
+	CALL32 %char2hex                            ; Get the hex value
+	SALI8_EAX !4                                ; c << 4
+	LOAD8_bl_from_ECX                           ; c[3]
+	MOVZX_bl                                    ; make it useful
+	SWAP_EAX_EBX                                ; protect c << 4
+	CALL32 %char2hex                            ; Get the hex value
+	ADD_ebx_into_eax                            ; hex(c[2]) << 4 + hex(c[3])
+	JMP32 %escape_lookup_done                   ; Be done
+
+:escape_lookup_string_0  "Unknown escape recieved: "
+:escape_lookup_string_1  " Unable to process
+"
+
+
+;; char2hex function
+;; Recieves char in EAX
+;; Returns hex or aborts hard
+:char2hex
+	SUBI8_EAX !48                               ; Try 0-9
+	CMPI8_EAX !10                               ; Otherwise fun times
+	JL32 %char2hex_done                         ; Be done
+
+	;; Deal with A-F
+	ANDI32_EAX %0xDF                            ; Unset High bit turning a-f into A-F
+	SUBI8_EAX !7                                ; Shift down into position
+	CMPI8_EAX !10                               ; Everything below A is bad
+	JL32 %char2hex_fail                         ; And should fail
+	CMPI8_EAX !16                               ; Make sure we are below F
+	JL32 %char2hex_done                         ; If so be done
+
+:char2hex_fail
+	;; Time to fail hard
+	LOADI32_EAX %2                              ; Using Standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+	LOADI32_EAX &char2hex_string_0              ; Using "Tried to print non-hex number\n"
+	CALL32 %File_Print                          ; Print it
+	JMP32 %Exit_Failure                         ; Abort Hard
+
+:char2hex_done
+	RETURN
+
+:char2hex_string_0  "Tried to print non-hex number
+"
+
+
+;; parse_string function
+;; Recieves char* string in EAX
+;; Returns cleaned up string
+;; Protects char* string in EBX
+:parse_string
+	PUSH_EBX                                    ; Protect EBX
+	COPY_EAX_to_EBX                             ; Protect char* string
+	CALL32 %weird                               ; Determine if we have a weird string
+	CMPI8_EAX !0                                ; If weird
+	JE32 %parse_string_weird                    ; Deal with it
+
+	;; Dealing with regular string
+	COPY_EBX_to_EAX                             ; Passing Char* string
+	CALL32 %collect_regular_string              ; Collect it
+	JMP32 %parse_string_done                    ; Be done
+
+:parse_string_weird
+	COPY_EBX_to_EAX                             ; Passing Char* string
+	CALL32 %collect_weird_string                ; Collect it
+
+:parse_string_done
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; weird function
+;; Recieves char* string in EAX
+;; Returns true(0) or false(1) in EAX
+;; Uses ECX to hold char* string
+:weird
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EAX_to_ECX                             ; Place string in safe place
+	ADDI8_ECX !1                                ; increment past the '\"'
+:weird_reset
+	LOAD8_al_from_ECX                           ; Load a char
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !0                                ; IF NULL == C
+	JE32 %weird_false                           ; Nothing weird found
+
+	CMPI8_EAX !92                               ; IF '\\'
+	JNE32 %weird_escaped                        ; Deal with escaping
+
+	;; Deal with escape
+	COPY_ECX_to_EAX                             ; We are passing the string
+	CALL32 %escape_lookup                       ; to look it up
+
+	ADDI8_ECX !1                                ; string = string + 1
+	LOAD8_bl_from_ECX                           ; get string[1]
+	MOVZX_bl                                    ; make it useful
+	CMPI8_EBX !120                              ; IF 'x' == string[1]
+	JNE32 %weird_escaped                        ; otherwise skip the gap
+
+	ADDI8_ECX !2                                ; string = string + 2
+
+:weird_escaped
+	PUSH_EAX                                    ; Protect C in case we need it
+	LOADI32_EBX &weird_string_0                 ; Use "\t\n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
+	CALL32 %In_Set                              ; To find if weird
+	CMPI8_EAX !1                                ; IF TRUE
+	POP_EAX                                     ; Restore C
+	JNE32 %weird_true                           ; Then not weird
+
+	ADDI8_ECX !1                                ; string = string + 1
+
+	;; Last chance for weird
+	LOADI32_EBX &weird_string_1                 ; Use "\t\n\r "
+	CALL32 %In_Set                              ; Check for special case
+	CMPI8_EAX !1                                ; IF TRUE
+	JNE32 %weird_reset                          ; Otherwise not in the special case
+
+	;; Deal with possible special case
+	LOAD8_al_from_ECX                           ; Load string[1]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !58                               ; IF string[1] == ":"
+	JE32 %weird_true                            ; Then we hit the special case
+	JMP32 %weird_reset                          ; Keep trying
+
+:weird_done
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:weird_true
+	LOADI32_EAX %0                              ; Return true
+	JMP32 %weird_done                           ; Be done
+
+:weird_false
+	LOADI32_EAX %1                              ; Return false
+	JMP32 %weird_done                           ; Be done
+
+:weird_string_0  "	
+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
+:weird_string_1  '09 0A 0D 20' ; "\t\n\r "
+
+
+;; collect_regular_string function
+;; Recieves char* string in EAX
+;; Malloc and creates new string to return in EAX
+;; Uses ECX for return string and EDX for passed string
+:collect_regular_string
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	COPY_EAX_to_EDX                             ; Protect our passed string
+	LOADI32_EAX %256                            ; We need 256bytes of storage
+	CALL32 %malloc                              ; Get our new pointer
+	COPY_EAX_to_ECX                             ; put it in place
+	PUSH_EAX                                    ; protect until done
+:collect_regular_string_reset
+	LOAD8_al_from_EDX                           ; string[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !0                                ; See if we hit the end
+	JE32 %collect_regular_string_done           ; And be done
+
+	CMPI8_EAX !92                               ; IF string[0] == '\\'
+	JE32 %collect_regular_string_escaped        ; Deal with that mess
+
+	;; deal with boring char
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = string[0]
+	ADDI8_ECX !1                                ; Increment it
+	ADDI8_EDX !1                                ; Increment it
+	JMP32 %collect_regular_string_reset         ; And keep going
+
+:collect_regular_string_escaped
+	COPY_EDX_to_EAX                             ; Using string
+	CALL32 %escape_lookup                       ; Get the char
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = escape_lookup(string)
+	ADDI8_EDX !1                                ; Increment it
+	ADDI8_ECX !1                                ; Increment it
+	LOAD8_al_from_EDX                           ; string[0]
+	MOVZX_al                                    ; Make it useful
+	ADDI8_EDX !1                                ; Increment it
+	CMPI8_EAX !120                              ; IF 'x' == string[1]
+	JNE32 %collect_regular_string_reset         ; Otherwise keep going
+
+	ADDI8_EDX !2                                ; Increment it
+	JMP32 %collect_regular_string_reset         ; Keep going
+
+:collect_regular_string_done
+	LOADI32_EAX %34                             ; Using '\"'
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = '\"'
+	ADDI8_ECX !1                                ; Increment it
+	LOADI32_EAX %10                             ; Using "\n"
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = '\n'
+	POP_EAX                                     ; Return our new string
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; collect_weird_string function
+;; Recieves char* string in EAX
+;; Mallocs and returns char* hold in EAX
+;; Uses ECX for char* hold and EDX for char* string
+:collect_weird_string
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	COPY_EAX_to_EDX                             ; Protect our passed string
+	LOADI32_EAX %512                            ; We need 512bytes of storage
+	CALL32 %malloc                              ; Get our new pointer
+	COPY_EAX_to_ECX                             ; put it in place
+	PUSH_EAX                                    ; protect until done
+
+	LOADI32_EAX %39                             ; Using "'"
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = "'"
+	ADDI8_ECX !1                                ; Increment it
+	ADDI8_EDX !1                                ; Increment it
+:collect_weird_string_reset
+	LOAD8_al_from_EDX                           ; Read a byte
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !0                                ; IF NULL == string[0]
+	JE32 %collect_weird_string_done             ; Be done
+
+	LOADI32_EAX %32                             ; Using ' '
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = ' '
+	ADDI8_ECX !1                                ; Increment it
+
+	COPY_EDX_to_EAX                             ; Using string
+	CALL32 %escape_lookup                       ; Get the char
+	CALL32 %hex8                                ; Update ECX
+
+	LOAD8_al_from_EDX                           ; Read a byte
+	MOVZX_al                                    ; Make it useful
+	ADDI8_EDX !1                                ; Increment it
+	CMPI8_EAX !92                               ; IF string[0] == '\\'
+	JNE32 %collect_weird_string_reset           ; Otherwise keep going
+
+	LOAD8_al_from_EDX                           ; Read a byte
+	MOVZX_al                                    ; Make it useful
+	ADDI8_EDX !1                                ; Increment it
+	CMPI8_EAX !120                              ; IF 'x' == string[1]
+	JNE32 %collect_weird_string_reset           ; Otherwise keep going
+
+	ADDI8_EDX !2                                ; Increment it
+	JMP32 %collect_weird_string_reset           ; Keep going
+
+:collect_weird_string_done
+	LOADI32_EAX %32                             ; Using ' '
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = ' '
+	ADDI8_ECX !1                                ; Increment it
+	LOADI32_EAX %48                             ; Using '0'
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = '0'
+	ADDI8_ECX !1                                ; Increment it
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = '0'
+	ADDI8_ECX !1                                ; Increment it
+	LOADI32_EAX %39                             ; Using "'"
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = "'"
+	ADDI8_ECX !1                                ; Increment it
+	LOADI32_EAX %10                             ; Using "\n"
+	STORE8_al_into_Address_ECX                  ; hold_string[index] = '\n'
+	POP_EAX                                     ; Return our new string
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; HEX to ascii routine
+;; Recieves INT in EAX and CHAR* in ECX
+;; Stores ascii of INT in CHAR*
+;; Returns only modifying EAX and ECX
+:hex8
+	PUSH_EAX                                    ; Protect bottom nibble
+	SHRI8_EAX !4                                ; do high nibble first
+	CALL32 %hex4                                ; Store it
+	POP_EAX                                     ; do low nibble
+:hex4
+	ANDI32_EAX %0xF                             ; isolate nibble
+	ADDI8_EAX !48                               ; convert to ascii
+	CMPI8_EAX !57                               ; valid digit?
+	JBE8 !hex1                                  ; yes
+	ADDI8_EAX !7                                ; use alpha range
+:hex1
+	STORE8_al_into_Address_ECX                  ; store result
+	ADDI8_ECX !1                                ; next position
+	RETURN
+
+
+;; type_name function
+;; Recieves nothing
+;; Returns type_size in EAX
+;; Uses ECX for STRUCT TYPE* RET
+:type_name
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &struct                         ; Using "struct"
+	CALL32 %match                               ; IF global_token->S == "struct"
+	COPY_EAX_to_ECX                             ; Protect structure
+	CMPI8_EAX !0                                ; need to skip over "struct"
+	JNE32 %type_name_native                     ; otherwise keep going
+
+	;; Deal with possible STRUCTs
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX                         ; global_token->next
+	STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; global_token->S
+	LOAD32_Absolute32_ebx &global_types         ; get all known types
+	CALL32 %lookup_type                         ; Find type if possible
+	COPY_EAX_to_ECX                             ; Set ret
+
+	CMPI8_EAX !0                                ; IF NULL == ret
+	JNE32 %type_name_common                     ; We have to create struct
+
+	;; Create a struct
+	CALL32 %create_struct                       ; Create a new struct
+	LOADI32_ECX %0                              ; We wish to return NULL
+	JMP32 %type_name_done                       ; be done
+
+:type_name_native
+	;; Deal only with native types
+	COPY_EBX_to_EAX                             ; Put global_token->S in the right place
+	LOAD32_Absolute32_ebx &global_types         ; get all known types
+	CALL32 %lookup_type                         ; Find the type if possible
+	COPY_EAX_to_ECX                             ; Set ret
+
+	CMPI8_EAX !0                                ; IF NULL == ret
+	JNE32 %type_name_common                     ; We need to abort hard
+
+	;; Aborting hard
+	LOADI32_EAX %2                              ; Using Standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+	LOADI32_EAX &type_name_string_0             ; Print header
+	CALL32 %File_Print                          ; Print it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %File_Print                          ; Print it
+
+	LOADI32_EAX &type_name_string_1             ; Print footer
+	CALL32 %File_Print                          ; Print it
+
+;	CALL32 %line_error                          ; Give details
+	JMP32 %Exit_Failure                         ; Abort
+
+:type_name_common
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX                         ; global_token->next
+	STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next
+
+:type_name_iter
+	LOAD32_EAX_from_EBX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; make it useful
+	CMPI8_EAX !42                               ; IF global_token->S[0] == '*'
+	JNE32 %type_name_done                       ; recurse
+
+	;; Deal with char**
+	LOAD32_ECX_from_ECX_Immediate8 !12          ; ret = ret->indirect
+	LOAD32_Absolute32_ebx &global_token         ; Using global_token
+	LOAD32_EBX_from_EBX                         ; global_token->next
+	STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next
+	JMP32 %type_name_iter                       ; keep looping
+
+:type_name_done
+	COPY_ECX_to_EAX                             ; put ret in the right place
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:type_name_string_0  "Unknown type "
+:type_name_string_1  "
+"
+
+
+;; lookup_type function
+;; Recieves char* s in EAX and struct type* start in EBX
+;; Returns struct type* in EAX
+;; Uses EBX for S and ECX for I
+:lookup_type
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	COPY_EBX_to_ECX                             ; I = Start
+	COPY_EAX_to_EBX                             ; Put S in place
+:lookup_type_iter
+	CMPI8_ECX !0                                ; Check if I == NULL
+	JE32 %lookup_type_done                      ; return NULL
+
+	LOAD32_EAX_from_ECX_Immediate8 !24          ; I->NAME
+	CALL32 %match                               ; Check if matching
+	CMPI8_EAX !0                                ; IF I->NAME == S
+	JE32 %lookup_type_done                      ; return it
+
+	LOAD32_ECX_from_ECX                         ; Otherwise I = I->NEXT
+	JMP32 %lookup_type_iter                     ; And keep looping
+
+:lookup_type_done
+	COPY_ECX_to_EAX                             ; return either I or NULL
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; create_struct function
+;; Recieves nothing
+;; Returns nothing
+;; Uses global_token to malloc a struct's definition
+;; Uses ECX for int OFFSET, EDX for struct type* head, EBP for struct type* I,
+;; EDI for member_size (Which is passed) and ESI for LAST
+;; EAX and EBX are used for scratch
+:create_struct
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	PUSH_EBP                                    ; Protect EBP
+	PUSH_EDI                                    ; Protect EDI
+	PUSH_ESI                                    ; Protect ESI
+	LOADI32_ECX %0                              ; OFFSET = 0
+	LOADI32_EDI %0                              ; member_size = 0
+
+	LOADI32_EAX %28                             ; sizeof(struct type)
+	CALL32 %malloc                              ; malloc(sizeof(struct type))
+	COPY_EAX_to_EDX                             ; Set HEAD
+
+	LOADI32_EAX %28                             ; sizeof(struct type)
+	CALL32 %malloc                              ; malloc(sizeof(struct type))
+	COPY_EAX_to_EBP                             ; Set I
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	STORE32_EAX_into_EDX_Immediate8 !24         ; HEAD->NAME = global_token->S
+	STORE32_EAX_into_EBP_Immediate8 !24         ; I->NAME = global_token->S
+
+	STORE32_EBP_into_EDX_Immediate8 !12         ; HEAD->INDIRECT = I
+	STORE32_EDX_into_EBP_Immediate8 !12         ; I->INDIRECT = HEAD
+
+	LOAD32_Absolute32_eax &global_types         ; Using global_types
+	STORE32_EAX_into_EDX                        ; HEAD->NEXT = global_types
+	STORE32_Absolute32_edx &global_types        ; global_types = HEAD
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX %4                              ; Using register size
+	STORE32_EAX_into_EBP_Immediate8 !4          ; I->SIZE = register size
+
+	LOADI32_EAX &create_struct_string_0         ; Using "ERROR in create_struct\n Missing {\n"
+	LOADI32_EBX &open_curly_brace               ; Using "{"
+	CALL32 %require_match                       ; Make sure we have it
+
+	LOADI32_ESI %0                              ; LAST = NULL
+
+:create_struct_iter
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; Make it useful
+	CMPI8_EAX !125                              ; IF global_token->S[0] == "}"
+	JE32 %create_struct_done                    ; be done
+
+	;; Looks like we are adding members
+	;; Lets see if it is a union
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOADI32_EBX &union                          ; Using "union"
+	CALL32 %match                               ; IF match(global_token->s, "union")
+	CMPI8_EAX !0                                ; Deal with union
+	JNE32 %create_struct_single                 ; Otherwise deal with singles
+
+	;; Deal with union
+	COPY_ESI_to_EAX                             ; Put last in right place
+	COPY_ECX_to_EBX                             ; put offset in right place
+	CALL32 %build_union                         ; ASSEMBLE
+	COPY_EAX_to_ESI                             ; last = build_union(last, offset)
+	ADD_edi_into_ecx                            ; offset = offset + member_size
+
+	LOADI32_EAX &create_struct_string_1         ; Using "ERROR in create_struct\n Missing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+	JMP32 %create_struct_iter                   ; keep going
+
+:create_struct_single
+	;; deal with singles
+	COPY_ESI_to_EAX                             ; Put last in right place
+	COPY_ECX_to_EBX                             ; put offset in right place
+	CALL32 %build_member                        ; ASSEMBLE
+	COPY_EAX_to_ESI                             ; last = build_union(last, offset)
+	ADD_edi_into_ecx                            ; offset = offset + member_size
+
+	LOADI32_EAX &create_struct_string_1         ; Using "ERROR in create_struct\n Missing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+	JMP32 %create_struct_iter                   ; keep going
+
+:create_struct_done
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &create_struct_string_1         ; Using "ERROR in create_struct\n Missing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+
+	STORE32_ECX_into_EDX_Immediate8 !4          ; HEAD->SIZE = OFFSET
+	STORE32_ESI_into_EDX_Immedate8 !16          ; HEAD->MEMBERS = LAST
+	STORE32_ESI_into_EBP_Immedate8 !16          ; I->MEMBERS = LAST
+
+	POP_ESI                                     ; Restore ESI
+	POP_EDI                                     ; Restore EDI
+	POP_EBP                                     ; Restore EBP
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:create_struct_string_0  "ERROR in create_struct
+ Missing {
+"
+:create_struct_string_1  "ERROR in create_struct
+ Missing ;
+"
+
+
+;; lookup_member function
+;; Recieves struct type* parent in EAX and char* name in EBX
+;; Returns struct type* I in EAX
+;; Uses char* NAME in EBX, ECX for struct type* I and EDX to hold parent for errors
+;; Aborts hard if not found
+:lookup_member
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	COPY_EAX_to_EDX                             ; Protect Parent
+	LOAD32_ECX_from_EAX_Immediate8 !16          ; struct type* I = parent->MEMBERS
+:lookup_member_iter
+	CMPI8_ECX !0                                ; IF I == NULL
+	JE32 %lookup_member_fail                    ; Abort HARD
+
+	LOAD32_EAX_from_ECX_Immediate8 !24          ; Using I->NAME
+	CALL32 %match                               ; IF I->NAME == NAME
+	CMPI8_EAX !0                                ; Then we have found the member
+	COPY_ECX_to_EAX                             ; Prepare for return
+	LOAD32_ECX_from_ECX_Immediate8 !16          ; Prepare for loop I = I->MEMBERS
+	JNE32 %lookup_member_iter                   ; Looks like we are looping
+
+	;; I is already in EAX
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:lookup_member_fail
+	LOADI32_EAX %2                              ; Using Standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+	LOADI32_EAX &lookup_member_string_0         ; Using "ERROR in lookup_member "
+	CALL32 %File_Print                          ; print it
+
+	LOAD32_EAX_from_EDX_Immediate8 !24          ; PARENT->NAME
+	CALL32 %File_Print                          ; print it
+
+	LOADI32_EAX &arrow_string                   ; Using "->"
+	CALL32 %File_Print                          ; print it
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %File_Print                          ; print it
+
+	LOADI32_EAX &lookup_member_string_1         ; Using " does not exist\n"
+	CALL32 %File_Print                          ; print it
+
+;	CALL32 %line_error                          ; Write useful debug info
+
+	LOADI32_EAX &lookup_member_string_2         ; Using "\n"
+	CALL32 %File_Print                          ; print it
+	JMP32 %Exit_Failure                         ; Abort Hard
+
+:lookup_member_string_0  "ERROR in lookup_member "
+:lookup_member_string_1  " does not exist
+"
+:lookup_member_string_2  "
+"
+
+
+;; build_member function
+;; Recieves struct type* last in EAX, int offset in EBX and global member_size in EDI
+;; Updates member_size in EDI and returns struct type* I in EAX
+;; Uses ECX for struct type* member_type and EDX for struct type* I
+:build_member
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	COPY_EAX_to_EDX                             ; Put last out of the way
+	LOADI32_EAX %28                             ; Allocate type
+	CALL32 %malloc                              ; Get I
+	STORE32_EDX_into_EAX_Immediate8 !16         ; I->MEMBERS = LAST
+	STORE32_EBX_into_EAX_Immediate8 !8          ; I->OFFSET = OFFSET
+	COPY_EAX_to_EDX                             ; Put I in place
+
+	CALL32 %type_name                           ; Get member_type
+	COPY_EAX_to_ECX                             ; Put in place
+	STORE32_ECX_into_EDX_Immediate8 !20         ; I->TYPE = MEMBER_TYPE
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
+	STORE32_EBX_into_EDX_Immediate8 !24         ; I->NAME = global_token->S
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	;; Check if we have an array
+	LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
+	LOADI32_EAX &open_bracket                   ; Using "["
+	CALL32 %match                               ; IF global_token->S == "["
+	CMPI8_EAX !0                                ; Then we have to deal with arrays in our structs
+	JE32 %build_member_array                    ; So deal with that pain
+
+	;; Deal with non-array case
+	LOAD32_EAX_from_ECX_Immediate8 !4           ; member_type->SIZE
+	STORE32_EAX_into_EDX_Immediate8 !4          ; I->SIZE = member_type->SIZE
+	JMP32 %build_member_done                    ; Be done
+
+:build_member_array
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	CALL32 %numerate_string                     ; convert number
+	LOAD32_EBX_from_ECX_Immediate8 !20          ; member_type->TYPE
+	LOAD32_EBX_from_EBX_Immediate8 !4           ; member_type->TYPE->SIZE
+	IMUL_EAX_by_EBX                             ; member_type->type->size * numerate_string(global_token->s)
+	STORE32_EAX_into_EDX_Immediate8 !4          ; I->SIZE = member_type->type->size * numerate_string(global_token->s)
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &build_member_string_0          ; Using "Struct only supports [num] form\n"
+	LOADI32_EBX &close_bracket                  ; Using "]"
+	CALL32 %require_match                       ; Make sure we have it
+
+:build_member_done
+	LOAD32_EDI_from_EDX_Immediate8 !4           ; MEMBER_SIZE = I->SIZE
+	STORE32_ECX_into_EDX_Immediate8 !20         ; I->TYPE = MEMBER_TYPE
+	COPY_EDX_to_EAX                             ; Return I
+
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:build_member_string_0  "Struct only supports [num] form
+"
+
+
+;; build_union function
+;; Recieves struct type* last in EAX, int offset in EBX and global member_size in EDI
+;; Updates member_size in EDI and returns struct type* LAST in EAX
+;; Uses ECX for struct type* last, EDX for int offset, ESI for int size and EDI for int member_size
+:build_union
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	PUSH_ESI                                    ; Protect ESI
+	COPY_EAX_to_ECX                             ; Put LAST in right spot
+	COPY_EBX_to_EDX                             ; Put OFFSET in right spot
+	LOADI32_ESI %0                              ; SIZE = 0
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	LOADI32_EAX &build_union_string_0           ; Using "ERROR in build_union\nMissing {\n"
+	LOADI32_EBX &open_curly_brace               ; Using "{"
+	CALL32 %require_match                       ; Make sure we have it
+
+:build_union_iter
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
+	LOAD8_al_from_EAX                           ; global_token->S[0]
+	MOVZX_al                                    ; make it useful
+	CMPI8_EAX !125                              ; IF global_token->S[0] == "}"
+	JE32 %build_union_done                      ; Be done
+
+	;; Collect union member
+	COPY_ECX_to_EAX                             ; Passing LAST
+	COPY_EDX_to_EBX                             ; Passing offset
+	CALL32 %build_member                        ; build_member(last, offset)
+	COPY_EAX_to_ECX                             ; last = build_member(last, offset)
+
+	CMP_EDI_ESI                                 ; IF member_size > size
+	JG32 %build_union_size                      ; Then update size
+
+	;; deal with member_size > size
+	COPY_EDI_to_ESI                             ; SIZE = MEMBER_SIZE
+
+:build_union_size
+	LOADI32_EAX &build_union_string_1           ; Using "ERROR in build_union\nMissing ;\n"
+	LOADI32_EBX &semicolon                      ; Using ";"
+	CALL32 %require_match                       ; Make sure we have it
+	JMP32 %build_union_iter                     ; Keep going
+
+:build_union_done
+	COPY_ESI_to_EDI                             ; MEMBER_SIZE = SIZE
+
+	LOAD32_Absolute32_eax &global_token         ; Using global_token
+	LOAD32_EAX_from_EAX                         ; global_token->NEXT
+	STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
+
+	COPY_ECX_to_EAX                             ; Return last
+
+	POP_ESI                                     ; Restore ESI
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:build_union_string_0  "ERROR in build_union
+Missing {
+"
+:build_union_string_1  "ERROR in build_union
+Missing ;
+"
+
+
+;; sym_declare function
+;; Recieves char *s in EAX, struct type* t in EBX, and struct token_list* list in ECX
+;; Returns struct token_list* in EAX
+;; Uses EAX for A
+:sym_declare
+	PUSH_EDX                                    ; Protect EDX
+	COPY_EAX_to_EDX                             ; Get char *S safely out of the way
+	LOADI32_EAX %20                             ; Using sizeof(struct token_list)
+	CALL32 %malloc                              ; Get pointer to A
+	STORE32_ECX_into_EAX                        ; A->NEXT = LIST
+	STORE32_EDX_into_EAX_Immediate8 !8          ; A->S = S
+	STORE32_EBX_into_EAX_Immediate8 !12         ; A->TYPE = T
+	POP_EDX                                     ; Restore EDX
+	RETURN
+
+
+;; match function
+;; Recieves CHAR* in EAX and CHAR* in EBX
+;; Returns 0 (TRUE) or 1 (FALSE) in EAX
+:match
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	COPY_EAX_to_ECX                             ; S1 in place
+	COPY_EBX_to_EDX                             ; S2 in place
+:match_Loop
+	LOAD8_al_from_ECX                           ; S1[0]
+	MOVZX_al                                    ; Make it useful
+	LOAD8_bl_from_EDX                           ; S2[0]
+	MOVZX_bl                                    ; Make it useful
+	CMP_EAX_EBX                                 ; See if they match
+	JNE32 %match_False                          ; If not
+
+	ADDI8_ECX !1                                ; S1 = S1 + 1
+	ADDI8_EDX !1                                ; S2 = S2 + 1
+	CMPI8_EAX !0                                ; If reached end of string
+	JE32 %match_Done                            ; Perfect match
+	JMP32 %match_Loop                           ; Otherwise keep looping
+
+:match_False
+	LOADI32_EAX %1                              ; Return false
+:match_Done
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; numerate_number function
+;; Recieves an INT A in EAX
+;; Returns char* result in EAX
+;; Allocates 16 bytes of memory
+;; Behaves badly when given a negative number too large
+;; Uses EAX for temp, EBX for DIVISOR, EDX for mod/0, ESI for result[i] and EBP for A
+:numerate_number
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	PUSH_ESI                                    ; Protect ESI
+	PUSH_EBP                                    ; Protect EBP
+	COPY_EAX_to_EBP                             ; Protect A
+
+	LOADI32_EAX %16                             ; 16bytes
+	CALL32 %malloc                              ; Get our pointer
+	PUSH_EAX                                    ; Protect our pointer
+	COPY_EAX_to_ESI                             ; put pointer in right place
+	LOADI32_EBX %0x3B9ACA00                     ; Set divisor to largest positive number that fits in 32bits
+
+	CMPI8_EBP !0                                ; Deal with 0 case
+	JE32 %numerate_number_ZERO                  ; If it is
+	JG32 %numerate_number_positive              ; If it is positive
+
+	;; Deal with negative case
+	LOADI32_EAX %45                             ; Using "-"
+	STORE8_al_into_Address_ESI                  ; Write it
+	ADDI8_ESI !1                                ; increment
+	IMULI8_EBP !-1                              ; A = A * -1
+
+:numerate_number_positive
+	LOADI32_EDX %0                              ; Set top to 0
+	COPY_EBP_to_EAX                             ; Using A as bottom
+	IDIV_EBX                                    ; edx:eax % ebx -> edx + edx:eax / ebx -> eax [Even if we don't want it]
+	CMPI8_EAX !0                                ; IF 0 == (a / divisor)
+	JNE32 %numerate_number_iter                 ; Clean up those leading Zeros
+
+	LOADI32_EDX %0                              ; Set top to 0
+	COPY_EBX_to_EAX                             ; Using Divisor for bottom
+	LOADI32_EBX %10                             ; Make this shit work because idiv 10 doesn't work
+	IDIV_EBX                                    ; edx:eax % 10 -> edx + edx:eax / 10 -> eax [Even if we don't want it]
+	COPY_EAX_to_EBX                             ; Update divisor
+	JMP32 %numerate_number_positive             ; Keep collecting
+
+:numerate_number_iter
+	CMPI8_EBX !0                                ; IF DIVISOR < 0
+	JLE32 %numerate_number_done                 ; Be done
+
+	LOADI32_EDX %0                              ; Set top to 0
+	COPY_EBP_to_EAX                             ; Using A as bottom
+	IDIV_EBX                                    ; edx:eax % ebx -> edx + edx:eax / ebx -> eax [Even if we don't want it]
+	ADDI8_EAX !48                               ; ((a / divisor) + 48)
+	STORE8_al_into_Address_ESI                  ; Write it
+	COPY_EDX_to_EBP                             ; a = a % divisor
+
+	LOADI32_EDX %0                              ; Set top to 0
+	COPY_EBX_to_EAX                             ; Using Divisor for bottom
+	LOADI32_EBX %10                             ; Make this shit work because idiv 10 doesn't work
+	IDIV_EBX                                    ; edx:eax % 10 -> edx + edx:eax / 10 -> eax [Even if we don't want it]
+	COPY_EAX_to_EBX                             ; Update divisor
+
+	ADDI8_ESI !1                                ; increment
+	JMP32 %numerate_number_iter                 ; Keep going
+
+:numerate_number_done
+	POP_EAX                                     ; Restore our result
+	POP_EBP                                     ; Restore EBP
+	POP_ESI                                     ; Restore ESI
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+:numerate_number_ZERO
+	LOADI32_EAX %48                             ; Using '0'
+	STORE8_al_into_Address_ESI                  ; Write it
+	ADDI8_ESI !1                                ; increment
+	JMP32 %numerate_number_done                 ; Be done
+
+
+;; numerate_string function
+;; Recieves CHAR* in EAX
+;; Returns value of CHAR* in EAX
+;; Uses EAX for VALUE, EBX for S, ECX for CH and ESI for NEGATIVE?
+:numerate_string
+	PUSH_EBX                                    ; Protect EBX
+	PUSH_ECX                                    ; Protect ECX
+	PUSH_EDX                                    ; Protect EDX
+	PUSH_ESI                                    ; Protect ESI
+	COPY_EAX_to_EBX                             ; put S in correct place
+	LOADI32_EAX %0                              ; Initialize to Zero
+:numerate_string_loop
+	LOAD8_cl_from_EBX_Immediate8 !1             ; S[1]
+	MOVZX_cl                                    ; make it useful
+	CMPI8_ECX !120                              ; IF 'x' == S[1]
+	JE32 %numerate_hex                          ; Deal with hex input
+
+	;; Assume decimal input
+	LOADI32_ESI %0                              ; Assume no negation
+	LOAD8_cl_from_EBX                           ; S[0]
+	MOVZX_cl                                    ; make it useful
+	CMPI8_ECX !45                               ; IF '-' == S[0]
+	JNE32 %numerate_decimal                     ; Skip negation
+
+	LOADI32_ESI %1                              ; Set FLAG
+	ADDI8_EBX !1                                ; S = S + 1
+
+:numerate_decimal
+	LOAD8_cl_from_EBX                           ; S[0]
+	MOVZX_cl                                    ; make it useful
+	CMPI8_ECX !0                                ; IF NULL == S[0]
+	JE32 %numerate_decimal_done                 ; We are done
+
+	IMULI8_EAX !10                              ; VALUE = VALUE * 10
+	SUBI8_ECX !48                               ; CH = CH - '0'
+	CMPI8_ECX !9                                ; Check for illegal
+	JG32 %numerate_string_fail                  ; If CH > '9'
+	CMPI8_ECX !0                                ; Check for illegal
+	JL32 %numerate_string_fail                  ; IF CH < 0
+	ADD_ecx_into_eax                            ; VALUE = VALUE + CH
+	ADDI8_EBX !1                                ; S = S + 1
+	JMP32 %numerate_decimal                     ; Keep looping
+
+:numerate_decimal_done
+	CMPI8_ESI !1                                ; Check if need to negate
+	JNE32 %numerate_string_done                 ; Nope
+
+	IMULI8_EAX !-1                              ; VALUE = VALUE * -1
+	JMP32 %numerate_string_done                 ; Done
+
+:numerate_hex
+	ADDI8_EBX !2                                ; S = S + 2
+:numerate_hex_loop
+	LOAD8_cl_from_EBX                           ; S[0]
+	MOVZX_cl                                    ; make it useful
+	CMPI8_ECX !0                                ; IF NULL == S[0]
+	JE32 %numerate_string_done                  ; We are done
+
+	SALI8_EAX !4                                ; VALUE = VALUE << 4
+	SUBI8_ECX !48                               ; CH = CH - '0'
+	CMPI8_ECX !10                               ; IF 10 >= CH
+	JL32 %numerate_hex_digit                    ; NO
+	SUBI8_ECX !7                                ; Push A-F into range
+:numerate_hex_digit
+	CMPI8_ECX !15                               ; Check for illegal
+	JG32 %numerate_string_fail                  ; If CH > 'F'
+	CMPI8_ECX !0                                ; Check for illegal
+	JL32 %numerate_string_fail                  ; IF CH < 0
+	ADD_ecx_into_eax                            ; VALUE = VALUE + CH
+	ADDI8_EBX !1                                ; S = S + 1
+	JMP32 %numerate_hex_loop                    ; Keep looping
+
+:numerate_string_fail
+	LOADI32_EAX %0                              ; return ZERO
+
+:numerate_string_done
+	POP_ESI                                     ; Restore ESI
+	POP_EDX                                     ; Restore EDX
+	POP_ECX                                     ; Restore ECX
+	POP_EBX                                     ; Restore EBX
+	RETURN
+
+
+;; Exit_Failure function
+;; Recieves nothing
+;; And aborts hard
+;; Does NOT return
+:Exit_Failure
+	LOADI32_EBX %1                              ; All is wrong
+	LOADI32_EAX %1                              ; put the exit syscall number in eax
+	INT_80                                      ; Call it a bad day
+
+;; Keywords
+:union  "union"
+:struct  "struct"
+:constant  "CONSTANT"
+:main_string  "main"
+:argc_string  "argc"
+:argv_string  "argv"
+:if_string  "if"
+:else_string  "else"
+:do_string  "do"
+:while_string  "while"
+:for_string  "for"
+:asm_string  "asm"
+:goto_string  "goto"
+:return_string  "return"
+:break_string  "break"
+:continue_string  "continue"
+:sizeof_string  "sizeof"
+:plus_string  "+"
+:minus_string  "-"
+:multiply_string  "*"
+:divide_string  "/"
+:modulus_string  "%"
+:left_shift_string  "<<"
+:right_shift_string  ">>"
+:less_than_string  "<"
+:less_than_equal_string  "<="
+:greater_than_equal_string  ">="
+:greater_than_string  ">"
+:equal_to_string  "=="
+:not_equal_string  "!="
+:bitwise_and  "&"
+:logical_and  "&&"
+:bitwise_or  "|"
+:logical_or  "||"
+:bitwise_xor  "^"
+:arrow_string  "->"
+
+
+;; Frequently Used strings
+;; Generally used by require_match
+:open_curly_brace  "{"
+:close_curly_brace  "}"
+:open_paren  "("
+:close_paren  ")"
+:open_bracket  "["
+:close_bracket  "]"
+:comma  ","
+:semicolon  ";"
+:equal  "="
+:percent  "%"
+:newline  "\n"
+:underline  "_"
+
+
+:prim_types
+:type_void
+	&type_int                                   ; NEXT
+	%4                                          ; SIZE
+	%0                                          ; OFFSET
+	&type_void                                  ; INDIRECT
+	%0                                          ; MEMBERS
+	&type_void                                  ; TYPE
+	&type_void_name                             ; NAME
+:type_void_name  "void"
+
+:type_int
+	&type_char                                  ; NEXT
+	%4                                          ; SIZE
+	%0                                          ; OFFSET
+	&type_int                                   ; INDIRECT
+	%0                                          ; MEMBERS
+	&type_int                                   ; TYPE
+	&type_int_name                              ; NAME
+:type_int_name  "int"
+
+:type_char
+	&type_file                                  ; NEXT
+	%1                                          ; SIZE
+	%0                                          ; OFFSET
+	&type_char_indirect                         ; INDIRECT
+	%0                                          ; MEMBERS
+	&type_char                                  ; TYPE
+	&type_char_name                             ; NAME
+:type_char_name  "char"
+
+:type_char_indirect
+	&type_file                                  ; NEXT
+	%4                                          ; SIZE
+	%0                                          ; OFFSET
+	&type_char_double_indirect                  ; INDIRECT
+	%0                                          ; MEMBERS
+	&type_char_indirect                         ; TYPE
+	&type_char_indirect_name                    ; NAME
+:type_char_indirect_name  "char*"
+
+:type_char_double_indirect
+	&type_file                                  ; NEXT
+	%4                                          ; SIZE
+	%0                                          ; OFFSET
+	&type_char_double_indirect                  ; INDIRECT
+	%0                                          ; MEMBERS
+	&type_char_indirect                         ; TYPE
+	&type_char_double_indirect_name             ; NAME
+:type_char_double_indirect_name  "char**"
+
+:type_file
+	&type_function                              ; NEXT
+	%4                                          ; SIZE
+	%0                                          ; OFFSET
+	&type_file                                  ; INDIRECT
+	%0                                          ; MEMBERS
+	&type_file                                  ; TYPE
+	&type_file_name                             ; NAME
+:type_file_name  "FILE"
+
+:type_function
+	&type_unsigned                              ; NEXT
+	%4                                          ; SIZE
+	%0                                          ; OFFSET
+	&type_function                              ; INDIRECT
+	%0                                          ; MEMBERS
+	&type_function                              ; TYPE
+	&type_function_name                         ; NAME
+:type_function_name  "FUNCTION"
+
+:type_unsigned
+	%0                                          ; NEXT
+	%4                                          ; SIZE
+	%0                                          ; OFFSET
+	&type_unsigned                              ; INDIRECT
+	%0                                          ; MEMBERS
+	&type_unsigned                              ; TYPE
+	&type_unsigned_name                         ; NAME
+:type_unsigned_name  "unsigned"
+
+
+;; debug_list function
+;; Recieves struct token_list* in EAX
+;; Prints contents of list and exits
+;; Does NOT return
+:debug_list
+	COPY_EAX_to_EBP                             ; Protect the list pointer
+	LOADI32_EAX %2                              ; Using Standard error
+	STORE32_Absolute32_eax &Output_file         ; write to standard error
+
+:debug_list_iter
+	;; Header
+	LOADI32_EAX &debug_list_string0             ; Using our first string
+	CALL32 %File_Print                          ; Print it
+	COPY_EBP_to_EAX                             ; Use address of pointer
+	CALL32 %numerate_number                     ; Convert it into string
+	CALL32 %File_Print                          ; Print it
+
+	;; NEXT
+	LOADI32_EAX &debug_list_string1             ; Using our second string
+	CALL32 %File_Print                          ; Print it
+	LOAD32_EAX_from_EBP_Immediate8 !0           ; Use address of pointer
+	CALL32 %numerate_number                     ; Convert it into string
+	CALL32 %File_Print                          ; Print it
+
+	;; PREV
+	LOADI32_EAX &debug_list_string2             ; Using our third string
+	CALL32 %File_Print                          ; Print it
+	LOAD32_EAX_from_EBP_Immediate8 !4           ; Use address of pointer
+	CALL32 %numerate_number                     ; Convert it into string
+	CALL32 %File_Print                          ; Print it
+
+	;; S
+	LOADI32_EAX &debug_list_string3             ; Using our fourth string
+	CALL32 %File_Print                          ; Print it
+	LOAD32_EAX_from_EBP_Immediate8 !8           ; Use address of pointer
+	CALL32 %numerate_number                     ; Convert it into string
+	CALL32 %File_Print                          ; Print it
+
+	;; S Contents
+	LOADI32_EAX &debug_list_string4             ; Using our fifth string
+	CALL32 %File_Print                          ; Print it
+	LOAD32_EAX_from_EBP_Immediate8 !8           ; Use address of string
+	CMPI8_EAX !0                                ; IF NULL Pointer
+	JNE32 %debug_list_null                      ; otherwise display
+	LOADI32_EAX &debug_list_string_null         ; Give meaningful message instead
+:debug_list_null
+	CALL32 %File_Print                          ; Print it
+
+	;; TYPE
+	LOADI32_EAX &debug_list_string5             ; Using our sixth string
+	CALL32 %File_Print                          ; Print it
+	LOAD32_EAX_from_EBP_Immediate8 !12          ; Use address of pointer
+	CALL32 %numerate_number                     ; Convert it into string
+	CALL32 %File_Print                          ; Print it
+
+	;; ARGS/DEPTH
+	LOADI32_EAX &debug_list_string6             ; Using our third string
+	CALL32 %File_Print                          ; Print it
+	LOAD32_EAX_from_EBP_Immediate8 !16          ; Use address of pointer
+	CALL32 %numerate_number                     ; Convert it into string
+	CALL32 %File_Print                          ; Print it
+
+	LOADI32_EAX %10                             ; Add "\n"
+	CALL32 %fputc                               ; print it
+	CALL32 %fputc                               ; print it
+
+	LOAD32_EBP_from_EBP                         ; TOKEN = TOKEN->NEXT
+	CMPI8_EBP !0                                ; Check if NULL
+	JNE32 %debug_list_iter                      ; iterate otherwise
+
+	LOADI32_EBX %666                            ; All is HELL
+	LOADI32_EAX %1                              ; put the exit syscall number in eax
+	INT_80                                      ; Call it a bad day
+
+:debug_list_string0  "Token_list node at address: "
+:debug_list_string1  "
+NEXT address: "
+:debug_list_string2  "
+PREV address: "
+:debug_list_string3  "
+S address: "
+:debug_list_string4  "
+The contents of S are: "
+:debug_list_string5  "
+TYPE address: "
+:debug_list_string6  "
+ARGUMENTS address: "
+:debug_list_string_null  ">::<NULL>::<"
+
+
+:Address_of
+	NULL
+:C
+	NULL
+:Input_file
+	NULL
+:MALLOC
+	NULL
+:Output_file
+	NULL
+:Token
+	NULL
+:break_frame
+	NULL
+:break_target_func
+	NULL
+:break_target_head
+	NULL
+:break_target_num
+	NULL
+:current_count
+	NULL
+:current_target
+	NULL
+:function
+	NULL
+:global_constant_list
+	NULL
+:global_function_list
+	NULL
+:global_symbol_list
+	NULL
+:global_token
+	NULL
+:global_types
+	&prim_types
+:globals_list
+	NULL
+:output_list
+	NULL
+:string_index
+	NULL
+:strings_list
+	NULL
+
+:ELF_end