Browse Source

wrote cc_knight-posix.s

Jeremiah Orians 4 years ago
parent
commit
e9dd488526
1 changed files with 4445 additions and 0 deletions
  1. 4445 0
      stage2/cc_knight-posix.s

+ 4445 - 0
stage2/cc_knight-posix.s

@@ -0,0 +1,4445 @@
+; Copyright (C) 2016 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/>.
+
+;; A Minimal C Compiler
+;; type Cells are in the following form:
+;; NEXT (0), SIZE (4), OFFSET (8), INDIRECT (12), MEMBERS (16), TYPE (20), NAME (24)
+;; token_list Cells are in the following form:
+;; NEXT (0), LOCALS/PREV (4), S (8), TYPE/FILENAME (12), ARGUMENTS/DEPTH/LINENUMBER (16)
+;; Each being the length of a register [32bits]
+;;
+
+;; STACK space: End of program -> 512KB (0x80000) [Could be reduced]
+;; HEAP space: 512KB -> End of Memory
+
+;; R15 is the STACK pointer
+;; R14 is the HEAP pointer
+
+:start
+	;; Prep TAPE_02
+	LOADUI R0 0x1101
+	FOPEN_WRITE
+
+	;; Prep TAPE_01
+	LOADUI R0 0x1100
+	FOPEN_READ
+
+:main
+	LOADUI R0 0x1100            ; Pass Tape_01 for reading
+	LOADR32 R14 @HEAP           ; Setup Initial HEAP
+	LOADUI R15 $STACK           ; Setup Initial STACK
+	CALLI R15 @read_all_tokens  ; Read all Tokens in Tape_01
+	CALLI R15 @reverse_list     ; Fix Token Order
+;	CALLI R15 @debug_list       ; Lets try to debug token errors
+	MOVE R13 R0                 ; Set global_token for future reading
+	FALSE R12                   ; Set struct token_list* out to NULL
+	FALSE R11                   ; Set struct token_list* list_strings to NULL
+	FALSE R10                   ; Set struct token_list* globals_list to NULL
+	CALLI R15 @program          ; Build our output
+	LOADUI R0 $header_string1   ; Using our first header string
+	LOADUI R1 0x1101            ; Using Tape_02
+	CALLI R15 @file_print       ; Write string
+	MOVE R0 R12                 ; using Contents of output_list
+	CALLI R15 @recursive_output ; Recursively write
+	LOADUI R0 $header_string2   ; Using our second header string
+	CALLI R15 @file_print       ; Write string
+	MOVE R0 R10                 ; using Contents of globals_list
+	CALLI R15 @recursive_output ; Recursively write
+	LOADUI R0 $header_string3   ; Using our third header string
+	CALLI R15 @file_print       ; Write string
+	MOVE R0 R11                 ; using Contents of strings_list
+	CALLI R15 @recursive_output ; Recursively write
+	LOADUI R0 $header_string4   ; Using our final header string
+	CALLI R15 @file_print       ; Write string
+	HALT                        ; We have completed compiling our input
+
+;; Symbol lists
+:global_constant_list
+	NOP
+:global_symbol_list
+	NOP
+:global_function_list
+	NOP
+
+;; Pointer to initial HEAP ADDRESS
+:HEAP
+	'00080000'
+
+;; Output strings
+:header_string1
+	"
+# Core program
+"
+:header_string2
+	"
+# Program global variables
+"
+
+:header_string3
+	"
+# Program strings
+"
+
+:header_string4
+	"
+:ELF_end
+"
+
+;; clearWhiteSpace function
+;; Receives a character in R0 and FILE* in R1 and line_num in R11
+;; Returns first non-whitespace character in R0
+:clearWhiteSpace
+	CMPSKIPI.NE R0 32           ; Check for a Space
+	JUMP @clearWhiteSpace_reset ; Looks like we need to remove a space
+
+	CMPSKIPI.NE R0 9            ; Check for a tab
+	JUMP @clearWhiteSpace_reset ; Looks like we need to remove a tab
+
+	CMPSKIPI.E R0 10            ; Check for a newline
+	RET R15                     ; Looks we found a non-whitespace
+
+	ADDUI R11 R11 1             ; Increment line number
+	;; Fall through to iterate to next char
+
+:clearWhiteSpace_reset
+	FGETC                       ; Get next char
+	JUMP @clearWhiteSpace       ; Iterate
+
+
+;; consume_byte function
+;; Receives a char in R0, FILE* in R1 and index in R13
+;; Returns next char in R0
+:consume_byte
+	STOREX8 R0 R14 R13          ; Put char onto HEAP
+	ADDUI R13 R13 1             ; Increment index
+	FGETC                       ; Get next char
+	RET R15
+
+
+;; consume_word function
+;; Receives a char in R0, FILE* in R1, FREQUENT in R2 and index in R13
+;; Returns next char in R0
+:consume_word
+	PUSHR R3 R15                ; Protect R3
+	FALSE R3                    ; ESCAPE is FALSE
+:consume_word_reset
+	JUMP.NZ R3 @consume_word_iter1
+	CMPSKIPI.NE R0 92           ; If \
+	TRUE R3                     ; Looks like we are in an escape
+	JUMP @consume_word_iter2
+:consume_word_iter1
+	FALSE R3                    ; Looks like we are no longer in an escape
+:consume_word_iter2
+	CALLI R15 @consume_byte     ; Store the char
+	JUMP.NZ R3 @consume_word_reset        ; If escape loop
+	CMPJUMPI.NE R0 R2 @consume_word_reset ; if not matching frequent loop
+	FGETC                       ; Get a new char to return
+	POPR R3 R15                 ; Restore R3
+	RET R15
+
+
+;; fixup_label function
+;; Receives nothing (But uses R14 as HEAP pointer)
+;; Returns 32 in R0 and no other registers altered
+:fixup_label
+	PUSHR R1 R15                ; Protect R1 from change
+	PUSHR R2 R15                ; Protect R2 from change
+	LOADUI R0 58                ; Set HOLD to :
+	FALSE R2                    ; Set I to 0
+:fixup_label_reset
+	MOVE R1 R0                  ; Set PREV = HOLD
+	LOADXU8 R0 R14 R2           ; Read hold_string[I] into HOLD
+	STOREX8 R1 R14 R2           ; Set hold_string[I] = PREV
+	ADDUI R2 R2 1               ; increment I
+	JUMP.NZ R0 @fixup_label_reset ; Loop until we hit a NULL
+
+	;; clean up
+	ADDUI R2 R2 1               ; increment I
+	LOADUI R0 32                ; Put 32 in R0
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; in_set2 function
+;; Receives a Char in R0, FILE* in R1, char* in R2 and index in R13
+;; Return result in R2
+:in_set2
+	PUSHR R3 R15                ; Protect R3 from changes
+:in_set2_reset
+	LOADU8 R3 R2 0              ; Get char from list
+	JUMP.Z R3 @in_set2_fail     ; Stop when 0 == s[0]
+	CMPJUMPI.E R0 R3 @in_set2_done ; We found a match
+	ADDUI R2 R2 1               ; Increment to next char
+	JUMP.NZ R3 @in_set2_reset   ; Iterate if not NULL
+
+:in_set2_fail
+	;; Looks like not found
+	FALSE R2                    ; Return FALSE
+
+:in_set2_done
+	CMPSKIPI.E R2 0             ; Provided not FALSE
+	TRUE R2                     ; The result is true
+	POPR R3 R15                 ; Restore R3
+	RET R15
+
+
+;; in_set function
+;; Receives a Char in R0, char* in R1
+;; Return result in R0
+:in_set
+	PUSHR R2 R15                ; Protect R3 from changes
+:in_set_reset
+	LOADU8 R2 R1 0              ; Get char from list
+	JUMP.Z R2 @in_set_fail      ; Stop when 0 == s[0]
+	CMPJUMPI.E R0 R2 @in_set_done ; We found a match
+	ADDUI R1 R1 1               ; Increment to next char
+	JUMP.NZ R2 @in_set_reset    ; Iterate if not NULL
+
+:in_set_fail
+	;; Looks like not found
+	FALSE R1                    ; Return FALSE
+
+:in_set_done
+	CMPSKIPI.E R1 0             ; Provided not FALSE
+	TRUE R2                     ; The result is true
+	MOVE R0 R2                  ; Put result in correct place
+	POPR R2 R15                 ; Restore R3
+	RET R15
+
+;; Common in_set strings of interest
+;; As Raw strings (") is forbidden and ' has some restrictions
+:nice_chars
+	"	
+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
+:keyword_chars
+	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
+:variable_chars
+	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
+:symbol_chars
+	"<=>|&!-"
+:hex_chars
+	"0123456789ABCDEF"
+:digit_chars
+	"0123456789"
+:whitespace_chars
+	" 	
+"
+
+;; preserve_keyword function
+;; Receives a Char in R0, FILE* in R1 and index in R13
+;; Overwrites R2
+;; Returns next CHAR
+:preserve_keyword
+	LOADUI R2 $keyword_chars    ; Using keyword list of chars
+	CALLI R15 @in_set2          ; Check if in list
+	JUMP.Z R2 @preserve_keyword_label ; if not in set, stop iterating
+
+:preserve_keyword_reset
+	CALLI R15 @consume_byte     ; Consume another byte
+	JUMP @preserve_keyword      ; Iterate
+
+:preserve_keyword_label
+	CMPSKIPI.NE R0 58           ; Check for label (:)
+	CALLI R15 @fixup_label      ; Looks like we found one
+	RET R15
+
+
+;; preserve_symbol function
+;; Receives a Char in R0, FILE* in R1 and index in R13
+;; Overwrites R2
+;; Returns next CHAR
+:preserve_symbol
+	LOADUI R2 $symbol_chars     ; Using symbol list of chars
+	CALLI R15 @in_set2          ; Check if in list
+	JUMP.NZ R2 @preserve_symbol_reset
+
+	;; Looks we didn't find anything we wanted to preserve
+	RET R15
+
+:preserve_symbol_reset
+	CALLI R15 @consume_byte     ; Consume another byte
+	JUMP @preserve_symbol       ; Iterate
+
+
+;; purge_macro function
+;; Receives a Char in R0, FILE* in R1 and index in R13
+;; Returns next CHAR via jumping to get_token_reset
+:purge_macro
+	CMPSKIPI.NE R0 10           ; Check for Line Feed
+	JUMP @get_token_reset       ; Looks like we found it, call it done
+
+	FGETC                       ; Looks like we need another CHAR
+	JUMP @purge_macro           ; Keep looping
+
+
+;; get_token function
+;; Receives a Char in R0, FILE* in R1, line_num in R11 and TOKEN in R10
+;; sets index in R13 and current in R12
+;; Overwrites R2
+;; Returns next CHAR
+:get_token
+	PUSHR R12 R15               ; Preserve R12
+	PUSHR R13 R15               ; Preserve R13
+	COPY R12 R14                ; Save CURRENT's Address
+	ADDUI R14 R14 20            ; Update Malloc to free space for string
+:get_token_reset
+	FALSE R13                   ; Reset string_index to 0
+	CALLI R15 @clearWhiteSpace  ; Clear any leading whitespace
+	CMPSKIPI.NE R0 35           ; Deal with # line macros
+	JUMP @purge_macro           ; Returns at get_token_reset
+
+	;; Check for keywords
+	LOADUI R2 $keyword_chars    ; Using keyword list
+	CALLI R15 @in_set2          ; Check if keyword
+	JUMP.Z R2 @get_token_symbol ; if not a keyword
+	CALLI R15 @preserve_keyword ; Yep its a keyword
+	JUMP @get_token_done        ; Be done with token
+
+	;; Check for symbols
+:get_token_symbol
+	LOADUI R2 $symbol_chars     ; Using symbol list
+	CALLI R15 @in_set2          ; Check if symbol
+	JUMP.Z R2 @get_token_char   ; If not a symbol
+	CALLI R15 @preserve_symbol  ; Yep its a symbol
+	JUMP @get_token_done        ; Be done with token
+
+	;; Check for char
+:get_token_char
+	CMPSKIPI.E R0 39            ; Check if '
+	JUMP @get_token_string      ; Not a '
+	COPY R2 R0                  ; Prepare for consume_word
+	CALLI R15 @consume_word     ; Call it
+	JUMP @get_token_done        ; Be done with token
+
+	;; Check for string
+:get_token_string
+	CMPSKIPI.E R0 34            ; Check if "
+	JUMP @get_token_EOF         ; Not a "
+	COPY R2 R0                  ; Prepare for consume_word
+	CALLI R15 @consume_word     ; Call it
+	JUMP @get_token_done        ; Be done with token
+
+	;; Check for EOF
+:get_token_EOF
+	CMPSKIPI.L R0 0             ; If c < 0
+	JUMP @get_token_comment     ; If not EOF
+	POPR R13 R15                ; Restore R13
+	POPR R12 R15                ; Restore R12
+	RET R15                     ; Otherwise just return the EOF
+
+	;; Check for C comments
+:get_token_comment
+	CMPSKIPI.E R0 47            ; Deal with non-comments
+	JUMP @get_token_else        ; immediately
+
+	CALLI R15 @consume_byte     ; Deal with another byte
+	CMPSKIPI.NE R0 42           ; if * make it a block comment
+	JUMP @get_token_comment_block ; and purge it all
+
+	CMPSKIPI.E R0 47            ; Check if not //
+	JUMP @get_token_done        ; Finish off the token
+
+	;; Looks like it was //
+	FGETC                       ; Get next char
+	JUMP @get_token_reset       ; Try again
+
+	;; Deal with the mess that is C block comments
+:get_token_comment_block
+	FGETC                       ; Get next char
+:get_token_comment_block_outer
+	CMPSKIPI.NE R0 47           ; Check for closing /
+	JUMP @get_token_comment_block_outer_done ; Yep has closing /
+:get_token_comment_block_inner
+	CMPSKIPI.NE R0 42           ; Check for preclosing *
+	JUMP @get_token_comment_block_inner_done ; Yep has *
+
+	;; Otherwise we are just consuming
+	FGETC                       ; Remove another CHAR
+	CMPSKIPI.NE R0 10           ; Check for Line Feed
+	ADDUI R11 R11 1             ; Found one, updating line number
+	JUMP @get_token_comment_block_inner
+
+:get_token_comment_block_inner_done
+	FGETC                       ; Remove another CHAR
+	CMPSKIPI.NE R0 10           ; Check for Line Feed
+	ADDUI R11 R11 1             ; Found one, updating line number
+	JUMP @get_token_comment_block_outer
+
+:get_token_comment_block_outer_done
+	FGETC                       ; Remove another CHAR
+	JUMP @get_token_reset       ; And Try again
+
+	;; Deal with default case
+:get_token_else
+	CALLI R15 @consume_byte     ; Consume the byte and be done
+
+:get_token_done
+	ADDUI R13 R13 2             ; Pad with NULL the string
+	STORE32 R14 R12 8           ; Set CURRENT->S to String
+	ADD R14 R14 R13             ; Add string length to HEAP
+
+	STORE32 R10 R12 0           ; CURRENT->NEXT = TOKEN
+	STORE32 R10 R12 4           ; CURRENT->PREV = TOKE
+	STORE32 R11 R12 16          ; CURRENT->LINENUM = LINE_NUM
+	MOVE R10 R12                ; SET TOKEN to CURRENT
+	POPR R13 R15                ; Restore R13
+	POPR R12 R15                ; Restore R12
+	RET R15
+
+
+;; reverse_list function
+;; Receives a Token_list in R0
+;; Returns List in Reverse order in R0
+:reverse_list
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	FALSE R1                    ; Set ROOT to NULL
+	CMPJUMPI.E R0 R1 @reverse_list_done ; ABORT if given a NULL
+:reverse_list_reset
+	LOAD32 R2 R0 0              ; SET next to HEAD->NEXT
+	STORE32 R1 R0 0             ; SET HEAD->NEXT to ROOT
+	MOVE R1 R0                  ; SET ROOT to HEAD
+	MOVE R0 R2                  ; SET HEAD to NEXT
+	JUMP.NZ R0 @reverse_list_reset ; Iterate if HEAD not NULL
+
+:reverse_list_done
+	MOVE R0 R1                  ; SET Result to ROOT
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; read_all_tokens function
+;; Receives a FILE* in R0
+;; sets line_num in R11 and TOKEN in R10
+;; Overwrites R2
+;; Returns struct token_list* in R0
+:read_all_tokens
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R10 R15               ; Protect R10
+	PUSHR R11 R15               ; Protect R11
+	MOVE R1 R0                  ; Set R1 as FILE*
+	FGETC                       ; Read our first CHAR
+	LOADUI R11 1                ; Start line_num at 1
+	FALSE R10                   ; First token is NULL
+:read_all_tokens_reset
+	JUMP.NP R0 @read_all_tokens_done
+	CALLI R15 @get_token
+	JUMP @read_all_tokens_reset
+:read_all_tokens_done
+	MOVE R0 R10                 ; Return the Token
+	POPR R11 R15                ; Restore R11
+	POPR R10 R15                ; Restore R10
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; parse_string function
+;; Receives char* string in R0
+;; R14 is HEAP Pointer
+;; Returns char* in R0
+:parse_string
+	PUSHR R1 R15                ; Protect R1
+	COPY R1 R0                  ; Make a copy of STRING
+	CALLI R15 @weird            ; Check if string is weird
+	SWAP R0 R1
+	JUMP.Z R1 @parse_string_regular ; Deal with regular strings
+
+	;; Looks like we have a weirdo
+	CALLI R15 @collect_weird_string ; Create our weird string
+	JUMP @parse_string_done     ; Simply return what was created
+:parse_string_regular
+	CALLI R15 @collect_regular_string
+:parse_string_done
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; weird function
+;; Analyze string to determine if it's output would be weird for mescc-tools
+;; Receives char* in R0
+;; Returns BOOL in R0
+:weird
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+	FALSE R2                    ; Assume FALSE
+	ADDUI R3 R0 1               ; STRING = STRING + 1
+:weird_iter
+	JUMP.NZ R2 @weird_done      ; Stop if TRUE
+	LOADU8 R4 R3 0              ; C = STRING[0]
+	JUMP.Z R4 @weird_done       ; Be done at NULL Termination
+	CMPSKIPI.E R4 92            ; If not '\\'
+	JUMP @weird_post_escape     ; Looks like no escape analysis
+
+	;; Deal with the mess
+	COPY R0 R3                  ; Using STRING
+	CALLI R15 @escape_lookup    ; Get our CHAR
+	MOVE R4 R0                  ; C = ESCAPE_LOOKUP(STRING)
+	LOADU8 R0 R3 1              ; STRING[1]
+	CMPSKIPI.NE R0 120          ; if 'x' == STRING[1]
+	ADDUI R3 R3 2               ; STRING = STRING + 2
+	ADDUI R3 R3 1               ; STRING = STRING + 1
+
+:weird_post_escape
+	LOADUI R1 $nice_chars       ; using list of nice CHARS
+	COPY R0 R4                  ; using copy of C
+	CALLI R15 @in_set           ; Use in_set
+	CMPSKIPI.NE R0 0            ; IF TRUE
+	TRUE R2                     ; Return TRUE
+
+	ADDUI R3 R3 1               ; STRING = STRING + 1
+	LOADUI R1 $whitespace_chars ; Check Whitespace Chars
+	COPY R0 R4                  ; Using copy of C
+	CALLI R15 @in_set           ; Use in_set
+	JUMP.Z R0 @weird_iter       ; If False simply loop
+	LOADU8 R0 R3 0              ; STRING[1]
+	CMPSKIPI.NE R0 58           ; If ':' == STRING[1]
+	TRUE R2                     ; Flip flag
+	JUMP @weird_iter            ; Keep trying to find an answer
+
+:weird_done
+	MOVE R0 R2                  ; Whatever is in R2 is the answer
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; collect_weird_string function
+;; Converts weird string into a form mescc-tools can handle cleanly
+;; Receives char* in R0
+;; R14 is HEAP Pointer and $hex_chars as the table
+;; Returns char* in R0
+:collect_weird_string
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+	LOADUI R4 $hex_chars        ; Pointer to TABLE
+	COPY R3 R14                 ; Get HOLD
+	MOVE R2 R0                  ; Put STRING in Place
+	LOADUI R0 39                ; Prefix with '
+	PUSH8 R0 R3                 ; HOLD[0] = '\'' && HOLD = HOLD + 1
+:collect_weird_string_iter
+	ADDUI R2 R2 1               ; STRING = STRING + 1
+	LOADUI R0 32                ; Insert ' '
+	PUSH8 R0 R3                 ; HOLD[0] = ' ' && HOLD = HOLD + 1
+	COPY R0 R2                  ; copy STRING
+	CALLI R15 @escape_lookup    ; Get char value
+	ANDI R1 R0 0x0F             ; Save Bottom out of the way
+	SR0I R0 4                   ; Isolate Top
+	LOADXU8 R0 R4 R0            ; Using Table
+	LOADXU8 R1 R4 R1            ; Using Table
+	PUSH8 R0 R3                 ; HOLD[0] = TABLE[(TEMP >> 4)] && HOLD = HOLD + 1
+	PUSH8 R1 R3                 ; HOLD[0] = TABLE[(TEMP & 15)] && HOLD = HOLD + 1
+	LOADU8 R0 R2 0              ; STRING[0]
+	JUMP.Z R0 @collect_weird_string_done ; Stop if NULL
+	CMPSKIPI.E R0 92            ; IF STRING[0] != '\\'
+	JUMP @collect_weird_string_check ; Deal with iteration
+	LOADU8 R0 R2 1              ; STRING[1]
+	CMPSKIPI.NE R0 120          ; If STRING[1] == 'x'
+	ADDUI R2 R2 2               ; STRING = STRING + 2
+	ADDUI R2 R2 1               ; STRING = STRING + 1
+:collect_weird_string_check
+	LOADU8 R0 R2 1              ; STRING[1]
+	JUMP.NZ R0 @collect_weird_string_iter
+
+:collect_weird_string_done
+	LOADUI R0 32                ; Insert ' '
+	PUSH8 R0 R3                 ; HOLD[0] = ' ' && HOLD = HOLD + 1
+	LOADUI R0 48                ; Insert '0'
+	PUSH8 R0 R3                 ; HOLD[0] = '0' && HOLD = HOLD + 1
+	PUSH8 R0 R3                 ; HOLD[0] = '0' && HOLD = HOLD + 1
+	LOADUI R0 39                ; Insert '\''
+	PUSH8 R0 R3                 ; HOLD[0] = '\'' && HOLD = HOLD + 1
+	LOADUI R0 10                ; Insert '\n'
+	PUSH8 R0 R3                 ; HOLD[0] = '\n' && HOLD = HOLD + 1
+	ADDUI R3 R3 1               ; NULL Terminate
+	SWAP R3 R14                 ; CALLOC HOLD
+	MOVE R0 R3                  ; Return HOLD
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; hex function
+;; Receives Char in R0
+;; Return Int in R0
+:hex
+	SUBUI R0 R0 48              ; First shift
+	CMPSKIPI.GE R0 10           ; If 0-9
+	RET R15                     ; Be done
+
+	;; Deal with A-F
+	ANDI R0 R0 0xDF             ; Unset high bit
+	SUBUI R0 R0 7               ; Shift them down
+	CMPSKIPI.GE R0 10           ; if between 9 and A
+	JUMP @hex_error             ; Throw an error
+	CMPSKIPI.L R0 16            ; if > F
+	JUMP @hex_error             ; Throw an error
+	RET R15
+
+:hex_error
+	LOADUI R0 $hex_error_message ; Our message
+	FALSE R1                    ; For human
+	CALLI R15 @file_print       ; write it
+	CALLI R15 @line_error       ; More info
+	HALT
+
+:hex_error_message
+	"Tried to print non-hex number
+"
+
+
+;; escape_lookup function
+;; Receives char* in R0
+;; Returns char in R0
+:escape_lookup
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	MOVE R1 R0                  ; Put C in the right spot
+	FALSE R2                    ; Our flag for done
+	LOADU8 R0 R1 0              ; c[0]
+	CMPSKIPI.E R0 92            ; If C[0] != '\\'
+	JUMP @escape_lookup_none    ; Deal with none case
+
+	LOADU8 R0 R1 1              ; c[1]
+	CMPSKIPI.NE R0 120          ; if \x??
+	JUMP @escape_lookup_hex
+
+	;; Deal with \? escapes
+	CMPSKIPI.NE R0 110          ; If \n
+	LOADUI R2 10                ; return \n
+
+	CMPSKIPI.NE R0 116          ; If \t
+	LOADUI R2 9                 ; return \t
+
+	CMPSKIPI.NE R0 92           ; If \\
+	LOADUI R2 92                ; return \\
+
+	CMPSKIPI.NE R0 39           ; If \'
+	LOADUI R2 39                ; return \'
+
+	CMPSKIPI.NE R0 34           ; If \"
+	LOADUI R2 34                ; return \"
+
+	CMPSKIPI.NE R0 114          ; If \r
+	LOADUI R2 13                ; return \r
+
+	JUMP.Z R2 @escape_lookup_error ; Looks like we got something weird
+	JUMP @escape_lookup_done    ; Otherwise just use our R2
+
+:escape_lookup_none
+	MOVE R2 R0                  ; We just return the char at C[0]
+	JUMP @escape_lookup_done    ; Be done
+
+:escape_lookup_hex
+	LOADU8 R0 R1 2              ; c[2]
+	CALLI R15 @hex              ; Get first char
+	SL0I R0 4                   ; Shift our first nybble
+	MOVE R2 R0                  ; Protect our top nybble
+	LOADU8 R0 R1 3              ; c[3]
+	CALLI R15 @hex              ; Get second char
+	ADD R2 R2 R0                ; \x?? => ? << 4 + ?
+
+:escape_lookup_done
+	MOVE R0 R2                  ; R2 has our answer
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+:escape_lookup_error
+	MOVE R2 R0                  ; Protect Char that failed
+	LOADUI R0 $escape_lookup_string0 ; Load message
+	FALSE R1                    ; We want the User to see
+	CALLI R15 @file_print       ; Write it
+	MOVE R0 R2                  ; Our CHAR
+	FPUTC                       ; Write it
+	LOADUI R0 10                ; '\n'
+	FPUTC                       ; Write it
+	CALLI R15 @line_error       ; Provide some debug information
+	HALT
+
+:escape_lookup_string0
+	"Received invalid escape \\"
+
+
+;; collect_regular_string function
+;; Converts C string into a RAW string for mescc-tools
+;; Receives char* in R0
+;; R14 is HEAP Pointer
+;; Returns char* in R0
+:collect_regular_string
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	COPY R2 R14                 ; MESSAGE
+	MOVE R1 R0                  ; Put STRING in the right place
+:collect_regular_string_iter
+	LOADU8 R0 R1 0              ; STRING[0]
+	JUMP.Z R0 @collect_regular_string_done ; End at NULL
+	CMPSKIPI.NE R0 92           ; if STRING[0] == '\\'
+	JUMP @collect_regular_string_escape ; deal with escapes
+
+	;; Deal with vannilla chars
+	STORE8 R0 R2 0              ; MESSAGE[0] = STRING[0]
+	ADDUI R2 R2 1               ; MESSAGE = MESSAGE + 1
+	ADDUI R1 R1 1               ; STRING = STRING + 1
+	JUMP @collect_regular_string_iter ; Loop
+
+:collect_regular_string_escape
+	COPY R0 R1                  ; Prepare for call
+	CALLI R15 @escape_lookup    ; Get what weird char we need
+	STORE8 R0 R2 0              ; MESSAGE[0] = escape_lookup(string)
+	ADDUI R2 R2 1               ; MESSAGE = MESSAGE + 1
+	LOADU8 R0 R1 1              ; STRING[1]
+	CMPSKIPI.NE R0 120          ; if \x??
+	ADDUI R1 R1 2               ; STRING = STRING + 2
+	ADDUI R1 R1 2               ; STRING = STRING + 2
+	JUMP @collect_regular_string_iter ; Loop
+
+:collect_regular_string_done
+	LOADUI R0 34                ; Using "
+	STORE8 R0 R2 0              ; MESSAGE[0] = '"'
+	LOADUI R0 10                ; Using '\n'
+	STORE8 R0 R2 1              ; MESSAGE[1] = "\n"
+	ADDUI R2 R2 3               ; Add extra NULL padding
+	SWAP R2 R14                 ; Update HEAP
+	MOVE R0 R2                  ; Put MESSAGE in the right Spot
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; unary_expr_sizeof function
+;; Receives nothing
+;; Returns nothing
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+:unary_expr_sizeof
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $unary_expr_sizeof_string0 ; Our first error message
+	LOADUI R1 $open_paren       ; Using "("
+	CALLI R15 @require_match    ; Ensure a match
+	CALLI R15 @type_name        ; Get type_name
+	MOVE R2 R0                  ; Protect A
+	LOADUI R0 $unary_expr_sizeof_string1 ; Our final error message
+	LOADUI R1 $close_paren      ; Using ")"
+	CALLI R15 @require_match    ; Ensure a match
+
+	LOADUI R0 $unary_expr_sizeof_string2 ; Our header
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R2 4              ; A->SIZE
+	CALLI R15 @numerate_number  ; Convert to string
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:unary_expr_sizeof_string0
+	"ERROR in unary_expr
+Missing (
+"
+:unary_expr_sizeof_string1
+	"ERROR in unary_expr
+Missing )
+"
+:unary_expr_sizeof_string2
+	"LOADUI R0 "
+
+
+;; constant_load function
+;; Receives struct token_list* a in R0
+;; Returns nothing
+:constant_load
+	PUSHR R0 R15                ; Protect R0
+	LOADUI R0 $constant_load_string0 ; Our header
+	CALLI R15 @emit_out         ; emit it
+	POPR R0 R15                 ; Restore R0
+	LOAD32 R0 R0 16             ; A->ARGUMENTS
+	LOAD32 R0 R0 8              ; A->ARGUMENTS->S
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+	RET R15
+
+:constant_load_string0
+	"LOADI R0 "
+
+
+;; variable_load function
+;; Receives struct token_list* a in R0
+;;	and struct token_list* current_target in R8
+;; Returns Nothing
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+:variable_load
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	MOVE R2 R0                  ; Protect A
+
+	;; Check if function call
+	LOADUI R0 $type_function_name ; Using "FUNCTION"
+	LOAD32 R1 R2 12             ; A->TYPE
+	LOAD32 R1 R1 24             ; A->TYPE->NAME
+	CALLI R15 @match            ; IF "FUNCTION" ==  A->TYPE->NAME
+	JUMP.Z R0 @variable_load_regular ; Nope
+
+	LOADUI R0 $open_paren       ; Using "("
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF "(" == GLOBAL_TOKEN->S
+	JUMP.Z R0 @variable_load_regular ; Nope
+
+	;; Deal with function call
+	LOAD32 R0 R2 16             ; A->DEPTH
+	CALLI R15 @numerate_number  ; Convert to string
+	TRUE R1                     ; Passing TRUE
+	CALLI R15 @function_call    ; DO IT
+	JUMP @variable_load_done    ; Be done
+
+:variable_load_regular
+	LOAD32 R8 R2 12             ; CURRENT_TARGET = A->TYPE
+	LOADUI R0 $variable_load_string0 ; Our prefix
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R0 R2 16             ; A->DEPTH
+	CALLI R15 @numerate_number  ; Convert to string
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	;; check for special case 1
+	LOADUI R0 $equal            ; Using "="
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "="
+	JUMP.NZ R0 @variable_load_done ; Be done
+
+	;; deal with the general case
+	LOADUI R0 $variable_load_string1 ; Our postfix
+	CALLI R15 @emit_out         ; emit it
+
+:variable_load_done
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+:variable_load_string0
+	"ADDI R0 R14 "
+:variable_load_string1
+	"LOAD R0 R0 0
+"
+
+
+;; function_load function
+;; Receives struct token_list* a in R0
+;; Returns nothing
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+:function_load
+	PUSHR R1 R15                ; Protect R1
+	LOAD32 R0 R0 8              ; A->S
+	PUSHR R0 R15                ; Protect A->S
+	LOADUI R0 $open_paren       ; Using "("
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; If GLOBAL_TOKEN->S == "("
+	JUMP.Z R0 @function_load_regular ; If not do the simple thing
+
+	;; Deal iwth function call
+	POPR R0 R15                 ; Restore A->S
+	FALSE R1                    ; FALSE
+	CALLI R15 @function_call    ; Do the function call
+	JUMP @function_load_done    ; Clean up
+
+:function_load_regular
+	LOADUI R0 $function_load_string0 ; Using our header string
+	CALLI R15 @emit_out         ; emit it
+	POPR R0 R15                 ; Restore A->S
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+:function_load_done
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+:function_load_string0
+	"LOADR R0 4
+JUMP 4
+&FUNCTION_"
+
+
+;; global_load function
+;; Receives struct token_list* a in R0
+;;	and struct token_list* current_target in R8
+;; Returns nothing
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+:global_load
+	PUSHR R0 R15                ; Protect A
+	LOAD32 R8 R0 12             ; CURRENT_TARGET = A->TYPE
+	LOADUI R0 $global_load_string0 ; Our header string
+	CALLI R15 @emit_out         ; emit it
+	POPR R0 R15                 ; Restore A
+	LOAD32 R0 R0 8              ; A->S
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	PUSHR R1 R15                ; Protect R1
+	LOADUI R0 $equal            ; Using "="
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "="
+	JUMP.NZ R0 @global_load_done ; Skip the following
+
+	;; Deal with non-assignment
+	LOADUI R0 $global_load_string1 ; Our footer string
+	CALLI R15 @emit_out         ; emit it
+
+:global_load_done
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+:global_load_string0
+	"LOADR R0 4
+JUMP 4
+&GLOBAL_"
+:global_load_string1
+	"LOAD R0 R0 0
+"
+
+
+;; primary_expr_failure function
+;; Fails hard and fast
+;; Receives nothing
+;; HALTs and will trash registers
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+:primary_expr_failure
+	LOADUI R0 $primary_expr_failure_string0 ; Our first string
+	FALSE R1                    ; Display to User
+	CALLI R15 @file_print       ; Print it
+
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @file_print       ; Print it
+
+	LOADUI R0 $primary_expr_failure_string1 ; Our last string
+	CALLI R15 @file_print       ; Print it
+
+	CALLI R15 @line_error       ; Make it a line error message too
+	HALT
+
+:primary_expr_failure_string0
+	"Received "
+:primary_expr_failure_string1
+	" in primary_expr
+"
+
+
+;; primary_expr_string function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:primary_expr_string
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOADR32 R0 @current_count   ; Using CURRENT_COUNT
+	ADDUI R1 R0 1               ; CURRENT_COUNT = CURRENT_COUNT + 1
+	STORER32 R1 @current_count  ; Update CURRENT_COUNT
+	CALLI R15 @numerate_number  ; Convert to string
+	MOVE R2 R0                  ; Put string in safe place
+	LOADUI R0 $primary_expr_string_string0 ; Our string prefix
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	COPY R1 R2                  ; NUMBER_STRING
+	CALLI R15 @uniqueID_out     ; Make it unique
+
+	;; The target
+	LOADUI R0 $primary_expr_string_string1
+	COPY R1 R11                 ; Using STRINGS_LIST
+	CALLI R15 @emit             ; emit it
+	MOVE R1 R0                  ; Put STRINGS_LIST in correct place
+	LOAD32 R0 R9 8              ; Using FUNCTION->S
+	CALLI R15 @uniqueID         ; Make it unique
+	MOVE R11 R0                 ; Update STRINGS_LIST
+
+	;; Parse the string
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @parse_string     ; Parse it
+	COPY R1 R11                 ; Using STRINGS_LIST
+	CALLI R15 @emit             ; emit it
+	MOVE R11 R0                 ; Update STRINGS_LIST
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:primary_expr_string_string0
+	"LOADR R0 4
+JUMP 4
+&STRING_"
+:primary_expr_string_string1
+	":STRING_"
+
+
+;; primary_expr_char function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:primary_expr_char
+	PUSHR R0 R15                ; Protect R0
+	LOADUI R0 $primary_expr_char_string0 ; Using our header string
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	ADDUI R0 R0 1               ; GLOBAL_TOKEN->S + 1
+	CALLI R15 @escape_lookup    ; escape_lookup value
+	CALLI R15 @numerate_number  ; Make it a string
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:primary_expr_char_string0
+	"LOADI R0 "
+
+
+;; primary_expr_number function
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:primary_expr_number
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @numerate_string  ; Convert it to an int
+	CMPSKIPI.L R0 32767         ; If 32767 > size
+	JUMP @primary_expr_number_ugly ; Do it the ugly way
+	CMPSKIPI.G R0 -32767         ; If -32767 < size
+	JUMP @primary_expr_number_ugly ; Do it the ugly way
+
+	LOADUI R0 $primary_expr_number_string0 ; Our header
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @emit_out         ; emit it
+	JUMP @primary_expr_number_done ; Be done
+
+:primary_expr_number_ugly
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R0 R15                ; Protect the size
+	LOADUI R0 $primary_expr_number_string1 ; Our ugly header
+	CALLI R15 @emit_out         ; emit it
+	POPR R0 R15                 ; Get the size back
+	COPY R1 R14                 ; Get pointer
+	CALLI R15 @hex32            ; Convert size to string
+	ADDUI R14 R14 1             ; Extra pad for paranoia
+	MOVE R0 R1                  ; Put string in right place
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $primary_expr_number_string2 ; Our ugly trailer
+	CALLI R15 @emit_out         ; emit it
+	POPR R1 R15                 ; Restore R1
+:primary_expr_number_done
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	RET R15
+
+:primary_expr_number_string0
+	"LOADI R0 "
+:primary_expr_number_string1
+	"LOADR R0 4
+JUMP 4
+'"
+:primary_expr_number_string2
+	"'"
+
+
+;; hex32 functionality
+;; Accepts 32bit value in R0
+;; Require R14 to be the heap pointer
+;; WILL ALTER R14 !
+;; Returns to whatever called it
+:hex32
+	PUSHR R0 R15
+	SR0I R0 16                  ; Do high word first
+	CALLI R15 @hex16
+	POPR R0 R15
+:hex16
+	PUSHR R0 R15
+	SR0I R0 8                   ; Do high byte first
+	CALLI R15 @hex8
+	POPR R0 R15
+:hex8
+	PUSHR R0 R15
+	SR0I R0 4                   ; Do high nybble first
+	CALLI R15 @hex4
+	POPR R0 R15
+:hex4
+	ANDI R0 R0 0xF              ; isolate nybble
+	ADDUI R0 R0 48              ; convert to ascii
+	CMPSKIPI.LE R0 57           ; If nybble was greater than '9'
+	ADDUI R0 R0 7               ; Shift it into 'A' range of ascii
+	STORE8 R0 R14 0             ; Store Hex Char
+	ADDUI R14 R14 1             ; Increment address pointer
+	RET R15                     ; Get next nybble or return if done
+
+
+;; primary_expr_variable function
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:primary_expr_variable
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOAD32 R2 R13 8             ; S = GLOBAL_TOKEN->S
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	COPY R0 R2                  ; Using S
+	LOADR32 R1 @global_constant_list
+	CALLI R15 @sym_lookup       ; Lookup S in CONSTANTS
+	JUMP.Z R0 @primary_expr_variable_locals ; try Locals
+
+	;; Deal with Constants
+	CALLI R15 @constant_load    ; A is in R0 already
+	JUMP @primary_expr_variable_done ; Moving on
+
+:primary_expr_variable_locals
+	COPY R0 R2                  ; Using S
+	LOAD32 R1 R9 4              ; Using FUNCTION->LOCALS
+	CALLI R15 @sym_lookup       ; Lookup S in Locals
+	JUMP.Z R0 @primary_expr_variable_arguments ; try arguments
+
+	;; Deal with Locals
+	CALLI R15 @variable_load    ; A is in R0 already
+	JUMP @primary_expr_variable_done ; Moving on
+
+:primary_expr_variable_arguments
+	COPY R0 R2                  ; Using S
+	LOAD32 R1 R9 16             ; Using FUNCTION->ARGUMENTS
+	CALLI R15 @sym_lookup       ; Lookup S in arguments
+	JUMP.Z R0 @primary_expr_variable_function ; try Functions
+
+	;; Deal with argument
+	CALLI R15 @variable_load    ; A is in R0 already
+	JUMP @primary_expr_variable_done ; Moving on
+
+:primary_expr_variable_function
+	COPY R0 R2                  ; Using S
+	LOADR32 R1 @global_function_list ; Get current GLOBAL_FUNCTION_LIST
+	CALLI R15 @sym_lookup       ; Lookup S in GLOBAL_FUNCTION_LIST
+	JUMP.Z R0 @primary_expr_variable_global ; try Globals
+
+	;; Deal with function
+	CALLI R15 @function_load    ; Dothe work
+	JUMP @primary_expr_variable_done ; Moving on
+
+:primary_expr_variable_global
+	COPY R0 R2                  ; Using S
+	LOADR32 R1 @global_symbol_list ; Get current GLOBAL_SYMBOL_LIST
+	CALLI R15 @sym_lookup       ; Lookup S in GLOBAL_SYMBOL_LIST
+	JUMP.Z R0 @primary_expr_variable_failure ; Looks like it isn't anything we know
+
+	;; Deal with a global
+	CALLI R15 @global_load
+
+:primary_expr_variable_done
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:primary_expr_variable_failure
+	MOVE R0 R2                  ; Using S
+	FALSE R1                    ; We want the user to see
+	CALLI R15 @file_print       ; Print it
+
+	LOADUI R0 $primary_expr_variable_string0 ; Body
+	CALLI R15 @file_print       ; Print it
+	CALLI R15 @line_error       ; Provide useful error info
+	HALT
+
+:primary_expr_variable_string0
+	" is not a defined symbol
+"
+
+
+;; promote_type function
+;; Receives struct type* in R0 and struct type* in R1
+;; Returns first match struct type* in R0
+:promote_type
+	JUMP.Z R1 @promote_type_abort0 ; If B is NULL just abort
+	PUSHR R1 R15                ; Protect R1
+	SWAP R0 R1                  ; Give A a try
+	JUMP.Z R1 @promote_type_abort1 ; A is NULL just short abort
+
+	;; Looks like we have a bunch of work to do
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+	PUSHR R5 R15                ; Protect R5
+	MOVE R5 R1                  ; Put A in the right spot
+	MOVE R4 R0                  ; Put B in the right spot
+	LOADR32 R3 @global_types    ; I = GLOBAL_TYPES
+
+:promote_type_iter
+	LOAD32 R1 R3 24             ; I->NAME
+	LOAD32 R0 R5 24             ; A->NAME
+	CMPJUMPI.E R0 R1 @promote_type_done ; break
+	LOAD32 R0 R4 24             ; B->NAME
+	CMPJUMPI.E R0 R1 @promote_type_done ; break
+
+	LOAD32 R1 R3 12             ; I->INDIRECT
+	LOAD32 R1 R1 24             ; I->INDIRECT->NAME
+	LOAD32 R0 R5 24             ; A->NAME
+	CMPJUMPI.E R0 R1 @promote_type_done ; break
+	LOAD32 R0 R4 24             ; B->NAME
+	CMPJUMPI.E R0 R1 @promote_type_done ; break
+
+	LOAD32 R3 R3 0              ; I = I->NEXT
+	JUMP.NZ R3 @promote_type_iter ; Loop if not NULL
+
+:promote_type_done
+	MOVE R0 R3                  ; Return I
+	POPR R5 R15                 ; Restore R5
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+:promote_type_abort1
+	POPR R1 R15                 ; Restore R1
+:promote_type_abort0
+	RET R15
+
+
+;; common_recursion function
+;; Receives FUNCTION* in R0
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:common_recursion
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	MOVE R2 R0                  ; Protect F
+	COPY R1 R8                  ; LAST_TYPE = CURRENT_TARGET
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	LOADUI R0 $common_recursion_string0 ; Header string
+	CALLI R15 @emit_out         ; Our header
+
+	CALL R2 R15                 ; CALL F()
+
+	COPY R0 R8                  ; Using CURRENT_TARGET
+	CALLI R15 @promote_type     ; Promote type
+	MOVE R8 R0                  ; update CURRENT_TARGET
+
+	LOADUI R0 $common_recursion_string1 ; Footer string
+	CALLI R15 @emit_out         ; Our footer
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:common_recursion_string0
+	"PUSHR R0 R15	#_common_recursion
+"
+:common_recursion_string1
+	"POPR R1 R15	# _common_recursion
+"
+
+
+;; general_recursion function
+;; Receives FUNCTION F in R0, char* s in R1, char* name in R2
+;; and FUNCTION ITERATE in R3
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns nothing
+:general_recursion
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect S
+	PUSHR R0 R15                ; Protect F
+	COPY R0 R2                  ; Using NAME
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == NAME
+	JUMP.Z R0 @general_recursion_done
+
+	;; deal with case of match
+	POPR R0 R15                 ; Restore F
+	CALLI R15 @common_recursion ; Recurse
+
+	POPR R1 R15                 ; Restore S
+	COPY R0 R1                  ; Put S in correct place
+	CALLI R15 @emit_out         ; emit it
+
+	CALL R3 R15                 ; CALL ITERATE()
+	POPR R0 R15                 ; Restore R0
+	RET R15                     ; Don't double pop
+
+:general_recursion_done
+	POPR R0 R15                 ; Restore F
+	POPR R1 R15                 ; Restore S
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+
+;; ceil_log2 function
+;; Receives INT A in R0
+;; Returns LOG2(A) in R0
+:ceil_log2
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	FALSE R2                    ; RESULT = 0
+
+	SUBI R1 R0 1                ; A - 1
+	AND R1 R1 R0                ; A & (A - 1)
+	CMPSKIPI.NE R1 0            ; IF (A & (A - 1)) == 0
+	LOADI R2 -1                 ; RESULT = -1
+
+:ceil_log2_iter
+	JUMP.Z R0 @ceil_log2_done   ; IF A > 0
+	ADDI R2 R2 1                ; RESULT = RESULT + 1
+	SARI R0 1                   ; A = A >> 1
+	JUMP @ceil_log2_iter        ; Loop
+
+:ceil_log2_done
+	MOVE R0 R2                  ; Use RESULT
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; postfix_expr_arrow function
+;; Receives nothing
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:postfix_expr_arrow
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOADUI R0 $postfix_expr_arrow_string0 ; Our header string
+	CALLI R15 @emit_out         ; Emit it
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	COPY R0 R8                  ; Passing CURRENT_TARGET
+	LOAD32 R1 R13 8             ; Using GLOBAL_TOKEN->S
+	CALLI R15 @lookup_member    ; Look it up
+	LOAD32 R2 R0 4              ; Protect I->SIZE
+	LOAD32 R8 R0 20             ; CURRENT_TARGET = I->TYPE
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	LOAD32 R1 R0 8              ; I->OFFSET
+	JUMP.Z R1 @postfix_expr_arrow_offset ; If no offset needed skip the work
+
+	;; Deal with non-zero offsets
+	LOADUI R0 $postfix_expr_arrow_string1 ; Our first prefix
+	CALLI R15 @emit_out         ; Emit it
+	LOADUI R0 $postfix_expr_arrow_string2 ; Our second prefix
+	CALLI R15 @emit_out         ; Emit it
+
+	MOVE R0 R1                  ; Put I->OFFSET in the right place
+	CALLI R15 @numerate_number  ; Convert to string
+	CALLI R15 @emit_out         ; Emit it
+
+	LOADUI R0 $postfix_expr_arrow_string3 ; Our postfix
+	CALLI R15 @emit_out         ; Emit it
+
+:postfix_expr_arrow_offset
+	LOADUI R0 $equal            ; Using "="
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "="
+	JUMP.NZ R0 @postfix_expr_arrow_done
+
+	LOADUI R0 4                 ; Compare against 4
+	CMPJUMPI.L R0 R2 @postfix_expr_arrow_done
+
+	;; Deal with special case
+	LOADUI R0 $postfix_expr_arrow_string4 ; Our final string
+	CALLI R15 @emit_out         ; Emit it
+
+:postfix_expr_arrow_done
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:postfix_expr_arrow_string0
+	"# looking up offset
+"
+:postfix_expr_arrow_string1
+	"# -> offset calculation
+"
+:postfix_expr_arrow_string2
+	"ADDUI R0 R0 "
+:postfix_expr_arrow_string3
+	"
+"
+:postfix_expr_arrow_string4
+	"LOAD R0 R0 0
+"
+
+
+;; postfix_expr_array function
+;; Receives nothing
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:postfix_expr_array
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	COPY R2 R8                  ; ARRAY = CURRENT_TARGET
+	LOADUI R0 $expression       ; Using EXPRESSION
+	CALLI R15 @common_recursion ; Recurse
+	MOVE R8 R2                  ; CURRENT_TARGET = ARRAY
+	LOADUI R2 $postfix_expr_array_string0 ; ASSIGN = load integer
+
+	LOADUI R0 $type_char_indirect_name ; Using "char*"
+	LOAD32 R1 R8 24             ; CURRENT_TARGET->NAME
+	CALLI R15 @match            ; IF CURRENT_TARGET->NAME == "char*"
+	CMPSKIPI.E R0 0             ; deal with Byte
+	LOADUI R2 $postfix_expr_array_string1 ; ASSIGN = load byte
+	JUMP.NZ R0 @postfix_expr_array_byte ; Skip if Byte
+
+	;; Deal with larger than byte
+	LOADUI R0 $postfix_expr_array_string2 ; Our shift
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R8 12             ; CURRENT_TARGET->INDIRECT
+	LOAD32 R0 R0 4              ; CURRENT_TARGET->INDIRECT->SIZE
+	CALLI R15 @ceil_log2        ; LOG2(CURRENT_TARGET->INDIRECT->SIZE)
+	CALLI R15 @numerate_number  ; Convert to string
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+:postfix_expr_array_byte
+	LOADUI R0 $postfix_expr_array_string3 ; Add the offset
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $postfix_expr_array_string4 ; Our final error message
+	LOADUI R1 $close_bracket    ; Using "]"
+	CALLI R15 @require_match    ; Ensure match
+
+	LOADUI R0 $equal            ; Using "="
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "="
+	CMPSKIPI.E R0 0             ; If match
+	LOADUI R2 $postfix_expr_array_string5 ; empty string
+
+	MOVE R0 R2                  ; What ever string survived
+	CALLI R15 @emit_out         ; emit it
+
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+
+	RET R15
+
+:postfix_expr_array_string0
+	"LOAD R0 R0 0
+"
+:postfix_expr_array_string1
+	"LOAD8 R0 R0 0
+"
+:postfix_expr_array_string2
+	"SALI R0 "
+:postfix_expr_array_string3
+	"ADD R0 R0 R1
+"
+:postfix_expr_array_string4
+	"ERROR in postfix_expr
+Missing ]
+"
+:postfix_expr_array_string5
+	""
+
+
+;; postfix_expr_stub function
+;; Receives nothing
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:postfix_expr_stub
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+
+	LOADUI R0 $open_bracket     ; Using "["
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "["
+	JUMP.Z R0 @postfix_expr_stub_next
+
+	;; Deal with "[" case
+	CALLI R15 @postfix_expr_array ; process
+	CALLI R15 @postfix_expr_stub ; recurse
+
+:postfix_expr_stub_next
+	LOADUI R0 $arrow_string     ; Using "->"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "->"
+	JUMP.Z R0 @postfix_expr_stub_done ; clean up
+
+	;; Deal with "->" case
+	CALLI R15 @postfix_expr_arrow ; Process
+	CALLI R15 @postfix_expr_stub ; recurse
+
+:postfix_expr_stub_done
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+
+;; postfix_expr function
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:postfix_expr
+	CALLI R15 @primary_expr     ; Walk up the tree
+	CALLI R15 @postfix_expr_stub ; Deal with nodes on this level
+	RET R15
+
+
+;; additive_expr_stub function
+;; receives nothing
+;; returns nothing
+;; Updates struct token_list*
+:additive_expr_stub
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	;; Fixed pieces
+	LOADUI R0 $postfix_expr     ; Set First argument
+	LOADUI R3 $additive_expr_stub
+
+	;; The + bit
+	LOADUI R1 $additive_expr_stub_string0 ; Our first operation
+	LOADUI R2 $plus_string      ; Using "+"
+	CALLI R15 @general_recursion
+
+	;; The - bit
+	LOADUI R1 $additive_expr_stub_string1 ; Our second operation
+	LOADUI R2 $minus_string     ; Using "-"
+	CALLI R15 @general_recursion
+
+	;; The * bit
+	LOADUI R1 $additive_expr_stub_string2 ; Our third operation
+	LOADUI R2 $multiply_string  ; Using "*"
+	CALLI R15 @general_recursion
+
+	;; The / bit
+	LOADUI R1 $additive_expr_stub_string3 ; Our fourth operation
+	LOADUI R2 $divide_string    ; Using "/"
+	CALLI R15 @general_recursion
+
+	;; The % bit
+	LOADUI R1 $additive_expr_stub_string4 ; Our fifth operation
+	LOADUI R2 $modulus_string   ; Using "%"
+	CALLI R15 @general_recursion
+
+	;; The << bit
+	LOADUI R1 $additive_expr_stub_string5 ; Our sixth operation
+	LOADUI R2 $left_shift_string ; Using "<<"
+	CALLI R15 @general_recursion
+
+	;; The >> bit
+	LOADUI R1 $additive_expr_stub_string6 ; Our final operation
+	LOADUI R2 $right_shift_string ; Using ">>"
+	CALLI R15 @general_recursion
+
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:additive_expr_stub_string0
+	"ADD R0 R1 R0
+"
+:additive_expr_stub_string1
+	"SUB R0 R1 R0
+"
+:additive_expr_stub_string2
+	"MUL R0 R1 R0
+"
+:additive_expr_stub_string3
+	"DIVU R0 R1 R0
+"
+:additive_expr_stub_string4
+	"MODU R0 R1 R0
+"
+:additive_expr_stub_string5
+	"SAL R0 R1 R0
+"
+:additive_expr_stub_string6
+	"SAR R0 R1 R0
+"
+
+
+;; additive_expr function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:additive_expr
+	CALLI R15 @postfix_expr     ; Walk up the tree
+	CALLI R15 @additive_expr_stub ; Deal with nodes at this level
+	RET R15
+
+
+;; relational_expr_stub function
+;; receives nothing
+;; returns nothing
+;; Updates struct token_list*
+:relational_expr_stub
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	;; Fixed pieces
+	LOADUI R0 $additive_expr     ; Set First argument
+	LOADUI R3 $relational_expr_stub
+
+	;; The < bit
+	LOADUI R1 $relational_expr_stub_string0 ; Our first operation
+	LOADUI R2 $less_than_string ; Using "<"
+	CALLI R15 @general_recursion
+
+	;; The <= bit
+	LOADUI R1 $relational_expr_stub_string1 ; Our second operation
+	LOADUI R2 $less_than_equal_string ; Using "<="
+	CALLI R15 @general_recursion
+
+	;; The >= bit
+	LOADUI R1 $relational_expr_stub_string2 ; Our third operation
+	LOADUI R2 $greater_than_equal_string ; Using ">="
+	CALLI R15 @general_recursion
+
+	;; The > bit
+	LOADUI R1 $relational_expr_stub_string3 ; Our fourth operation
+	LOADUI R2 $greater_than_string ; Using ">"
+	CALLI R15 @general_recursion
+
+	;; The == bit
+	LOADUI R1 $relational_expr_stub_string4 ; Our fifth operation
+	LOADUI R2 $equal_to_string  ; Using "=="
+	CALLI R15 @general_recursion
+
+	;; The != bit
+	LOADUI R1 $relational_expr_stub_string5 ; Our final operation
+	LOADUI R2 $not_equal_string ; Using "!="
+	CALLI R15 @general_recursion
+
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:relational_expr_stub_string0
+	"CMPSKIP.GE R1 R0
+LOADUI R2 1
+MOVE R0 R2
+"
+:relational_expr_stub_string1
+	"CMPSKIP.G R1 R0
+LOADUI R2 1
+MOVE R0 R2
+"
+:relational_expr_stub_string2
+	"CMPSKIP.L R1 R0
+LOADUI R2 1
+MOVE R0 R2
+"
+:relational_expr_stub_string3
+	"CMPSKIP.LE R1 R0
+LOADUI R2 1
+MOVE R0 R2
+"
+:relational_expr_stub_string4
+	"CMPSKIP.NE R1 R0
+LOADUI R2 1
+MOVE R0 R2
+"
+:relational_expr_stub_string5
+	"CMPSKIP.E R1 R0
+LOADUI R2 1
+MOVE R0 R2
+"
+
+
+;; relational_expr function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:relational_expr
+	CALLI R15 @additive_expr    ; Walk up the tree
+	CALLI R15 @relational_expr_stub ; Deal with nodes at this level
+	RET R15
+
+
+;; relational_expr_stub function
+;; receives nothing
+;; returns nothing
+;; Updates struct token_list*
+:bitwise_expr_stub
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	;; Fixed pieces
+	LOADUI R0 $relational_expr  ; Set First argument
+	LOADUI R3 $bitwise_expr_stub
+
+	;; The & bit
+	LOADUI R1 $bitwise_expr_stub_string0 ; Our first operation
+	LOADUI R2 $bitwise_and      ; Using "&"
+	CALLI R15 @general_recursion
+
+	;; The && bit
+	LOADUI R1 $bitwise_expr_stub_string0 ; Our first operation
+	LOADUI R2 $logical_and      ; Using "&&"
+	CALLI R15 @general_recursion
+
+	;; The | bit
+	LOADUI R1 $bitwise_expr_stub_string1 ; Our second operation
+	LOADUI R2 $bitwise_or       ; Using "|"
+	CALLI R15 @general_recursion
+
+	;; The || bit
+	LOADUI R1 $bitwise_expr_stub_string1 ; Our second operation
+	LOADUI R2 $logical_or       ; Using "||"
+	CALLI R15 @general_recursion
+
+	;; The ^ bit
+	LOADUI R1 $bitwise_expr_stub_string2 ; Our second operation
+	LOADUI R2 $bitwise_xor       ; Using "^"
+	CALLI R15 @general_recursion
+
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:bitwise_expr_stub_string0
+	"AND R0 R0 R1
+"
+:bitwise_expr_stub_string1
+	"OR R0 R0 R1
+"
+:bitwise_expr_stub_string2
+	"XOR R0 R0 R1
+"
+
+
+;; bitwise_expr function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:bitwise_expr
+	CALLI R15 @relational_expr  ; Walk up the tree
+	CALLI R15 @bitwise_expr_stub ; Deal with nodes at this level
+	RET R15
+
+
+;; primary_expr function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:primary_expr
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	LOADUI R0 $sizeof_string    ; Load "sizeof"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "sizeof"
+	JUMP.Z R0 @primary_expr_negate ; Guess not
+
+	;; Deal with sizeof expression
+	CALLI R15 @unary_expr_sizeof ; Do real work
+	JUMP @primary_expr_done     ; Wrap up
+
+:primary_expr_negate
+	LOADU8 R0 R1 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.E R0 45            ; IF GLOBAL_TOKEN->S[0] == '-'
+	JUMP @primary_expr_bang     ; If not try '!'
+
+	;; Deal with -a and -4 expressions
+	LOADUI R0 $primary_expr     ; Using PRIMARY_EXPR
+	CALLI R15 @common_recursion ; Recurse
+	LOADUI R0 $primary_expr_str0 ; add footer
+	CALLI R15 @emit_out         ; emit it
+
+	JUMP @primary_expr_done     ; Wrap up
+
+:primary_expr_bang
+	CMPSKIPI.E R0 33            ; IF GLOBAL_TOKEN->S[0] == "!"
+	JUMP @primary_expr_nested   ; If not try '('
+
+	;; deal with !a expressions
+	LOADUI R0 $postfix_expr     ; Using POSTFIX_EXPR
+	CALLI R15 @common_recursion ; Recurse
+	LOADUI R0 $primary_expr_str1 ; add footer
+	CALLI R15 @emit_out         ; emit it
+
+	JUMP @primary_expr_done     ; Wrap up
+
+:primary_expr_nested
+	CMPSKIPI.E R0 40            ; IF GLOBAL_TOKEN->S[0] == '('
+	JUMP @primary_expr_ch       ; If not try 'char'
+
+	;; Deal with ( expr )
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	CALLI R15 @expression       ; Recurse
+
+	LOADUI R0 $primary_expr_str2 ; Using error message
+	LOADUI R1 $close_paren      ; Using ")"
+	CALLI R15 @require_match    ; Make sure we have closing match
+
+	JUMP @primary_expr_done     ; Wrap up
+
+:primary_expr_ch
+	CMPSKIPI.E R0 39            ; IF GLOBAL_TOKEN->S[0] == '\''
+	JUMP @primary_expr_st       ; If not try "string"
+
+	;; Deal with 'char'
+	CALLI R15 @primary_expr_char ; Collect char
+	JUMP @primary_expr_done     ; Wrap up
+
+:primary_expr_st
+	CMPSKIPI.E R0 34            ; IF GLOBAL_TOKEN->S[0] == '"'
+	JUMP @primary_expr_var      ; If not try variables
+
+	;; deal with "string"
+	CALLI R15 @primary_expr_string ; Collect string
+	JUMP @primary_expr_done     ; Wrap up
+
+:primary_expr_var
+	LOADUI R1 $variable_chars   ; Using a-z+A-Z+_
+	CALLI R15 @in_set           ; IF GLOBAL_TOKEN->S[0] in a-z+A-Z+_
+	JUMP.Z R0 @primary_expr_num
+
+	;; Deal with foo TODO
+	CALLI R15 @primary_expr_variable ; deal with names
+	JUMP @primary_expr_done     ; Wrap up
+
+:primary_expr_num
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	LOADUI R1 $digit_chars      ; Using 0-9
+	CALLI R15 @in_set           ; IF GLOBAL_TOKEN->S[0] in 0-9
+	JUMP.Z R0 @primary_expr_failure ; Fail HARD
+
+	;; Deal with 5
+	CALLI R15 @primary_expr_number ; deal with number
+
+:primary_expr_done
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:primary_expr_str0
+	"NEG R0 R0
+"
+:primary_expr_str1
+	"XORI R0 R0 1
+"
+:primary_expr_str2
+	"Error in Primary expression
+Didn't get )
+"
+
+
+;; expression function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:expression
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	CALLI R15 @bitwise_expr     ; Check for more primitives first
+	LOADUI R0 $equal            ; Using "="
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "="
+	JUMP.Z R0 @expression_done  ; Be done
+
+	;; Determine store type
+	LOADUI R3 $expression_string1 ; Assuming the default of STORE CHAR
+
+	;; First possible reason for INT
+	LOADUI R0 $close_bracket    ; Using "]"
+	LOAD32 R1 R13 4             ; GLOBAL_TOKEN->PREV
+	LOAD32 R1 R1 8              ; GLOBAL_TOKEN->PREV->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->PREV-> == "]"
+	CMPSKIPI.NE R0 0            ; IF FALSE
+	LOADUI R3 $expression_string0 ; STORE INTEGER
+
+	;; Second possible reason for INTeger
+	LOADUI R0 $type_char_indirect_name ; Using "char*"
+	LOAD32 R1 R8 24             ; CURRENT_TARGET->NAME
+	CALLI R15 @match            ; IF CURRENT_TARGET->NAME == "char*"
+	CMPSKIPI.NE R0 0            ; IF FALSE
+	LOADUI R3 $expression_string0 ; STORE INTEGER
+
+	;; Recurse to evaluate expression being stored
+	LOADUI R0 $expression       ; Using expression
+	CALLI R15 @common_recursion ; Perform common recursion
+
+	;; Put our string and clean up
+	MOVE R0 R3                  ; Using our STORED string
+	CALLI R15 @emit_out         ; emit it
+
+	FALSE R8                    ; CURRENT_TARGET = NULL
+
+:expression_done
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:expression_string0
+	"STORE R0 R1 0
+"
+:expression_string1
+	"STORE8 R0 R1 0
+"
+
+;; process_if function
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:process_if
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOADR32 R0 @current_count   ; Using CURRENT_COUNT
+	ADDUI R1 R0 1               ; CURRENT_COUNT = CURRENT_COUNT + 1
+	STORER32 R1 @current_count  ; Update CURRENT_COUNT
+	CALLI R15 @numerate_number  ; Convert CURRENT_COUNT to string
+	MOVE R2 R0                  ; Protect our string
+
+	LOADUI R0 $process_if_string0 ; using first string
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	COPY R1 R2                  ; Using our current count string
+	CALLI R15 @uniqueID_out     ; Add unique identifier
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $process_if_string1 ; Our first error message
+	LOADUI R1 $open_paren       ; Using "("
+	CALLI R15 @require_match    ; Make sure we have what we need
+	CALLI R15 @expression       ; Recurse to get our boolean expression
+
+	LOADUI R0 $process_if_string2 ; Our test and jump
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	COPY R1 R2                  ; Using our current count string
+	CALLI R15 @uniqueID_out     ; Add unique identifier
+
+	LOADUI R0 $process_if_string3 ; Our second error message
+	LOADUI R1 $close_paren      ; Using ")"
+	CALLI R15 @require_match    ; Make sure we have what we need
+	CALLI R15 @statement        ; Collect our if statement
+
+	LOADUI R0 $process_if_string4 ; Our jump over else
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	COPY R1 R2                  ; Using our current count string
+	CALLI R15 @uniqueID_out     ; Add unique identifier
+	LOADUI R0 $process_if_string5 ; Our else label
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; Add unique identifier
+
+	LOADUI R0 $else_string      ; Using "else"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "else"
+	JUMP.Z R0 @process_if_else  ; Looks like no else
+
+	;; Deal with else
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN =  GLOBAL_TOKEN->NEXT
+	CALLI R15 @statement        ; Grab else statement
+
+:process_if_else
+	LOADUI R0 $process_if_string6 ; Our jump over else
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	COPY R1 R2                  ; Using our current count string
+	CALLI R15 @uniqueID_out     ; Add unique identifier
+
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:process_if_string0
+	"# IF_"
+:process_if_string1
+	"ERROR in process_if
+MISSING (
+"
+:process_if_string2
+	"JUMP.Z R0 @ELSE_"
+:process_if_string3
+	"ERROR in process_if
+MISSING )
+"
+:process_if_string4
+	"JUMP @_END_IF_"
+:process_if_string5
+	":ELSE_"
+:process_if_string6
+	":_END_IF_"
+
+
+;; save_break_frame microfunction
+;; Overwrites R0 and R1
+;; Saves break frame on stack
+;; Returns to caller
+:save_break_frame
+	POPR R1 R15                 ; Save return address
+	LOADR32 R0 @break_frame     ; Obtain BREAK_FRAME
+	PUSHR R0 R15                ; Protect BREAK_FRAME
+	LOADR32 R0 @break_target_head ; obtain HEAD
+	PUSHR R0 R15                ; Protect HEAD
+	LOADR32 R0 @break_target_func ; obtain FUNC
+	PUSHR R0 R15                ; Protect FUNC
+	LOADR32 R0 @break_target_num ; obtain NUM
+	PUSHR R0 R15                ; Protect NUM
+	PUSHR R1 R15                ; Set where we are returning to
+	RET R15
+
+
+;; restore_break_frame microfunction
+;; Overwrites R0 and R1
+;; Restores break frame from stack
+;; Returns to caller
+:restore_break_frame
+	POPR R1 R15                 ; Save return address
+	POPR R0 R15                 ; obtain NUM
+	STORER32 R0 @break_target_num ; Restore NUM
+	POPR R0 R15                 ; obtain FUNC
+	STORER32 R0 @break_target_func ; Restore FUNC
+	POPR R0 R15                 ; obtain HEAD
+	STORER32 R0 @break_target_head ; Restore HEAD
+	POPR R0 R15                 ; obtain BREAK_FRAME
+	STORER32 R0 @break_frame    ; Restore BREAK_FRAME
+	PUSHR R1 R15                ; Set where we are returning to
+	RET R15
+
+
+;; set_break_frame microfunction
+;; Receives char* num in R0, char* head in R1
+;; Overwrites R0
+;; Sets break frame using
+;; R9 holding FUNC
+;; Returns to calling function
+:set_break_frame
+	STORER32 R1 @break_target_head ; update BREAK_TARGET_HEAD
+	STORER32 R0 @break_target_num ; Update BREAK_TARGET_NUM
+	LOAD32 R0 R9 4              ; Using FUNCTION->LOCALS
+	STORER32 R0 @break_frame    ; update BREAK_FRAME
+	LOAD32 R0 R9 8              ; Using FUNCTION->S
+	STORER32 R0 @break_target_func ; update BREAK_TARGET_FUNC
+	RET R15
+
+
+;; process_for function
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:process_for
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R0 R15                ; Protect R0
+	CALLI R15 @save_break_frame ; Save break frame
+
+	LOADR32 R0 @current_count   ; Using CURRENT_COUNT
+	ADDUI R1 R0 1               ; CURRENT_COUNT = CURRENT_COUNT + 1
+	STORER32 R1 @current_count  ; Update CURRENT_COUNT
+	CALLI R15 @numerate_number  ; Convert to string
+	COPY R2 R0                  ; Protect NUMBER_STRING
+
+	LOADUI R1 $process_for_string0 ; Get new HEAD
+	CALLI R15 @set_break_frame  ; Set the break frame values
+
+	LOADUI R0 $process_for_string1 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	LOADUI R0 $process_for_string2 ; Our first error message
+	LOADUI R1 $open_paren       ; Using "("
+	CALLI R15 @require_match    ; Verify match
+	LOADUI R0 $semicolon        ; Using ";"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S -- ";"
+	CMPSKIPI.NE R0 0            ; If GLOBAL_TOKEN->S != ";"
+	CALLI R15 @expression       ; Skip that step
+
+	LOADUI R0 $process_for_string3 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	LOADUI R0 $process_for_string4 ; Our second error message
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Verify match
+	CALLI R15 @expression       ; TEST logic required
+
+	LOADUI R0 $process_for_string5 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+	LOADUI R0 $process_for_string6 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+	LOADUI R0 $process_for_string7 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	LOADUI R0 $process_for_string8 ; Our third error message
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Verify match
+	CALLI R15 @expression       ; Iterator logic
+
+	LOADUI R0 $process_for_string9 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+	LOADUI R0 $process_for_string10 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	LOADUI R0 $process_for_string11 ; Our final error message
+	LOADUI R1 $close_paren      ; Using ")"
+	CALLI R15 @require_match    ; Verify match
+	CALLI R15 @statement        ; Main body
+
+	LOADUI R0 $process_for_string12 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+	LOADUI R0 $process_for_string13 ; Our comment header
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	CALLI R15 @restore_break_frame ; Restore break frame
+	POPR R0 R15                 ; Restore R0
+	POPR R1 R15                 ; Restore R1
+	POPR R2 R15                 ; Restore R2
+	RET R15
+
+:process_for_string0
+	"FOR_END_"
+:process_for_string1
+	"# FOR_initialization_"
+:process_for_string2
+	"ERROR in process_for
+MISSING (
+"
+:process_for_string3
+	":FOR_"
+:process_for_string4
+	"ERROR in process_for
+MISSING ;1
+"
+:process_for_string5
+	"JUMP.Z R0 @FOR_END_"
+:process_for_string6
+	"JUMP @FOR_THEN_"
+:process_for_string7
+	":FOR_ITER_"
+:process_for_string8
+	"ERROR in process_for
+MISSING ;2
+"
+:process_for_string9
+	"JUMP @FOR_"
+:process_for_string10
+	":FOR_THEN_"
+:process_for_string11
+	"ERROR in process_for
+MISSING )
+"
+:process_for_string12
+	"JUMP @FOR_ITER_"
+:process_for_string13
+	":FOR_END_"
+
+
+;; process_do function
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:process_do
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R0 R15                ; Protect R0
+	CALLI R15 @save_break_frame ; Save break frame
+
+	LOADR32 R0 @current_count   ; Using CURRENT_COUNT
+	ADDUI R1 R0 1               ; CURRENT_COUNT = CURRENT_COUNT + 1
+	STORER32 R1 @current_count  ; Update CURRENT_COUNT
+	CALLI R15 @numerate_number  ; Convert to string
+	COPY R2 R0                  ; Protect NUMBER_STRING
+
+	LOADUI R1 $process_do_string0 ; Using our desired head
+	CALLI R15 @set_break_frame  ; Set the break frame values
+
+	LOADUI R0 $process_do_string1 ; Our label
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	CALLI R15 @statement        ; Collect our Do statement
+
+	LOADUI R0 $process_do_string2 ; our first error message
+	LOADUI R1 $while_string     ; Using "while"
+	CALLI R15 @require_match    ; Check for match
+	LOADUI R0 $process_do_string3 ; our second error message
+	LOADUI R1 $open_paren       ; Using "("
+	CALLI R15 @require_match    ; Check for match
+	CALLI R15 @expression       ; Our logical expression
+	LOADUI R0 $process_do_string4 ; our third error message
+	LOADUI R1 $close_paren      ; Using ")"
+	CALLI R15 @require_match    ; Check for match
+	LOADUI R0 $process_do_string5 ; our final error message
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Check for match
+
+	LOADUI R0 $process_do_string6 ; Our test string
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Put NUMBER_STRING in right place
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+	LOADUI R0 $process_do_string7 ; Our end label string
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	CALLI R15 @restore_break_frame ; Restore break frame
+	POPR R0 R15                 ; Restore R0
+	POPR R1 R15                 ; Restore R1
+	POPR R2 R15                 ; Restore R2
+	RET R15
+
+:process_do_string0
+	"DO_END_"
+:process_do_string1
+	":DO_"
+:process_do_string2
+	"ERROR in process_do
+MISSING while
+"
+:process_do_string3
+	"ERROR in process_do
+MISSING (
+"
+:process_do_string4
+	"ERROR in process_do
+MISSING )
+"
+:process_do_string5
+	"ERROR in process_do
+MISSING ;
+"
+:process_do_string6
+	"JUMP.NZ R0 @DO_"
+:process_do_string7
+	":DO_END_"
+
+
+;; process_while function
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:process_while
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R0 R15                ; Protect R0
+	CALLI R15 @save_break_frame ; Save break frame
+
+	LOADR32 R0 @current_count   ; Using CURRENT_COUNT
+	ADDUI R1 R0 1               ; CURRENT_COUNT = CURRENT_COUNT + 1
+	STORER32 R1 @current_count  ; Update CURRENT_COUNT
+	CALLI R15 @numerate_number  ; Convert to string
+	COPY R2 R0                  ; Protect NUMBER_STRING
+
+	LOADUI R1 $process_while_string0 ; Set HEAD
+	CALLI R15 @set_break_frame ; Set the break frame values
+
+	LOADUI R0 $process_while_string1 ; Our head label
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $process_while_string2 ; Our first error message
+	LOADUI R1 $open_paren       ; Using "("
+	CALLI R15 @require_match    ; Check for match
+	CALLI R15 @expression       ; Collect test expression
+
+	LOADUI R0 $process_while_string3 ; Our test and jump
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+	LOADUI R0 $process_while_string4 ; Our trailing comment
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	LOADUI R0 $process_while_string5 ; Our first error message
+	LOADUI R1 $close_paren      ; Using ")"
+	CALLI R15 @require_match    ; Check for match
+	CALLI R15 @statement        ; Collect our loop statement
+
+	LOADUI R0 $process_while_string6 ; Our test and jump
+	CALLI R15 @emit_out         ; emit it
+	COPY R1 R2                  ; Using NUMBER_STRING
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+	LOADUI R0 $process_while_string7 ; Our trailing comment
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R0 R9 8              ; FUNCTION->S
+	CALLI R15 @uniqueID_out     ; emit it
+
+	CALLI R15 @restore_break_frame ; Restore break frame
+	POPR R0 R15                 ; Restore R0
+	POPR R1 R15                 ; Restore R1
+	POPR R2 R15                 ; Restore R2
+	RET R15
+
+:process_while_string0
+	"END_WHILE_"
+:process_while_string1
+	":WHILE_"
+:process_while_string2
+	"ERROR in process_while
+MISSING (
+"
+:process_while_string3
+	"JUMP.Z R0 @END_WHILE_"
+:process_while_string4
+	"# THEN_while_"
+:process_while_string5
+	"ERROR in process_while
+MISSING )
+"
+:process_while_string6
+	"JUMP @WHILE_"
+:process_while_string7
+	":END_WHILE_"
+
+
+;; return_result function
+;; Receives nothing
+;; Returns nothing
+;;	and struct token_list* FUNC in R9
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+:return_result
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.E R0 59            ; IF GLOBAL_TOKEN->S[0] == ';'
+	CALLI R15 @expression       ; Evaluate expression
+
+	LOADUI R0 $return_result_string0 ; Using or error message
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Require a match to ";"
+
+	LOADUI R0 $return_result_string1 ; Our pop command
+	LOAD32 R1 R9 4              ; FUNCTION->LOCALS
+
+:return_result_iter
+	JUMP.Z R1 @return_result_done ; Be done when we hit NULL
+	CALLI R15 @emit_out         ; Put the string every iteration
+	LOAD32 R1 R1 0              ; I = I->NEXT
+	JUMP @return_result_iter    ; Keep looping
+
+:return_result_done
+	LOADUI R0 $return_result_string2 ; Our footer
+	CALLI R15 @emit_out         ; emit it
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:return_result_string0
+	"ERROR in return_result
+MISSING ;
+"
+:return_result_string1
+	"POPR R1 R15	# _return_result_locals
+"
+:return_result_string2
+	"RET R15
+"
+
+
+;; process_break function
+;; Receives nothing
+;;	and struct token_list* FUNC in R9
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:process_break
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOADR32 R0 @break_target_head ; BREAK_TARGET_HEAD
+	JUMP.NZ R0 @process_break_NON_NULL
+
+	;; Deal with NULL == BREAK_TARGET_HEAD
+	LOADUI R0 $process_break_string0 ; Our first error message
+	FALSE R1                    ; Write for User
+	CALLI R15 @file_print       ; write it
+	CALLI R15 @line_error       ; Give useful info
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @file_print       ; Print it
+	HALT
+
+:process_break_NON_NULL
+	LOADR32 R2 @break_frame     ; BREAK_FRAME
+	LOAD32 R1 R9 4              ; I = FUNCTION->LOCALS
+	LOADUI R0 $process_break_string1 ; Our pop string
+
+:process_break_iter
+	CMPJUMPI.E R1 R2 @process_break_done ; IF I == BREAK_FRAME
+	JUMP.Z R1 @process_break_done ; IF NULL == I break
+	CALLI R15 @emit_out         ; emit pop
+	LOAD32 R1 R1 0              ; I = I->NEXT
+	JUMP @process_break_iter    ; Loop
+
+:process_break_done
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $process_break_string2 ; Our jump string
+	CALLI R15 @emit_out         ; emit it
+	LOADR32 R0 @break_target_head ; Our HEAD string
+	CALLI R15 @emit_out         ; emit it
+	LOADR32 R0 @break_target_func ; Our FUNC string
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $underline        ; Using "_"
+	CALLI R15 @emit_out         ; emit it
+	LOADR32 R0 @break_target_num ; Our NUM string
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $process_break_string3 ; Our final error string
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Make sure we get that match
+
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:process_break_string0
+	"Not inside of a loop or case statement
+"
+:process_break_string1
+	"POPR R1 R15	# break_cleanup_locals
+"
+:process_break_string2
+	"JUMP @"
+:process_break_string3
+	"ERROR in break statement
+Missing ;
+"
+
+:break_frame
+	NOP
+:break_target_head
+	NOP
+:break_target_func
+	NOP
+:break_target_num
+	NOP
+
+
+;; process_asm function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:process_asm
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	;; First required match
+	LOADUI R0 $process_asm_string0 ; Using our First error message
+	LOADUI R1 $open_paren       ; Using "("
+	CALLI R15 @require_match    ; Make sure of our required match
+
+:process_asm_iter
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.E R0 34            ; IF GLOBAL_TOKEN->S[0] == '"'
+	JUMP @process_asm_done      ; Otherwise be done
+
+	;; Add block of assembly
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	ADDUI R0 R0 1               ; GLOBAL_TOKEN->S + 1
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	JUMP @process_asm_iter
+
+:process_asm_done
+	LOADUI R0 $process_asm_string1 ; Using our First error message
+	LOADUI R1 $close_paren      ; Using ")"
+	CALLI R15 @require_match    ; Make sure of our required match
+
+	LOADUI R0 $process_asm_string2 ; Using our First error message
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Make sure of our required match
+
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:process_asm_string0
+	"ERROR in process_asm
+MISSING (
+"
+:process_asm_string1
+	"ERROR in process_asm
+MISSING )
+"
+:process_asm_string2
+	"ERROR in process_asm
+MISSING ;
+"
+
+
+;; recursive_statement function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:recursive_statement
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOAD32 R3 R9 4              ; FRAME = FUNCTION->LOCALS
+:recursive_statement_iter
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	LOADUI R0 $close_curly_brace ; '}'
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "}"
+	JUMP.NZ R0 @recursive_statement_cleanup
+
+	;; Lets collect those statements
+	CALLI R15 @statement        ; Collect next statement
+	JUMP @recursive_statement_iter ; Iterate
+
+:recursive_statement_cleanup
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOAD32 R1 R12 8             ; OUT->S
+	LOADUI R0 $recursive_statement_string0 ; "RET R15\n"
+	CALLI R15 @match            ; IF OUT->S == "RET R15\n"
+	JUMP.NZ R0 @recursive_statement_done ; Save some work
+
+	;; Lets pop them all off
+	LOAD32 R2 R9 4              ; FUNC->LOCALS
+	LOADUI R0 $recursive_statement_string1 ; Our POP string
+:recursive_statement_pop
+	CMPJUMPI.E R2 R3 @recursive_statement_done
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R2 R2 0              ; I = I->NEXT
+	JUMP.NZ R2 @recursive_statement_pop ; Keep looping
+
+:recursive_statement_done
+	STORE32 R3 R9 4             ; FUNC->LOCALS = FRAME
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:recursive_statement_string0
+	"RET R15
+"
+:recursive_statement_string1
+	"POPR R1 R15	# _recursive_statement_locals
+"
+
+
+;; statement function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:statement
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOAD32 R2 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R2 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.E R0 123           ; If GLOBAL_TOKEN->S[0] != '{'
+	JUMP @statement_label       ; Try next match
+
+	;; Deal with { statements }
+	CALLI R15 @recursive_statement
+	JUMP @statement_done        ; All done
+
+:statement_label
+	CMPSKIPI.E R0 58            ; If GLOBAL_TOKEN->S[0] != ':'
+	JUMP @statement_collect_local ; Try next match
+
+	;; Deal with :label
+	LOAD32 R0 R13 8             ; Using GLOBAL_TOKEN->S
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $statement_string0 ; Using label string
+	CALLI R15 @emit_out         ; emit it
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	JUMP @statement_done        ; Move on to next thing
+
+:statement_collect_local
+	LOADUI R0 $struct           ; Using "struct"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "struct"
+	JUMP.NZ R0 @statement_collect_local_0
+
+	;; Otherwise check if it is a primitive
+	LOADUI R0 $prim_types       ; Using the Primitive types list
+	SWAP R0 R1                  ; Put in correct order
+	CALLI R15 @lookup_type      ; Check if a primitive type
+	JUMP.Z R0 @statement_process_if ; If not try the next one
+
+:statement_collect_local_0
+	CALLI R15 @collect_local    ; Collect the local
+	JUMP @statement_done        ; And move on
+
+:statement_process_if
+	LOADUI R0 $if_string        ; Using "if"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "if"
+	JUMP.Z R0 @statement_process_do
+	CALLI R15 @process_if       ; Collect that if statement
+	JUMP @statement_done        ; Move on to next thing
+
+:statement_process_do
+	LOADUI R0 $do_string        ; Using "do"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "do"
+	JUMP.Z R0 @statement_process_while
+	CALLI R15 @process_do       ; Collect that do statement
+	JUMP @statement_done        ; Move on to next thing
+
+:statement_process_while
+	LOADUI R0 $while_string     ; Using "while"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "while"
+	JUMP.Z R0 @statement_process_for
+	CALLI R15 @process_while    ; Collect that while statement
+	JUMP @statement_done        ; Move on to next thing
+
+:statement_process_for
+	LOADUI R0 $for_string       ; Using "for"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "for"
+	JUMP.Z R0 @statement_process_asm
+	CALLI R15 @process_for      ; Collect that FOR statement
+	JUMP @statement_done        ; Move on to next thing
+
+:statement_process_asm
+	LOADUI R0 $asm_string       ; Using "asm"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "asm"
+	JUMP.Z R0 @statement_goto
+	CALLI R15 @process_asm      ; Collect that ASM statement
+	JUMP @statement_done        ; Move on to next thing
+
+:statement_goto
+	LOADUI R0 $goto_string      ; Using "goto"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "goto"
+	JUMP.Z R0 @statement_return_result
+
+	;; Deal with goto label:
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $statement_string1 ; Using our JUMP string
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $newline          ; "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	LOADUI R0 $statement_string2 ; Using our error message
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Make sure of our required match
+	JUMP @statement_done        ; Move on
+
+:statement_return_result
+	LOADUI R0 $return_string    ; Using "return"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "return"
+	JUMP.Z R0 @statement_break
+
+	;; Deal with return statements in functions
+	CALLI R15 @return_result    ; Do all of the work
+	JUMP @statement_done        ; Move on to next
+
+:statement_break
+	LOADUI R0 $break_string     ; Using "break"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "break"
+	JUMP.Z R0 @statement_continue
+
+	;; Let break function deal with updating out
+	CALLI R15 @process_break    ; Do all the work
+	JUMP @statement_done        ; Move on to next
+
+:statement_continue
+	LOADUI R0 $continue_string  ; Using "continue"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "continue"
+	JUMP.Z R0 @statement_expression
+
+	;; Simple Continue compatibility
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	LOADUI R0 $statement_string3 ; Using our continue comment string
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $statement_string2 ; Using our error message
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Make sure of our required match
+	JUMP @statement_done        ; Move on
+
+:statement_expression
+	CALLI R15 @expression       ; Do expression evaluation
+	LOADUI R0 $statement_string2 ; Load our error message
+	LOADUI R1 $semicolon        ; use ";"
+	CALLI R15 @require_match    ; Make sure GLOBAL_TOKEN-> == ";"
+
+:statement_done
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:statement_string0
+	"	#C goto label
+"
+:statement_string1
+	"JUMP @"
+:statement_string2
+	"ERROR in statement
+MISSING ;
+"
+:statement_string3
+	"
+#continue statement
+"
+
+
+;; collect_local function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:collect_local
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	CALLI R15 @type_name        ; Get it's type
+	MOVE R1 R0                  ; Prepare for call
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOAD32 R2 R9 4              ; FUNC->LOCALS
+	CALLI R15 @sym_declare      ; SET A
+	MOVE R2 R0                  ; Protect A
+
+	;; Figure out depth
+	LOADUI R0 $main_string      ; Using "main"
+	LOAD32 R1 R9 8              ; FUNC->S
+	CALLI R15 @match            ; IF FUNC->S == "main"
+	JUMP.Z R0 @collect_local_0  ; Try next
+	LOAD32 R0 R9 4              ; FUNC->LOCALS
+	JUMP.NZ R0 @collect_local_0 ; Try next
+
+	LOADI R0 20                 ; The default depth for main
+	STORE32 R0 R2 16            ; A->DEPTH = 20
+	JUMP @collect_local_output  ; Deal with header
+
+:collect_local_0
+	LOAD32 R0 R9 16             ; FUNC->ARGS
+	JUMP.NZ R0 @collect_local_1 ; Try Next
+	LOAD32 R0 R9 4              ; FUNC->LOCALS
+	JUMP.NZ R0 @collect_local_1 ; Try Next
+
+	LOADI R0 4                  ; The default depth for foo()
+	STORE32 R0 R2 16            ; A->DEPTH = 4
+	JUMP @collect_local_output  ; Deal with header
+
+:collect_local_1
+	LOAD32 R0 R9 4              ; FUNC->LOCALS
+	JUMP.NZ R0 @collect_local_2 ; Try Next
+
+	LOAD32 R0 R9 16             ; FUNC->ARGS
+	LOAD32 R0 R0 16             ; FUNC->ARGS->DEPTH
+	ADDI R0 R0 8                ; DEPTH = FUNC->ARGS->DEPTH + 8
+	STORE32 R0 R2 16            ; A->DEPTH = DEPTH
+	JUMP @collect_local_output  ; Deal with header
+
+:collect_local_2
+	LOAD32 R0 R9 4              ; FUNC->LOCALS
+	LOAD32 R0 R0 16             ; FUNC->LOCALS->DEPTH
+	ADDI R0 R0 4                ; DEPTH = FUNC->LOCALS->DEPTH + 4
+	STORE32 R0 R2 16            ; A->DEPTH = DEPTH
+
+:collect_local_output
+	STORE32 R2 R9 4             ; FUNC->LOCALS = A
+
+	;; Output header
+	LOADUI R0 $collect_local_string0 ; Starting with the comment
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R0 R2 8              ; A->S
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+
+	;; Deal with possible assignment
+	LOADUI R0 $equal            ; Using "="
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "="
+	JUMP.Z R0 @collect_local_nonassign
+
+	;; Deal with assignment of the local
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	CALLI R15 @expression       ; Update OUT with the evaluation of the Expression
+
+:collect_local_nonassign
+	LOADUI R0 $collect_local_string1 ; Our error message
+	LOADUI R1 $semicolon        ; Using ";"
+	CALLI R15 @require_match    ; Make sure GLOBAL_TOKEN->S == ";"
+
+	;; Final Footer
+	LOADUI R0 $collect_local_string2 ; Add our PUSH statement
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R0 R2 8              ; A->S
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:collect_local_string0
+	"# Defining local "
+:collect_local_string1
+	"ERROR in collect_local
+Missing ;
+"
+:collect_local_string2
+	"PUSHR R0 R15	#"
+
+
+;; collect_arguments function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:collect_arguments
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+:collect_arguments_iter
+	LOADUI R0 $close_paren      ; Using ")"
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == ")"
+	JUMP.NZ R0 @collect_arguments_done ; Be done
+
+	;; Collect the arguments
+	CALLI R15 @type_name        ; Get what type we are working with
+	MOVE R1 R0                  ; Put TYPE where it will be used
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.NE R0 41           ; IF GLOBAL_TOKEN->S[0] == ')'
+	JUMP @collect_arguments_iter3 ; foo(int,char,void) doesn't need anything done
+
+	;; Check for foo(int a,...)
+	CMPSKIPI.NE R0 41           ; IF GLOBAL_TOKEN->S[0] == ','
+	JUMP @collect_arguments_iter3 ; Looks like final case
+
+	;; Deal with foo(int a, ...)
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOAD32 R2 R9 16             ; FUNC->ARGUMENTS
+	CALLI R15 @sym_declare      ; Get A
+	MOVE R2 R0                  ; Get A out of the way
+
+:collect_arguments_func
+	LOAD32 R0 R9 16             ; FUNC->ARGS
+	JUMP.Z R0 @collect_arguments_func_0 ; IF NULL == FUNC->ARGS then FUNC->ARGS->DEPTH = 0
+	LOAD32 R0 R0 16             ; FUNC->ARGS->DEPTH
+	ADDI R0 R0 4                ; FUNC->ARGS->DEPTH + 4
+:collect_arguments_func_0
+	STORE32 R0 R2 16            ; A->DEPTH = VALUE
+
+:collect_arguments_iter2
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	STORE32 R2 R9 16            ; FUNC->ARGUMENTS = A
+
+:collect_arguments_iter3
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.NE R0 44           ; IF GLOBAL_TOKEN->S[0] == ','
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	JUMP @collect_arguments_iter ; Keep looping
+
+:collect_arguments_done
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+
+;; declare_function function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	and struct token_list* global_list in R10
+;; SETS R9 to struct token_list* FUNC
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:declare_function
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	FALSE R0                    ; Using Zero
+	STORER32 R0 @current_count  ; CURRENT_COUNT = 0
+	LOAD32 R0 R13 4             ; GLOBAL_TOKEN->PREV
+	LOAD32 R0 R0 8              ; GLOBAL_TOKEN->PREV->S
+	FALSE R1                    ; Passing NULL
+	LOADR32 R2 @global_function_list ; where the global function list is located
+	CALLI R15 @sym_declare      ; declare FUNC
+	STORER32 R0 @global_function_list ; GLOBAL_FUNCTION_LIST = FUNC
+	MOVE R9 R0                  ; SETS FUNC
+	CALLI R15 @collect_arguments ; Collect function arguments
+	LOAD32 R2 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R2 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.NE R0 59           ; IF GLOBAL_TOKEN->S[0] == ';'
+	JUMP @declare_function_prototype ; Don't waste time
+
+	;; Looks like it is an actual function definition
+	LOADUI R0 $declare_function_string0 ; Using first string
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R0 R9 8              ; Using FUNC->S
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $declare_function_string1 ; Using second string
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R0 R9 8              ; Using FUNC->S
+	CALLI R15 @emit_out         ; emit it
+
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+
+:declare_function_nonmain
+	FALSE R1                    ; Cleaning up before call
+	CALLI R15 @statement        ; Collect the statement
+
+	;; Prevent Duplicate Returns
+	LOAD32 R1 R12 8             ; OUT->S
+	LOADUI R0 $declare_function_string2 ; Our final string
+	CALLI R15 @match            ; Check for Match
+	JUMP.NZ R0 @declare_function_done ; Clean up
+
+	;; Deal with adding the return
+	LOADUI R0 $declare_function_string2 ; Our final string
+	CALLI R15 @emit_out         ; emit it
+
+:declare_function_done
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:declare_function_prototype
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	JUMP @declare_function_done ; Clean up
+
+:declare_function_string0
+	"# Defining function "
+:declare_function_string1
+	":FUNCTION_"
+:declare_function_string2
+	"RET R15
+"
+
+:current_count
+	NOP
+
+
+;; program function
+;; Receives struct token_list* global_token in R13,
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	and struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:program
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+:program_iter
+	JUMP.Z R13 @program_done    ; Looks like we read all the tokens
+	LOADUI R0 $constant         ; Using the constant string
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; Check if they match
+	JUMP.Z R0 @program_type     ; Looks like not
+
+	;; Deal with CONSTANT case
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	FALSE R1                    ; Set NULL
+	LOADR32 R2 @global_constant_list ; GLOBAL_CONSTANTS_LIST
+	CALLI R15 @sym_declare      ; Declare the global constant
+	STORER32 R0 @global_constant_list ; Update global constant
+
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	STORE32 R13 R0 16           ; GLOBAL_CONSTANT_LIST->ARGUMENTS = GLOBAL_TOKEN
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	JUMP @program_iter          ; Loop again
+
+:program_type
+	CALLI R15 @type_name        ; Get the type
+	JUMP.Z R0 @program_iter     ; If newly defined type iterate
+
+	;; Looks like we got a defined type
+	MOVE R1 R0                  ; Put the type where it can be used
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADUI R3 $global_symbol_list ; Get address of global symbol list
+	LOAD32 R2 R3 0              ; GLOBAL_SYMBOLS_LIST
+	CALLI R15 @sym_declare      ; Declare that global symbol
+	STORE32 R0 R3 0             ; Update global symbol list
+
+	LOAD32 R3 R13 8             ; GLOBAL_TOKEN->S
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $semicolon        ; Get semicolon string
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; Check if they match
+	JUMP.Z R0 @program_function ; If not a match
+
+	;; Deal with case of TYPE NAME;
+	COPY R1 R10                 ; Using GLOBALS_LIST
+	LOADUI R0 $program_string0  ; Using the GLOBAL_ prefix
+	CALLI R15 @emit             ; emit it
+	MOVE R1 R0                  ; Move new GLOBALS_LIST into Place
+	MOVE R0 R3                  ; Use GLOBAL_TOKEN->PREV->S
+	CALLI R15 @emit             ; emit it
+	MOVE R1 R0                  ; Move new GLOBALS_LIST into Place
+	LOADUI R0 $program_string1  ; Using the NOP postfix
+	CALLI R15 @emit             ; emit it
+	MOVE R10 R0                 ; Move new GLOBALS_LIST into Place
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	JUMP @program_iter
+
+:program_function
+	LOADUI R0 $open_paren       ; Get open paren string
+	CALLI R15 @match            ; Check if they match
+	JUMP.Z R0 @program_assign   ; If not a match
+
+	;; Deal with case of TYPE NAME(...)
+	CALLI R15 @declare_function
+	JUMP @program_iter
+
+:program_assign
+	LOADUI R0 $equal            ; Get equal string
+	CALLI R15 @match            ; Check if they match
+	JUMP.Z R0 @program_error    ; If not a match
+	COPY R1 R10                 ; Using GLOBALS_LIST
+	LOADUI R0 $program_string0  ; Using the GLOBAL_ prefix
+	CALLI R15 @emit             ; emit it
+	MOVE R1 R0                  ; Move new GLOBALS_LIST into Place
+	MOVE R0 R3                  ; Use GLOBAL_TOKEN->PREV->S
+	CALLI R15 @emit             ; emit it
+	MOVE R1 R0                  ; Move new GLOBALS_LIST into Place
+	LOADUI R0 $newline          ; Using the Newline postfix
+	CALLI R15 @emit             ; emit it
+	MOVE R10 R0                 ; Update GLOBALS_LIST
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	LOADUI R1 $digit_chars      ; 0-9
+	CALLI R15 @in_set           ; Figure out if in set
+	JUMP.Z R0 @program_assign_string ; If not in sets
+
+	;; Looks like we have an int
+	COPY R1 R10                 ; Using GLOBALS_LIST
+	LOADUI R0 $percent          ; Using percent prefix
+	CALLI R15 @emit             ; emit it
+	MOVE R1 R0                  ; Put GLOBALS_LIST into Place
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @emit             ; emit it
+	MOVE R1 R0                  ; Put GLOBALS_LIST into Place
+	LOADUI R0 $newline          ; Using newline postfix
+	CALLI R15 @emit             ; emit it
+	MOVE R10 R0                 ; Update GLOBALS_LIST
+	JUMP @program_assign_done   ; Move on
+
+:program_assign_string
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.E R0 34            ; If GLOBAL_TOKEN->S[0] == '"'
+	JUMP @program_error         ; If not we hit an error
+
+	;; Looks like we have a string
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @parse_string     ; Parse it into useful form
+	COPY R1 R10                 ; GLOBALS_LIST
+	CALLI R15 @emit             ; emit it
+	MOVE R10 R0                 ; Update GLOBALS_LIST
+
+:program_assign_done
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $program_string4  ; Potential error message
+	LOADUI R1 $semicolon        ; Checking for ;
+	CALLI R15 @require_match    ; Catch those errors
+	JUMP @program_iter
+
+:program_error
+	LOADUI R0 $program_string2  ; message part 1
+	FALSE R1                    ; Show to user
+	CALLI R15 @file_print       ; write
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @file_print       ; write
+	LOADUI R0 $program_string3  ; message part 2
+	CALLI R15 @file_print       ; write
+	CALLI R15 @line_error       ; Provide a meaningful error message
+	HALT
+
+:program_done
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:program_string0
+	":GLOBAL_"
+:program_string1
+	"
+NULL
+"
+:program_string2
+	"Received "
+:program_string3
+	" in program
+"
+:program_string4
+"ERROR in Program
+Missing ;
+"
+
+
+;; sym_declare function
+;; Receives char* in R0, struct type* in R1, struct token_list* in R2
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns struct token_list* in R0
+:sym_declare
+	STORE32 R2 R14 0            ; A->NEXT = LIST
+	STORE32 R0 R14 8            ; A->S = S
+	STORE32 R1 R14 12           ; A->TYPE = T
+	ADDUI R0 R14 20             ; CALLOC struct token_list
+	SWAP R0 R14                 ; Prepare for Return
+	RET R15
+
+
+;; sym_lookup function
+;; Receives char* in R0 and struct token_list in R1
+;; Returns struct token_list* or NULL in R0
+:sym_lookup
+	PUSHR R2 R15                ; Protect R2
+	MOVE R2 R1                  ; Protect I
+	MOVE R1 R0                  ; Put S in proper place
+:sym_lookup_iter
+	JUMP.Z R2 @sym_lookup_done  ; Stop if NULL
+	LOAD32 R0 R2 8              ; I->S
+	CALLI R15 @match            ; if I->S == S
+	JUMP.NZ R0 @sym_lookup_done ; Stop if match
+	LOAD32 R2 R2 0              ; I = I->NEXT
+	JUMP @sym_lookup_iter       ; Keep looping
+
+:sym_lookup_done
+	MOVE R0 R2                  ; Using R2 as our result
+	POPR R2 R15                 ; Restore R2
+	RET R15
+
+
+;; function_call function
+;; Receives CHAR* S in R0 and INT BOOL in R1
+;;	struct token_list* out in R12,
+;;	struct token_list* string_list in R11
+;;	and struct token_list* global_list in R10
+;;	and struct token_list* FUNC in R9
+;;	and struct token_list* current_target in R8
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns the token_lists modified
+:function_call
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+	MOVE R2 R0                  ; Protect S
+	MOVE R3 R1                  ; Protect BOOL
+
+	LOADUI R0 $function_call_string0 ; Our first error message
+	LOADUI R1 $open_paren       ; Using "("
+	CALLI R15 @require_match    ; Make sure of a match
+
+	FALSE R4                    ; PASSED = 0
+	LOADUI R0 $function_call_string1 ; Our first header
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $function_call_string2 ; Our second header
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $function_call_string3 ; Our third header
+	CALLI R15 @emit_out         ; emit it
+
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.NE R0 41           ; IF GLOBAL_TOKEN->S[0] != ')'
+	JUMP @function_call_collect_done ; looks like function()
+
+	;; Collect arguments
+	CALLI R15 @expression       ; Deal with first argument
+	LOADUI R0 $function_call_string4 ; Push it onto stack
+	CALLI R15 @emit_out         ; emit it
+	ADDUI R4 R4 1               ; PASSED = 1
+
+:function_call_collect_iter
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.E R0 44            ; IF GLOBAL_TOKEN->S[0] != ','
+	JUMP @function_call_collect_done ; looks like we are done collecting arguments
+
+	;; Collect another argument
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	CALLI R15 @expression       ; Deal with Nth argument
+	LOADUI R0 $function_call_string5 ; Push it onto stack
+	CALLI R15 @emit_out         ; emit it
+	ADDUI R4 R4 1               ; PASSED = PASSED + 1
+	JUMP @function_call_collect_iter ; Keep looping
+
+:function_call_collect_done
+	LOADUI R0 $function_call_string6 ; Our second error message
+	LOADUI R1 $close_paren      ; Using ")"
+	CALLI R15 @require_match    ; Make sure of a match
+
+	JUMP.Z R3 @function_call_call_false ; if BOOL != TRUE
+
+	;; Deal with TRUE == BOOL
+	LOADUI R0 $function_call_string7 ; Our first prefix
+	CALLI R15 @emit_out         ; emit it
+	MOVE R0 R2                  ; Using S
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $function_call_string8 ; Our first postfix
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $function_call_string9 ; Our second postfix
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $function_call_string10 ; Our last postfix
+	CALLI R15 @emit_out         ; emit it
+	JUMP @function_call_call_done ; Move on
+
+:function_call_call_false
+	;; Deal with FALSE == BOOL
+	LOADUI R0 $function_call_string11 ; Our first prefix
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $function_call_string12 ; Our last prefix
+	CALLI R15 @emit_out         ; emit it
+	MOVE R0 R2                  ; Using S
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $function_call_string16 ; The terminator
+	CALLI R15 @emit_out         ; emit it
+
+:function_call_call_done
+	LOADUI R0 $function_call_string13 ; Our POP
+
+:function_call_pop_iter
+	JUMP.Z R4 @function_call_pop_done ; Skip POP if out of args on Stack
+	CALLI R15 @emit_out         ; emit our POP
+	SUBI R4 R4 1                ; PASSED = PASSED - 1
+	JUMP @function_call_pop_iter ; Loop
+
+:function_call_pop_done
+	LOADUI R0 $function_call_string14 ; Our first postfix
+	CALLI R15 @emit_out         ; emit it
+	LOADUI R0 $function_call_string15 ; Our final postfix
+	CALLI R15 @emit_out         ; emit it
+
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:function_call_string0
+	"ERROR in process_expression_list
+No ( was found
+"
+:function_call_string1
+	"PUSHR R13 R15	# Prevent overwriting in recursion
+"
+:function_call_string2
+	"PUSHR R14 R15	# Protect the old base pointer
+"
+:function_call_string3
+	"COPY R13 R15	# Copy new base pointer
+"
+:function_call_string4
+	"PUSHR R0 R15	#_process_expression1
+"
+:function_call_string5
+	"PUSHR R0 R15	#_process_expression2
+"
+:function_call_string6
+	"ERROR in process_expression_list
+No ) was found
+"
+:function_call_string7
+	"LOAD R0 R14 "
+:function_call_string8
+	"
+"
+:function_call_string9
+	"MOVE R14 R13
+"
+:function_call_string10
+	"CALL R0 R15
+"
+:function_call_string11
+	"MOVE R14 R13
+"
+:function_call_string12
+	"LOADR R0 4
+JUMP 4
+&FUNCTION_"
+:function_call_string13
+	"POPR R1 R15	# _process_expression_locals
+"
+:function_call_string14
+	"POPR R14 R15	# Restore old base pointer
+"
+:function_call_string15
+	"POPR R13 R15	# Prevent overwrite
+"
+:function_call_string16
+	"
+CALL R0 R15
+"
+
+
+;; emit function
+;; Receives char* in R0, struct token_list* in R1
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns struct token_list* in R0
+:emit
+	PUSHR R2 R15                ; Protect R2
+	COPY R2 R14                 ; Pointer to T
+	ADDUI R14 R14 20            ; CALLOC struct token_list
+	STORE32 R1 R2 0             ; T->NEXT = HEAD
+	STORE32 R0 R2 8             ; T->S = S
+	MOVE R0 R2                  ; Put T in proper spot for return
+	POPR R2 R15                 ; Restore R2
+	RET R15
+
+
+;; emit_out function
+;; Receives char* in R0
+;;	struct token_list* out in R12,
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns struct token_list* in R0
+:emit_out
+	STORE32 R12 R14 0           ; T->NEXT = OUT
+	ADDUI R12 R14 20            ; Get T
+	SWAP R12 R14                ; CALLOC struct token_list
+	STORE32 R0 R12 8            ; T->S = S
+	RET R15
+
+
+;; uniqueID function
+;; Receives char* in R0, struct token_list* in R1 and char* in R2
+;; Calls emit repeatedly
+;; Returns struct token_list* in R0
+:uniqueID
+	CALLI R15 @emit             ; emit S
+
+	MOVE R1 R0                  ; Put L in the correct place
+	LOADUI R0 $underline        ; Using "_"
+	CALLI R15 @emit             ; emit it
+
+	MOVE R1 R0                  ; Put L in the correct place
+	COPY R0 R2                  ; Put NUM in the correct place
+	CALLI R15 @emit             ; emit NUM
+
+	MOVE R1 R0                  ; Put L in the correct place
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit             ; emit it
+	RET R15
+
+
+;; uniqueID_out function
+;; Receives char* in R0, char* in R1
+;; Calls emit_out repeatedly
+;; Returns nothing
+:uniqueID_out
+	CALLI R15 @emit_out         ; emit S
+
+	LOADUI R0 $underline        ; Using "_"
+	CALLI R15 @emit_out         ; emit it
+
+	COPY R0 R1                  ; Put NUM in the correct place
+	CALLI R15 @emit_out         ; emit NUM
+
+	LOADUI R0 $newline          ; Using "\n"
+	CALLI R15 @emit_out         ; emit it
+	RET R15
+
+
+;; file_print function
+;; Receives pointer to string in R0 and FILE* in R1
+;; Returns nothing
+:file_print
+	PUSHR R2 R15                ; Protect R2 from Overwrite
+	MOVE R2 R0                  ; Put string pointer into place
+:file_print_read
+	LOAD8 R0 R2 0               ; Get a char
+	JUMP.Z R0 @file_print_done  ; If NULL be done
+	FPUTC                       ; Write the Char
+	ADDUI R2 R2 1               ; Point at next CHAR
+	JUMP @file_print_read       ; Loop again
+:file_print_done
+	POPR R2 R15                 ; Restore R2
+	RET R15
+
+
+;; recursive_output function
+;; Receives token_list in R0 and FILE* in R1
+;; Returns nothing and alters nothing
+:recursive_output
+	JUMP.Z R0 @recursive_output_abort ; Abort if NULL
+	PUSHR R2 R15                ; Preserve R2 from recursion
+	MOVE R2 R0                  ; Preserve R0 from recursion
+	LOAD32 R0 R2 0              ; Using I->NEXT
+	CALLI R15 @recursive_output ; Recurse
+	LOAD32 R0 R2 8              ; Using I->S
+	CALLI R15 @file_print       ; Write the string
+	MOVE R0 R2                  ; Put R0 back
+	POPR R2 R15                 ; Restore R0
+:recursive_output_abort
+	RET R15
+
+
+;; match function
+;; Receives a CHAR* in R0, CHAR* in R1
+;; Returns Bool in R0 indicating if strings match
+:match
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+	MOVE R2 R0                  ; Put First string in place
+	MOVE R3 R1                  ; Put Second string in place
+	LOADUI R4 0                 ; Set initial index of 0
+:match_cmpbyte
+	LOADXU8 R0 R2 R4            ; Get a byte of our first string
+	LOADXU8 R1 R3 R4            ; Get a byte of our second string
+	ADDUI R4 R4 1               ; Prep for next loop
+	CMPSKIP.NE R1 R0            ; Compare the bytes
+	JUMP.NZ R1 @match_cmpbyte   ; Loop if bytes are equal
+;; Done
+	FALSE R2                    ; Default answer
+	CMPSKIP.NE R0 R1            ; If ended loop with everything matching
+	TRUE R2                     ; Set as TRUE
+	MOVE R0 R2                  ; Prepare for return
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; lookup_type function
+;; Receives a CHAR* in R0 and struct type* in R1
+;; Returns struct type* in R0 or NULL if no match
+:lookup_type
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	MOVE R2 R1                  ; Put START in correct place
+	MOVE R1 R0                  ; Put S in correct place
+:lookup_type_iter
+	LOAD32 R0 R2 24             ; Get I->NAME
+	CALLI R15 @match            ; Check if I->NAME == S
+	JUMP.NZ R0 @lookup_type_done ; If match found be done
+	LOAD32 R2 R2 0              ; I = I->NEXT
+	JUMP.NZ R2 @lookup_type_iter ; Otherwise iterate until I == NULL
+:lookup_type_done
+	MOVE R0 R2                  ; Our answer (I or NULL)
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; lookup_member function
+;; Receives struct type* parent in R0 and char* name in R1
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+	;; Returns struct type* of member in R0 or aborts with error
+:lookup_member
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	LOAD32 R3 R0 24             ; PARENT->NAME for error
+	MOVE R2 R0                  ; I = PARENT
+:lookup_member_iter
+	LOAD32 R2 R2 16             ; I = I->MEMBERS
+	JUMP.Z R2 @lookup_member_error ; We failed hard
+	LOAD32 R0 R2 24             ; I->NAME
+	CALLI R15 @match            ; IF I->NAME == NAME
+	JUMP.Z R0 @lookup_member_iter ; Loop again
+
+:lookup_member_done
+	MOVE R0 R2                  ; Put I in the correct place
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+:lookup_member_error
+	FALSE R1                    ; Write to TTY
+	LOADUI R0 $lookup_member_string0 ; Our header string
+	CALLI R15 @file_print       ; Print it
+	MOVE R0 R3                  ; Using PARENT->NAME
+	CALLI R15 @file_print       ; Print it
+	LOADUI R0 $arrow_string     ; Using "->"
+	CALLI R15 @file_print       ; Print it
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @file_print       ; Print it
+	LOADUI R0 $lookup_member_string1 ; Our footer string
+	CALLI R15 @file_print       ; Print it
+	CALLI R15 @line_error       ; Give line info
+	LOADUI R0 $newline          ; Our final addition
+	CALLI R15 @file_print       ; Print it
+	HALT
+
+:lookup_member_string0
+	"ERROR in lookup_member "
+:lookup_member_string1
+	" does not exist
+"
+
+
+;; build_member function
+;; Receives a struct type* in R0, int in R1 and int in R2
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Modifies R2 to current member_size
+;; Returns struct type* in R0
+:build_member
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+	PUSHR R5 R15                ; Protect R5
+	PUSHR R6 R15                ; Protect R6
+	MOVE R6 R1                  ; Protect OFFSET
+	MOVE R4 R0                  ; Protect LAST
+	CALLI R15 @type_name        ; Get MEMBER_TYPE
+	MOVE R5 R0                  ; Protect MEMBER_TYPE
+	ADDUI R3 R14 28             ; CALLOC struct type
+	SWAP R3 R14                 ; SET I
+
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	STORE32 R0 R3 24            ; I->NAME = GLOBAL_TOKEN->S
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	STORE32 R4 R3 16            ; I->MEMBERS = LAST
+
+	LOADUI R0 $open_bracket     ; Using "["
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; IF GLOBAL_TOKEN->S == "["
+	JUMP.Z R0 @build_member_single
+
+	;; Deal with type name [ number ] ;
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @numerate_string  ; Convert string to int NUMBER
+	LOAD32 R1 R5 20             ; MEMBER_TYPE->TYPE
+	LOAD32 R1 R1 4              ; MEMBER_TYPE->TYPE->SIZE
+	MULU R0 R0 R1               ; MEMBER_TYPE->TYPE->SIZE * NUMBER
+	STORE32 R0 R3 4             ; I->SIZE = MEMBER_TYPE->TYPE->SIZE * NUMBER
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $build_member_string0 ; Our error message
+	LOADUI R1 $close_bracket    ; Using "]"
+	CALLI R15 @require_match    ; Make sure it is right
+	JUMP @build_member_done     ; Skip over single steps
+
+:build_member_single
+	LOAD32 R0 R5 4              ; MEMBER_TYPE->SIZE
+	STORE32 R0 R3 4             ; I->SIZE = MEMBER_TYPE->SIZE
+
+:build_member_done
+	LOAD32 R2 R3 4              ; MEMBER_SIZE = I->SIZE
+	STORE32 R5 R3 20            ; I->TYPE = MEMBER_TYPE
+	STORE32 R6 R3 8             ; I->OFFSET = OFFSET
+	MOVE R1 R6                  ; Restore OFFSET
+	MOVE R0 R3                  ; RETURN I in R0
+	POPR R6 R15                 ; Restore R6
+	POPR R5 R15                 ; Restore R5
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	RET R15
+
+:build_member_string0
+	"Struct only supports [num] form
+"
+
+
+;; build_union function
+;; Receives a struct type* in R0, int in R1 and int in R2
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Modifies R2 to current member_size
+;; Returns struct type* in R0
+:build_union
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+	PUSHR R5 R15                ; Protect R5
+	MOVE R4 R0                  ; Protect LAST
+	MOVE R3 R1                  ; Protect OFFSET
+	FALSE R5                    ; SIZE = 0
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $build_union_string0 ; ERROR MESSAGE
+	LOADUI R1 $open_curly_brace ; OPEN CURLY BRACE
+	CALLI R15 @require_match    ; Ensure we have that curly brace
+:build_union_iter
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	LOADUI R1 125               ; numerical value of }
+	CMPJUMPI.E R0 R1 @build_union_done ; No more looping required
+	MOVE R0 R4                  ; We are passing last to be overwritten
+	MOVE R1 R3                  ; We are also passing OFFSET
+	CALLI R15 @build_member     ; To build_member to get new LAST and new member_size
+	CMPSKIP.LE R2 R5            ; If MEMBER_SIZE > SIZE
+	COPY R5 R2                  ; SIZE = MEMMER_SIZE
+	MOVE R4 R0                  ; Protect LAST
+	MOVE R3 R1                  ; Protect OFFSET
+	LOADUI R0 $build_union_string1 ; ERROR MESSAGE
+	LOADUI R1 $semicolon        ; SEMICOLON
+	CALLI R15 @require_match    ; Ensure we have that curly brace
+	JUMP @build_union_iter      ; Loop until we get that closing curly brace
+:build_union_done
+	MOVE R2 R5                  ; Setting MEMBER_SIZE = SIZE
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	MOVE R1 R3                  ; Restore OFFSET
+	MOVE R0 R4                  ; Restore LAST as we are turning that
+	POPR R5 R15                 ; Restore R5
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	RET R15
+
+:build_union_string0
+"ERROR in build_union
+Missing {
+"
+:build_union_string1
+"ERROR in build_union
+Missing ;
+"
+
+
+;; create_struct function
+;; Receives Nothing
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns Nothing
+:create_struct
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+	PUSHR R5 R15                ; Protect R5
+	PUSHR R6 R15                ; Protect R6
+	FALSE R5                    ; OFFSET = 0
+	FALSE R2                    ; MEMBER_SIZE = 0
+	COPY R3 R14                 ; SET HEAD
+	ADDUI R14 R14 28            ; CALLOC struct type
+	COPY R4 R14                 ; SET I
+	ADDUI R14 R14 28            ; CALLOC struct type
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	STORE32 R0 R3 24            ; HEAD->NAME = GLOBAL_TOKEN->S
+	STORE32 R0 R4 24            ; I->NAME = GLOBAL_TOKEN->S
+	STORE32 R4 R3 12            ; HEAD->INDIRECT = I
+	STORE32 R3 R4 12            ; I->INDIRECT - HEAD
+	LOADR32 R0 @global_types    ; Get Address of GLOBAL_TYPES
+	STORE R0 R3 0               ; HEAD->NEXT = GLOBAL_TYPES
+	STORER32 R3 @global_types   ; GLOBAL_TYPES = HEAD
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 4                 ; Standard Pointer SIZE
+	STORE32 R0 R4 4             ; I->SIZE = 4
+	LOADUI R0 $create_struct_string0 ; ERROR MESSAGE
+	LOADUI R1 $open_curly_brace ; OPEN CURLY BRACE
+	CALLI R15 @require_match    ; Ensure we have that curly brace
+	FALSE R6                    ; LAST = NULL
+:create_struct_iter
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R0 R0 0              ; GLOBAL_TOKEN->S[0]
+	LOADUI R1 125               ; Numerical value of }
+	CMPJUMPI.E R0 R1 @create_struct_done ; Stop looping if match
+	LOADUI R1 $union            ; Pointer to string UNION
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; Check if they Match
+	SWAP R0 R6                  ; Put LAST in place
+	MOVE R1 R5                  ; Put OFFSET in place
+	JUMP.NZ R6 @create_struct_union ; Deal with union case
+
+	;; Deal with standard member case
+	CALLI R15 @build_member     ; Sets new LAST and MEMBER_SIZE
+	JUMP @create_struct_iter2   ; reset for loop
+
+:create_struct_union
+	CALLI R15 @build_union
+
+:create_struct_iter2
+	ADD R5 R1 R2                ; OFFSET = OFFSET + MEMBER_SIZE
+	SWAP R0 R6                  ; Put LAST in place
+	LOADUI R0 $create_struct_string1 ; ERROR MESSAGE
+	LOADUI R1 $semicolon        ; SEMICOLON
+	CALLI R15 @require_match    ; Ensure we have that semicolon
+	JUMP @create_struct_iter    ; Keep Looping
+
+:create_struct_done
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOADUI R0 $create_struct_string1 ; ERROR MESSAGE
+	LOADUI R1 $semicolon        ; SEMICOLON
+	CALLI R15 @require_match    ; Ensure we have that semicolon
+	STORE32 R5 R3 4             ; HEAD->SIZE = OFFSET
+	STORE32 R6 R3 16            ; HEAD->MEMBERS = LAST
+	STORE32 R6 R4 16            ; I->MEMBERS = LAST
+	POPR R6 R15                 ; Restore R6
+	POPR R5 R15                 ; Restore R5
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:create_struct_string0
+"ERROR in create_struct
+Missing {
+"
+:create_struct_string1
+"ERROR in create_struct
+Missing ;
+"
+
+
+;; type_name function
+;; Receives Nothing
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns struct type* in R0
+:type_name
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	LOADUI R0 $struct           ; String for struct for comparison
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; Check if they match
+	CMPSKIPI.E R0 0             ; If STRUCTURE
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOAD32 R2 R13 8             ; GLOBAL_TOKEN->S
+	LOADR32 R1 @global_types    ; Check using the GLOBAL TYPES LIST
+	SWAP R0 R2                  ; Put GLOBAL_TOKEN->S in the right place
+	CALLI R15 @lookup_type      ; RET = lookup_type(GLOBAL_TOKEN->S)
+	MOVE R1 R2                  ; Put STRUCTURE in the right place
+	CMPSKIP.E R0 R1             ; If RET == NULL and !STRUCTURE
+	JUMP @type_name_struct      ; Guess not
+
+	;; Exit with useful error message
+	FALSE R1                    ; We will want to be writing the error message for the Human
+	LOADUI R0 $type_name_string0 ; The first string
+	CALLI R15 @file_print       ; Display it
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @file_print       ; Display it
+	LOADUI R0 $newline          ; Terminating linefeed
+	CALLI R15 @file_print       ; Display it
+	CALLI R15 @line_error       ; Give useful debug info
+	HALT                        ; Just exit
+
+:type_name_struct
+	JUMP.NZ R0 @type_name_iter  ; If was found
+	CALLI R15 @create_struct    ; Otherwise create it
+	JUMP @type_name_done        ; and be done
+
+:type_name_iter
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	LOAD32 R1 R13 8             ; GLOBAL_TOKEN->S
+	LOADU8 R1 R1 0              ; GLOBAL_TOKEN->S[0]
+	CMPSKIPI.E R1 42            ; if GLOBAL_TOKEN->S[0] == '*'
+	JUMP @type_name_done        ; Looks like Nope
+	LOAD32 R0 R0 12             ; RET = RET->INDIRECT
+	JUMP @type_name_iter        ; Keep looping
+
+:type_name_done
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+:type_name_string0
+"Unknown type "
+
+
+;; line_error function
+;; Receives Nothing
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns nothing
+:line_error
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R1 R15                ; Protect R1
+	LOADUI R0 $line_error_string0 ; Our leading string
+	FALSE R1                    ; We want the user to see
+	CALLI R15 @file_print       ; Print it
+	LOAD32 R0 R13 16            ; GLOBAL_TOKEN->LINENUMBER
+	CALLI R15 @numerate_number  ; Get a string pointer for number
+	CALLI R15 @file_print       ; And print it
+	POPR R1 R15                 ; Restore R1
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+:line_error_string0
+	"In file: TTY1 On line: "
+
+
+;; require_match function
+;; Receives char* in R0 and char* in R1
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns Nothing
+:require_match
+	PUSHR R0 R15                ; Protect R0
+	PUSHR R2 R15                ; Protect R2
+	MOVE R2 R0                  ; Get MESSAGE out of the way
+	LOAD32 R0 R13 8             ; GLOBAL_TOKEN->S
+	CALLI R15 @match            ; Check if GLOBAL_TOKEN->S == REQUIRED
+	JUMP.NZ R0 @require_match_done ; Looks like it was a match
+
+	;; Terminate with an error
+	MOVE R0 R2                  ; Put MESSAGE in required spot
+	FALSE R1                    ; We want to write for user
+	CALLI R15 @file_print       ; Write it
+	CALLI R15 @line_error       ; And provide some debug info
+	HALT                        ; Then Stop immediately
+
+:require_match_done
+	LOAD32 R13 R13 0            ; GLOBAL_TOKEN = GLOBAL_TOKEN->NEXT
+	POPR R2 R15                 ; Restore R2
+	POPR R0 R15                 ; Restore R0
+	RET R15
+
+
+;; numerate_number function
+;; Receives int in R0
+;; R13 Holds pointer to global_token, R14 is HEAP Pointer
+;; Returns pointer to string generated
+:numerate_number
+	PUSHR R1 R15                ; Preserve R1
+	PUSHR R2 R15                ; Preserve R2
+	PUSHR R3 R15                ; Preserve R3
+	PUSHR R4 R15                ; Preserve R4
+	PUSHR R5 R15                ; Preserve R5
+	PUSHR R6 R15                ; Preserve R6
+	MOVE R3 R0                  ; Move Integer out of the way
+	COPY R1 R14                 ; Get pointer result
+	ADDUI R14 R14 16            ; CALLOC the 16 chars of space
+	FALSE R6                    ; Set index to 0
+
+	JUMP.Z R3 @numerate_number_ZERO ; Deal with Special case of ZERO
+	JUMP.P R3 @numerate_number_Positive
+	LOADUI R0 45                ; Using -
+	STOREX8 R0 R1 R6            ; write leading -
+	ADDUI R6 R6 1               ; Increment by 1
+	NOT R3 R3                   ; Flip into positive
+	ADDUI R3 R3 1               ; Adjust twos
+
+:numerate_number_Positive
+	LOADR R2 @Max_Decimal       ; Starting from the Top
+	LOADUI R5 10                ; We move down by 10
+	FALSE R4                    ; Flag leading Zeros
+
+:numerate_number_0
+	DIVIDE R0 R3 R3 R2          ; Break off top 10
+	CMPSKIPI.E R0 0             ; If Not Zero
+	TRUE R4                     ; Flip the Flag
+
+	JUMP.Z R4 @numerate_number_1 ; Skip leading Zeros
+	ADDUI R0 R0 48              ; Shift into ASCII
+	STOREX8 R0 R1 R6            ; write digit
+	ADDUI R6 R6 1               ; Increment by 1
+
+:numerate_number_1
+	DIV R2 R2 R5                ; Look at next 10
+	CMPSKIPI.E R2 0             ; If we reached the bottom STOP
+	JUMP @numerate_number_0     ; Otherwise keep looping
+
+:numerate_number_done
+	FALSE R0                    ; NULL Terminate
+	STOREX8 R0 R1 R6            ; write
+	MOVE R0 R1                  ; Return pointer to our string
+	;; Cleanup
+	POPR R6 R15                 ; Restore R6
+	POPR R5 R15                 ; Restore R5
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+:numerate_number_ZERO
+	LOADUI R0 48                ; Using Zero
+	STOREX8 R0 R1 R6            ; write
+	ADDUI R6 R6 1               ; Increment by 1
+	JUMP @numerate_number_done  ; Be done
+
+:Max_Decimal
+	'3B9ACA00'
+
+
+;; numerate_string function
+;; Receives pointer To string in R0
+;; Returns number in R0 equal to value of string
+;; Or Zero in the event of invalid string
+:numerate_string
+	PUSHR R1 R15                ; Protect R1
+	PUSHR R2 R15                ; Protect R2
+	PUSHR R3 R15                ; Protect R3
+	PUSHR R4 R15                ; Protect R4
+
+	;; Initialize
+	MOVE R1 R0                  ; Get Text pointer out of the way
+	FALSE R2                    ; Set Negative flag to false
+	FALSE R3                    ; Set current count to Zero
+	LOAD8 R0 R1 1               ; Get second byte
+	CMPSKIPI.NE R0 120          ; If the second byte is x
+	JUMP @numerate_string_hex   ; treat string like hex
+
+	;; Deal with Decimal input
+	LOADUI R4 10                ; Multiply by 10
+	LOAD8 R0 R1 0               ; Get a byte
+	CMPSKIPI.NE R0 45           ; If - toggle flag
+	TRUE R2                     ; So that we know to negate
+	CMPSKIPI.E R2 0             ; If toggled
+	ADDUI R1 R1 1               ; Move to next
+:numerate_string_dec
+	LOAD8 R0 R1 0               ; Get a byte
+
+	CMPSKIPI.NE R0 0            ; If NULL
+	JUMP @numerate_string_done  ; Be done
+
+	MUL R3 R3 R4                ; Shift counter by 10
+	SUBI R0 R0 48               ; Convert ascii to number
+	CMPSKIPI.GE R0 0            ; If less than a number
+	JUMP @numerate_string_done  ; Terminate NOW
+	CMPSKIPI.L R0 10            ; If more than a number
+	JUMP @numerate_string_done  ; Terminate NOW
+	ADDU R3 R3 R0               ; Don't add to the count
+
+	ADDUI R1 R1 1               ; Move onto next byte
+	JUMP @numerate_string_dec
+
+	;; Deal with Hex input
+:numerate_string_hex
+	LOAD8 R0 R1 0               ; Get a byte
+	CMPSKIPI.E R0 48            ; All hex strings start with 0x
+	JUMP @numerate_string_done  ; Be done if not a match
+	ADDUI R1 R1 2               ; Move to after leading 0x
+:numerate_string_hex_0
+	LOAD8 R0 R1 0               ; Get a byte
+	CMPSKIPI.NE R0 0            ; If NULL
+	JUMP @numerate_string_done  ; Be done
+
+	SL0I R3 4                   ; Shift counter by 16
+	SUBI R0 R0 48               ; Convert ascii number to number
+	CMPSKIPI.L R0 10            ; If A-F
+	SUBI R0 R0 7                ; Shove into Range
+	CMPSKIPI.L R0 16            ; If a-f
+	SUBI R0 R0 32               ; Shove into Range
+	ADDU R3 R3 R0               ; Add to the count
+
+	ADDUI R1 R1 1               ; Get next Hex
+	JUMP @numerate_string_hex_0
+
+;; Clean up
+:numerate_string_done
+	CMPSKIPI.E R2 0             ; If Negate flag has been set
+	NEG R3 R3                   ; Make the number negative
+	MOVE R0 R3                  ; Put number in R0
+
+	POPR R4 R15                 ; Restore R4
+	POPR R3 R15                 ; Restore R3
+	POPR R2 R15                 ; Restore R2
+	POPR R1 R15                 ; Restore R1
+	RET R15
+
+
+;; 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
+	"]"
+:semicolon
+	";"
+:equal
+	"="
+:percent
+	"%"
+:newline
+	"
+"
+:underline
+	"_"
+
+;; Global types
+;; NEXT (0), SIZE (4), OFFSET (8), INDIRECT (12), MEMBERS (16), TYPE (20), NAME (24)
+:global_types
+	&type_void
+
+:prim_types
+:type_void
+	&type_int                   ; NEXT
+	'00 00 00 04'               ; SIZE
+	NOP                         ; OFFSET
+	&type_void                  ; INDIRECT
+	NOP                         ; MEMBERS
+	&type_void                  ; TYPE
+	&type_void_name             ; NAME
+:type_void_name
+	"void"
+
+:type_int
+	&type_char                  ; NEXT
+	'00 00 00 04'               ; SIZE
+	NOP                         ; OFFSET
+	&type_int                   ; INDIRECT
+	NOP                         ; MEMBERS
+	&type_int                   ; TYPE
+	&type_int_name              ; NAME
+:type_int_name
+	"int"
+
+:type_char
+	&type_file                  ; NEXT
+	'00 00 00 01'               ; SIZE
+	NOP                         ; OFFSET
+	&type_char_indirect         ; INDIRECT
+	NOP                         ; MEMBERS
+	&type_char                  ; TYPE
+	&type_char_name             ; NAME
+:type_char_name
+	"char"
+
+:type_char_indirect
+	&type_file                  ; NEXT
+	'00 00 00 04'               ; SIZE
+	NOP                         ; OFFSET
+	&type_char_double_indirect  ; INDIRECT
+	NOP                         ; MEMBERS
+	&type_char_indirect         ; TYPE
+	&type_char_indirect_name    ; NAME
+:type_char_indirect_name
+	"char*"
+
+:type_char_double_indirect
+	&type_file                  ; NEXT
+	'00 00 00 04'               ; SIZE
+	NOP                         ; OFFSET
+	&type_char_double_indirect  ; INDIRECT
+	NOP                         ; MEMBERS
+	&type_char_indirect         ; TYPE
+	&type_char_double_indirect_name ; NAME
+:type_char_double_indirect_name
+	"char**"
+
+:type_file
+	&type_function              ; NEXT
+	'00 00 00 04'               ; SIZE
+	NOP                         ; OFFSET
+	&type_file                  ; INDIRECT
+	NOP                         ; MEMBERS
+	&type_file                  ; TYPE
+	&type_file_name             ; NAME
+:type_file_name
+	"FILE"
+
+:type_function
+	&type_unsigned              ; NEXT
+	'00 00 00 04'               ; SIZE
+	NOP                         ; OFFSET
+	&type_function              ; INDIRECT
+	NOP                         ; MEMBERS
+	&type_function              ; TYPE
+	&type_function_name         ; NAME
+:type_function_name
+	"FUNCTION"
+
+:type_unsigned
+	NOP                         ; NEXT (NULL)
+	'00 00 00 04'               ; SIZE
+	NOP                         ; OFFSET
+	&type_unsigned              ; INDIRECT
+	NOP                         ; MEMBERS
+	&type_unsigned              ; TYPE
+	&type_unsigned_name         ; NAME
+:type_unsigned_name
+	"unsigned"
+
+
+;; debug_list function
+;; Receives struct token_list* in R0
+;; Prints contents of list and HALTS
+;; Does not return
+:debug_list
+	MOVE R9 R0                  ; Protect the list Pointer
+	FALSE R1                    ; Write to TTY
+
+:debug_list_iter
+	;; Header
+	LOADUI R0 $debug_list_string0 ; Using our first string
+	CALLI R15 @file_print       ; Print it
+	COPY R0 R9                  ; Use address of pointer
+	CALLI R15 @numerate_number  ; Convert it into a string
+	CALLI R15 @file_print       ; Print it
+
+	;; NEXT
+	LOADUI R0 $debug_list_string1 ; Using our second string
+	CALLI R15 @file_print       ; Print it
+	LOAD32 R0 R9 0              ; Use address of pointer
+	CALLI R15 @numerate_number  ; Convert it into a string
+	CALLI R15 @file_print       ; Print it
+
+	;; PREV
+	LOADUI R0 $debug_list_string2 ; Using our third string
+	CALLI R15 @file_print       ; Print it
+	LOAD32 R0 R9 4              ; Use address of pointer
+	CALLI R15 @numerate_number  ; Convert it into a string
+	CALLI R15 @file_print       ; Print it
+
+	;; S
+	LOADUI R0 $debug_list_string3 ; Using our fourth string
+	CALLI R15 @file_print       ; Print it
+	LOAD32 R0 R9 8              ; Use address of pointer
+	CALLI R15 @numerate_number  ; Convert it into a string
+	CALLI R15 @file_print       ; Print it
+
+	;; S Contents
+	LOADUI R0 $debug_list_string4 ; Using our Prefix string
+	CALLI R15 @file_print       ; Print it
+	LOAD32 R0 R9 8              ; Use address of pointer
+	CMPSKIPI.NE R0 0            ; If NULL Pointer
+	LOADUI R0 $debug_list_string_null ; Give meaningful message instead
+	CALLI R15 @file_print       ; Print it
+
+	;; TYPE
+	LOADUI R0 $debug_list_string5 ; Using our fifth string
+	CALLI R15 @file_print       ; Print it
+	LOAD32 R0 R9 12             ; Use address of pointer
+	CALLI R15 @numerate_number  ; Convert it into a string
+	CALLI R15 @file_print       ; Print it
+
+	;; PREV
+	LOADUI R0 $debug_list_string6 ; Using our sixth string
+	CALLI R15 @file_print       ; Print it
+	LOAD32 R0 R9 16             ; Use address of pointer
+	CALLI R15 @numerate_number  ; Convert it into a string
+	CALLI R15 @file_print       ; Print it
+
+	;; Add some space
+	LOADUI R0 10                ; Using NEWLINE
+	FPUTC
+	FPUTC
+
+	;; Iterate if next not NULL
+	LOAD32 R9 R9 0              ; TOKEN = TOKEN->NEXT
+	JUMP.NZ R9 @debug_list_iter
+
+	;; Looks lke we are done, wrap it up
+	HALT
+
+
+: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>::<"
+
+:STACK