summaryrefslogtreecommitdiff
path: root/04a/in03
diff options
context:
space:
mode:
Diffstat (limited to '04a/in03')
-rw-r--r--04a/in03322
1 files changed, 0 insertions, 322 deletions
diff --git a/04a/in03 b/04a/in03
deleted file mode 100644
index ed965e6..0000000
--- a/04a/in03
+++ /dev/null
@@ -1,322 +0,0 @@
-I=8S
-A=d3
-?I!A:usage_error
-; open input file
- J=S
- ; argv[1] is at *(rsp+16)
- J+=d16
- J=8J
- I=d0
- syscall x2
- J=A
- ?J<0:input_file_error
-; open output file
- J=S
- ; argv[2] is at *(rsp+24)
- J+=d24
- J=8J
- I=x241
- D=x1ed
- syscall x2
- J=A
- ?J<0:output_file_error
-; initialize :definitions_end
-J=:definitions_end
-D=:definitions
-8J=D
-
-:read_line
-; use rbp to store line pointer
-R=:line
-:read_line_loop
- ; read 1 byte into rbp
- J=d3
- I=R
- D=d1
- syscall x0
- D=A
- ?D=0:eof
-
- ; check if the character was a newline:
- C=1R
- D=xa
- ?C=D:read_line_loop_end
- R+=d1
- !:read_line_loop
-:read_line_loop_end
-
-; check if line = "#define " up to a terminator of ' '.
-C=x20
-I=:#define
-J=:line
-call :string=
-D=A
-?D!0:handle_#define
-
-; handle a normal line
-; R will store a pointer to the current character
-R=:line
-:process_line_loop
- C=1R
- B=C
- call :isident
- ?A!0:process_ident
- ; if *R is not an identifier character, just output it to the file.
- J=d4
- B=C
- call :fputc
- ; check if we reached the end of the line
- C=1R
- D=xa
- ?C=D:read_line
- ; increment R, keep looping
- R+=d1
- !:process_line_loop
- :process_ident
- ; if *R is an ident char. look up this identifier in :definitions.
- ; use C to keep pointer to definition
- C=:definitions
- :lookup_loop
- D=1C
- ; check if we reached end of definition table
- ?D=0:lookup_loop_end
- ; check if this entry matches our identifier
- I=R
- J=C
- call :ident=
- ?A!0:perform_substitution
- ; if not, skip over this entry
- :skip_definition_loop
- D=1C
- I=xa
- C+=d1
- ?I!D:skip_definition_loop
- !:lookup_loop
- :lookup_loop_end
- ; this identifier doesn't match anything in the definitions table; just write it.
- ; first, figure out how long it is
- J=R
- :length_loop
- C=1J
- B=C
- call :isident
- ?A=0:length_loop_end
- J+=d1
- !:length_loop
- :length_loop_end
- ; now write it.
- I=R
- R=J
- J-=I
- D=J
- J=d4
- syscall x1
- ; keep looping
- !:process_line_loop
-
-:perform_substitution
- ; right now, I is a pointer to the end of the identifier in :line,
- ; and J is a pointer to the end of the identifier in :definitions.
-
- ; advance :line pointer for next loop iteration
- R=I
-
- J+=d1
- ; J now points to the definition. let's write it
- I=J
- :definition_end_loop
- C=1I
- D=xa
- ?C=D:definition_end_loop_end
- I+=d1
- !:definition_end_loop
- :definition_end_loop_end
- D=I
- D-=J
- I=J
- J=d4
- syscall x1
- ; process the rest of this line
- !:process_line_loop
-
-:eof
- J=d0
- syscall x3c
-
-; can the character in rbx appear in an identifier?
-:isident
- A='0
- ?B<A:return_0
- ; note: 58 = '9' + 1
- A=d58
- ?B<A:return_1
- A='A
- ?B<A:return_0
- ; note: 91 = 'z' + 1
- A=d91
- ?B<A:return_1
- A='z
- ?B>A:return_0
- ; 96 = 'a' - 1
- A=d96
- ?B>A:return_1
- A='_
- ?B=A:return_1
- !:return_0
-
-
-:handle_#define
- J=:definitions_end
- J=8J
- ; start copy from after "#define"
- I=:line
- I+=d8
-
- :#define_copy_loop
- D=1I
- 1J=D
- I+=d1
- J+=d1
- A=xa
- ?D=A:#define_copy_loop_end
- !:#define_copy_loop
- :#define_copy_loop_end
-
- ; update end of definitions
- D=:definitions_end
- 8D=J
- ; emit newline so we don't screw up line numbers
- J=d4
- I=:newline
- D=d1
- syscall x1
-
- !:read_line
-
-:newline
- xa
-
-
-:usage_error
- B=:usage_error_message
- call :error
-
-:usage_error_message
- str Please provide an input and an output file.
- xa
- x0
-
-:input_file_error
- B=:input_file_error_message
- !:error
-
-:input_file_error_message
- str Couldn't open input file.
- xa
- x0
-
-:output_file_error
- B=:output_file_error_message
- !:error
-
-:output_file_error_message
- str Couldn't open output file.
- xa
- x0
-
-:error
- J=B
- call :strlen
- D=A
- I=J
- J=d2
- syscall x1
- J=d1
- syscall x3c
-
-:strlen
- I=B
- D=B
- :strlen_loop
- C=1I
- ?C=0:strlen_ret
- I+=d1
- !:strlen_loop
- :strlen_ret
- I-=D
- A=I
- return
-
-:#define
- str #define
- x20
- x0
-
-; check if strings in rdi and rsi are equal, up to terminator in rcx
-:string=
- D=1I
- A=1J
- ?D!A:return_0
- ?D=C:return_1
- I+=d1
- J+=d1
- !:string=
-
-; check if strings in rdi and rsi are equal, up to the first non-identifier character
-:ident=
- D=1I
- B=D
- call :isident
- ; I ended
- ?A=0:ident=_I_end
-
- D=1J
- B=D
- call :isident
- ; J ended, but I didn't
- ?A=0:return_0
-
- ; we haven't reached the end of either
- D=1I
- A=1J
- ?D!A:return_0
- I+=d1
- J+=d1
- !:ident=
-:ident=_I_end
- D=1J
- B=D
- call :isident
- ; check if J also ended
- ?A=0:return_1
- ; J didn't end
- !:return_0
-
-:return_0
- A=d0
- return
-:return_1
- A=d1
- return
-
-; write the character in rbx to the file in rdi.
-:fputc
- C=B
- I=S
- I-=d1
- 1I=C
- D=d1
- syscall x1
- return
-
-
-align
-:definitions_end
- reserve d8
-:line
- reserve d1000
-:definitions
- reserve d200000
-
-; we shouldn't end the file with a reserve; we don't handle that properly
-x00