about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCase Duckworth2022-06-29 00:59:59 -0500
committerCase Duckworth2022-06-29 00:59:59 -0500
commit0a78720644e45bd27c4a57cbddf2d32aacb555c3 (patch)
tree29783dc9a534dbbfe172d5c84e66f5efcd9c43dc
parentRecognize bf comments (diff)
downloadtrainfuck-0a78720644e45bd27c4a57cbddf2d32aacb555c3.tar.gz
trainfuck-0a78720644e45bd27c4a57cbddf2d32aacb555c3.zip
Probably version ... whatever the next higher one is
-rw-r--r--examples/add2.bf27
-rw-r--r--examples/hello-world.bf45
-rw-r--r--examples/helloworld.bf1
-rw-r--r--examples/helloworld.trainfuck152
-rw-r--r--examples/rot13.bf32
-rwxr-xr-xfucktrain4
-rwxr-xr-xtrainfuck123
-rwxr-xr-xtrainfuck.awk321
8 files changed, 433 insertions, 272 deletions
diff --git a/examples/add2.bf b/examples/add2.bf new file mode 100644 index 0000000..42361db --- /dev/null +++ b/examples/add2.bf
@@ -0,0 +1,27 @@
1[ Add two values
2from https://en.wikipedia.org/wiki/Brainfuck#Adding_two_values
3]
4
5++ Cell c0 = 2
6> +++++ Cell c1 = 5
7
8[ Start your loops with your cell pointer on the loop counter (c1 in our case)
9< + Add 1 to c0
10> - Subtract 1 from c1
11] End your loops with the cell pointer on the loop counter
12
13At this point our program has added 5 to 2 leaving 7 in c0 and 0 in c1
14but we cannot output this value to the terminal since it is not ASCII encoded
15
16To display the ASCII character "7" we must add 48 to the value 7
17We use a loop to compute 48 = 6 * 8
18
19++++ ++++ c1 = 8 and this will be our loop counter again
20[
21< +++ +++ Add 6 to c0
22> - Subtract 1 from c1
23]
24< . Print out c0 which has the value 55 which translates to "7"!
25
26Finally print a newline:
27---------------------------------------------.
diff --git a/examples/hello-world.bf b/examples/hello-world.bf new file mode 100644 index 0000000..dce24e2 --- /dev/null +++ b/examples/hello-world.bf
@@ -0,0 +1,45 @@
1[ This program prints "Hello World!" and a newline to the screen, its
2length is 106 active command characters. [It is not the shortest.]
3
4This loop is an "initial comment loop", a simple way of adding a comment
5to a BF program such that you don't have to worry about any command
6characters. Any ".", ",", "+", "-", "<" and ">" characters are simply
7ignored, the "[" and "]" characters just have to be balanced. This
8loop and the commands it contains are ignored because the current cell
9defaults to a value of 0; the 0 value causes this loop to be skipped.
10
11from https://en.wikipedia.org/wiki/Brainfuck#Hello_World!
12]
13++++++++ Set Cell #0 to 8
14[
15>++++ Add 4 to Cell #1; this will always set Cell #1 to 4
16[ as the cell will be cleared by the loop
17>++ Add 2 to Cell #2
18>+++ Add 3 to Cell #3
19>+++ Add 3 to Cell #4
20>+ Add 1 to Cell #5
21<<<<- Decrement the loop counter in Cell #1
22] Loop until Cell #1 is zero; number of iterations is 4
23>+ Add 1 to Cell #2
24>+ Add 1 to Cell #3
25>- Subtract 1 from Cell #4
26>>+ Add 1 to Cell #6
27[<] Move back to the first zero cell you find; this will
28be Cell #1 which was cleared by the previous loop
29<- Decrement the loop Counter in Cell #0
30] Loop until Cell #0 is zero; number of iterations is 8
31
32The result of this is:
33Cell no : 0 1 2 3 4 5 6
34Contents: 0 0 72 104 88 32 8
35Pointer : ^
36
37>>. Cell #2 has value 72 which is 'H'
38>---. Subtract 3 from Cell #3 to get 101 which is 'e'
39+++++++..+++. Likewise for 'llo' from Cell #3
40>>. Cell #5 is 32 for the space
41<-. Subtract 1 from Cell #4 for 87 to give a 'W'
42<. Cell #3 was set to 'o' from the end of 'Hello'
43+++.------.--------. Cell #3 for 'rl' and 'd'
44>>+. Add 1 to Cell #5 gives us an exclamation point
45>++. And finally a newline from Cell #6
diff --git a/examples/helloworld.bf b/examples/helloworld.bf deleted file mode 100644 index 8fa0f72..0000000 --- a/examples/helloworld.bf +++ /dev/null
@@ -1 +0,0 @@
1++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
diff --git a/examples/helloworld.trainfuck b/examples/helloworld.trainfuck deleted file mode 100644 index 1f68f11..0000000 --- a/examples/helloworld.trainfuck +++ /dev/null
@@ -1,152 +0,0 @@
1TRAINFUCK BABEEE
2CHOO CHOO MUTHERFUCKER
3
4This example adapted from https://en.wikipedia.org/wiki/Brainfuck
5
6This program prints "Hello World!" and a newline to the screen, its
7length is 106 active command characters.
8
9The program doesn't start until we have ALL ABOARD on a line by itself, so
10we've got one better than an initial comment loop.
11
12This file was handwritten, but soon(TM) we'll have a fucktrain command,
13that'll translate to trainfuck from brainfuck.
14
15ALL ABOARD
16chug chug chug chug chug chug chug chug
17END OF THE LINE
18 Set Cell #0 to 8
19 (Also note: you can have comments betwen END OF THE LINE and ALL ABOARD)
20ALL ABOARD
21tickets please
22choo
23chug chug chug chug
24END OF THE LINE
25 Add 4 to Cell #1; this will always set Cell #1 to 4
26ALL ABOARD
27tickets please
28END OF THE LINE
29 as the cell will be cleared by the loop
30ALL ABOARD
31choo
32chug chug
33END OF THE LINE
34 Add 2 to Cell #2
35ALL ABOARD
36choo
37chug chug chug
38END OF THE LINE
39 Add 3 to Cell #3
40ALL ABOARD
41choo
42chug chug chug
43END OF THE LINE
44 Add 3 to Cell #4
45ALL ABOARD
46choo
47chug
48END OF THE LINE
49 Add 1 to Cell #5
50ALL ABOARD
51choo choo
52choo choo
53choo choo
54choo choo
55chugga
56END OF THE LINE
57 Decrement the loop counter in Cell #1
58ALL ABOARD
59your ticket please
60END OF THE LINE
61 Loop till Cell #1 is zero; number of iterations is 4
62ALL ABOARD
63choo
64chug
65END OF THE LINE
66 Add 1 to Cell #2
67ALL ABOARD
68choo
69chug
70END OF THE LINE
71 Add 1 to Cell #3
72ALL ABOARD
73choo
74chugga
75END OF THE LINE
76 Subtract 1 from Cell #4
77ALL ABOARD
78choo
79choo
80chug
81END OF THE LINE
82 Add 1 to Cell #6
83ALL ABOARD
84tickets pleasechoo choo
85your ticket please
86END OF THE LINE
87 Move back to the first zero cell you find; this will
88ALL ABOARD
89
90END OF THE LINE
91 be Cell #1 which was cleared by the previous loop
92ALL ABOARD
93choo choo
94chugga
95END OF THE LINE
96 Decrement the loop Counter in Cell #0
97ALL ABOARD
98your ticket please
99END OF THE LINE
100 Loop till Cell #0 is zero; number of iterations is 8
101ALL ABOARD
102END OF THE LINE
103The result of this is:
104Cell No : 0 1 2 3 4 5 6
105Contents: 0 0 72 104 88 32 8
106Pointer : ^
107
108ALL ABOARD
109choo
110choo
111click
112END OF THE LINE
113 Cell #2 has value 72 which is 'H'
114ALL ABOARD
115choo
116chugga chugga chugga click
117END OF THE LINE
118 Subtract 3 from Cell #3 to get 101 which is 'e'
119ALL ABOARD
120chug chug chug chug chug chug chug click click chug chug chug click
121END OF THE LINE
122 Likewise for 'llo' from Cell #3
123ALL ABOARD
124choo
125choo
126click
127END OF THE LINE
128 Cell #5 is 32 for the space
129ALL ABOARD
130choo choo
131chugga click
132END OF THE LINE
133 Subtract 1 from Cell #4 for 87 to give a 'W'
134ALL ABOARD
135choo choo
136click
137END OF THE LINE
138 Cell #3 was set to 'o' from the end of 'Hello'
139ALL ABOARD
140chug chug chug click chugga chugga chugga chugga chugga chugga click chugga chugga chugga chugga chugga chugga chugga chugga click
141END OF THE LINE
142 Cell #3 for 'rl' and 'd'
143ALL ABOARD
144choo
145choo
146chug click
147END OF THE LINE
148 Add 1 to Cell #5 gives us an exclamation point
149ALL ABOARD
150choo
151chug chug click
152END OF THE LINE
diff --git a/examples/rot13.bf b/examples/rot13.bf new file mode 100644 index 0000000..bfcde73 --- /dev/null +++ b/examples/rot13.bf
@@ -0,0 +1,32 @@
1[ ROT13 in Brainfuck
2from https://en.wikipedia.org/wiki/Brainfuck#ROT13
3]
4
5-,+[ Read first character and start outer character reading loop
6-[ Skip forward if character is 0
7>>++++[>++++++++<-] Set up divisor (32) for division loop
8(MEMORY LAYOUT: dividend copy remainder divisor quotient zero zero)
9<+<-[ Set up dividend (x minus 1) and enter division loop
10>+>+>-[>>>] Increase copy and remainder / reduce divisor / Normal case: skip forward
11<[[>+<-]>>+>] Special case: move remainder back to divisor and increase quotient
12<<<<<- Decrement dividend
13] End division loop
14]>>>[-]+ End skip loop; zero former divisor and reuse space for a flag
15>--[-[<->+++[-]]]<[ Zero that flag unless quotient was 2 or 3; zero quotient; check flag
16++++++++++++<[ If flag then set up divisor (13) for second division loop
17(MEMORY LAYOUT: zero copy dividend divisor remainder quotient zero zero)
18>-[>+>>] Reduce divisor; Normal case: increase remainder
19>[+[<+>-]>+>>] Special case: increase remainder / move it back to divisor / increase quotient
20<<<<<- Decrease dividend
21] End division loop
22>>[<+>-] Add remainder back to divisor to get a useful 13
23>[ Skip forward if quotient was 0
24-[ Decrement quotient and skip forward if quotient was 1
25-<<[-]>> Zero quotient and divisor if quotient was 2
26]<<[<<->>-]>> Zero divisor and subtract 13 from copy if quotient was 1
27]<<[<<+>>-] Zero divisor and add 13 to copy if quotient was 0
28] End outer skip loop (jump to here if ((character minus 1)/32) was not 2 or 3)
29<[-] Clear remainder from first division if second division was skipped
30<.[-] Output ROT13ed character from copy and clear it
31<-,+ Read next character
32] End character reading loop
diff --git a/fucktrain b/fucktrain index d382efa..7ade621 100755 --- a/fucktrain +++ b/fucktrain
@@ -17,7 +17,9 @@ BEGIN {
17 gsub(/,/, "clack ", $0) 17 gsub(/,/, "clack ", $0)
18 gsub(/\[/, "tickets please ", $0) 18 gsub(/\[/, "tickets please ", $0)
19 gsub(/\]/, "your ticket please ", $0) 19 gsub(/\]/, "your ticket please ", $0)
20 print 20 if ($0) {
21 print
22 }
21} 23}
22 24
23END { 25END {
diff --git a/trainfuck b/trainfuck index 602fc92..22d1009 100755 --- a/trainfuck +++ b/trainfuck
@@ -1,128 +1,15 @@
1#!/bin/awk -f 1#!/bin/sh
2# TRAINFUCK: CHOO CHOO MUTHAFUCKA -*- awk -*- 2# TRAINFUCK: CHOO CHOO MUTHAFUCKA -*- sh -*-
3# Author: Case Duckworth <acdw@acdw.net> 3# Author: Case Duckworth <acdw@acdw.net>
4# License: WTFPL 4# License: WTFPL
5# Version: #9 5# Version: #9
6 6
7### Commentary: 7### Commentary:
8 8
9# LANGUAGE 9# shell wrapper around trainfuck.awk, which see.
10
11# trainfuck is not case-sensitive
12# -- except for ALL ABOARD and END OF THE LINE
13# ignore everything before ALL ABOARD
14# ignore everything after END OF THE LINE
15# (this means you can comment between these)
16# bf tf
17# + chug
18# - chugga
19# > choo
20# < choo choo
21# . click OR clickety
22# , clack
23# [ tickets please
24# ] your ticket please
25# syntax does NOT WRAP across line breaks
26# anything else is an error and DERAILS the train
27 10
28### Code: 11### Code:
29BEGIN {
30 aboard = 0
31 width = 30
32 print "["
33}
34
35/^ALL ABOARD$/ {
36 if (! header) {
37 print "]"
38 }
39 header++
40 aboard = 1
41 next
42}
43
44/^END OF THE LINE$/ {
45 aboard = 0
46 next
47}
48
49aboard {
50 gsub(/[[:space:]]/, "", $0)
51 buf = buf proc(toupper($0))
52}
53
54! aboard {
55 printbuf()
56 if (header) {
57 gsub(/[-+<>.,\[\]]/, "", $0)
58 }
59 print
60 buf = ""
61}
62
63END {
64 if (DERAIL_ERR) {
65 print DERAIL_ERR
66 exit 9
67 }
68 printbuf()
69 printf "\n"
70}
71
72
73function derail(err)
74{
75 print "TRAIN DERAILED at input line", FNR
76 DERAIL_ERR = err
77 exit
78}
79 12
80function printbuf(newline) 13TRAINFUCK=trainfuck.awk
81{
82 for (ss = 1; ss <= length(buf); ss += width) {
83 printf "%s\n", substr(buf, ss, width)
84 }
85}
86 14
87function proc(t) 15gawk -v EXE_NAME="$(basename $0)" -f "$TRAINFUCK" -- "$@"
88{
89 if (! match(t, /CHUGGA|CHUG|CHOO|CLICK|CLICKETY|CLACK|TICKETSPLEASE|YOURTICKETPLEASE|$/)) {
90 derail("WTF")
91 }
92 pre = substr(t, 1, RSTART - 1)
93 tok = substr(t, RSTART, RLENGTH)
94 pst = substr(t, RSTART + RLENGTH)
95 if (tok == "CHUGGA") { # needs to be first
96 tok = "-"
97 return (pre tok proc(pst))
98 }
99 if (tok == "CHUG") {
100 tok = "+"
101 return (pre tok proc(pst))
102 }
103 if (tok == "CHOO") {
104 if (substr(pst, 1, 4) == "CHOO") {
105 tok = "<"
106 sub(/CHOO/, "", pst)
107 } else {
108 tok = ">"
109 }
110 return (pre tok proc(pst))
111 }
112 if (tok == "CLICK" || tok == "CLICKETY") {
113 tok = "."
114 return (pre tok proc(pst))
115 }
116 if (tok == "CLACK") {
117 tok = ","
118 return (pre tok proc(pst))
119 }
120 if (tok == "TICKETSPLEASE") {
121 tok = "["
122 return (pre tok proc(pst))
123 }
124 if (tok == "YOURTICKETPLEASE") {
125 tok = "]"
126 return (pre tok proc(pst))
127 }
128}
diff --git a/trainfuck.awk b/trainfuck.awk new file mode 100755 index 0000000..df89821 --- /dev/null +++ b/trainfuck.awk
@@ -0,0 +1,321 @@
1#!/bin/awk -f
2# TRAINFUCK: CHOO CHOO MUTHAFUCKA -*- awk -*-
3# Author: Case Duckworth <acdw@acdw.net>
4# License: WTFPL
5# Version: #9
6
7### Commentary:
8
9# LANGUAGE
10
11# trainfuck is not case-sensitive
12# -- except for ALL ABOARD and END OF THE LINE
13# ignore everything before ALL ABOARD
14# ignore everything after END OF THE LINE
15# (this means you can comment between these)
16# bf tf
17# + chug
18# - chugga
19# > choo
20# < choo choo
21# . click OR clickety
22# , clack
23# [ tickets please
24# ] your ticket please
25# syntax does NOT WRAP across line breaks
26# anything else is an error and DERAILS the train
27
28### Code:
29BEGIN {
30 # Configuration
31 BF_WIDTH = 42
32 BF_PRINT = 1
33 BF_PRINT_COMMENTS = 1
34 BF_COMMENTS_COMPACT = 1
35 BF_EXECUTE = 0
36 BF_OUTPUT = "/dev/stderr"
37 BF_MODE = "trainfuck"
38 process_commandline()
39 # Constants
40 EXE_NAME = (EXE_NAME ? EXE_NAME : "trainfuck")
41 ERR_SYNTAX = 1
42}
43
44BEGIN {
45 # State variables and beginning output
46 ABOARD = 0
47 FIRST_LINE = 1
48 OFS = "\t"
49}
50
51BF_MODE == "brainfuck" {
52 bf_program = bf_program $0
53 next
54}
55
56FIRST_LINE {
57 if (BF_PRINT_COMMENTS && first_line != "[") {
58 eprint("[")
59 }
60 eprint(first_line)
61 FIRST_LINE = 0
62}
63
64/^ALL ABOARD$/ {
65 if (! header && BF_PRINT_COMMENTS) {
66 eprint("]")
67 }
68 header++
69 ABOARD = 1
70 next
71}
72
73/^END OF THE LINE$/ {
74 ABOARD = 0
75 next
76}
77
78ABOARD {
79 gsub(/[[:space:]]/, "", $0)
80 buf = buf tf_convert(toupper($0))
81}
82
83! ABOARD && BF_PRINT_COMMENTS {
84 printbuf()
85 eprint($0)
86 buf = ""
87}
88
89END {
90 if (ABOARD) {
91 die("Didn't disembark from the train!", ERR_SYNTAX)
92 }
93 if (dead) {
94 exit dead
95 }
96 printbuf()
97 if (BF_EXECUTE) {
98 brainfuck(bf_program)
99 }
100}
101
102
103function brainfuck(buffer)
104{
105 split(buffer, bf, "")
106 i = 1
107 c = 1
108 for (n = 1; n < 30000; n++) {
109 tape[n] = 0
110 }
111 while (c <= length(bf)) {
112 # print i, tape[i], c, bf[c]
113 if (bf[c] == "<" && c > 1) {
114 i--
115 } else if (bf[c] == ">") {
116 i++
117 } else if (bf[c] == "+") {
118 tape[i]++
119 } else if (bf[c] == "-") {
120 tape[i]--
121 } else if (bf[c] == ".") {
122 printf "%c", tape[i]
123 } else if (bf[c] == ",") {
124 tape[i] = char2number(getchar())
125 } else if (bf[c] == "[") {
126 bracket = 1
127 if (! tape[i]) {
128 while (c <= length(bf)) {
129 c++
130 if (bf[c] == "[") {
131 bracket++
132 } else if (bf[c] == "]") {
133 bracket--
134 if (! bracket) {
135 break
136 }
137 }
138 }
139 if (c > length(bf)) {
140 die("Mismatched bracket: " c, ERR_SYNTAX)
141 }
142 }
143 } else if (bf[c] == "]") {
144 bracket = 1
145 if (tape[i]) {
146 while (c) {
147 c--
148 if (bf[c] == "]") {
149 bracket++
150 } else if (bf[c] == "[") {
151 bracket--
152 if (! bracket) {
153 break
154 }
155 }
156 }
157 if (! c) {
158 die("Mismatched bracket: " c, ERR_SYNTAX)
159 }
160 }
161 }
162 c++
163 }
164}
165
166function die(message, errnum)
167{
168 print(message) > "/dev/stderr"
169 dead = errnum
170}
171
172function eprint(message, suppress_newline)
173{
174 printf("%s" (suppress_newline ? "" : "\n"), message) > BF_OUTPUT
175}
176
177function getchar()
178{
179 system("stty raw")
180 cmd = "dd bs=1 count=1 2>/dev/null"
181 cmd | getline ch
182 close(cmd)
183 system("stty cooked")
184 return ch
185}
186
187function printbuf(newline)
188{
189 suppress_newline = BF_PRINT_COMMENTS && BF_COMMENTS_COMPACT
190 for (ss = 1; ss <= length(buf); ss += BF_WIDTH) {
191 eprint(substr(buf, ss, BF_WIDTH), suppress_newline)
192 suppress_newline = 0
193 }
194 bf_program = bf_program buf
195}
196
197function process_commandline()
198{
199 for (a in ARGV) {
200 if (ARGV[a] == "--") {
201 delete ARGV[a]
202 break
203 } else if (ARGV[a] == "-h" || ARGV[a] == "--help") {
204 usage()
205 } else if (ARGV[a] == "-w") {
206 delete ARGV[a]
207 BF_WIDTH = ARGV[++a]
208 delete ARGV[a]
209 } else if (ARGV[a] == "-o") {
210 delete ARGV[a]
211 BF_OUTPUT = ARGV[++a]
212 delete ARGV[a]
213 } else if (ARGV[a] == "-c" || ARGV[a] == "--comments") {
214 BF_PRINT_COMMENTS = 1
215 delete ARGV[a]
216 } else if (ARGV[a] == "-C" || ARGV[a] == "--no-comments") {
217 BF_PRINT_COMMENTS = 0
218 delete ARGV[a]
219 } else if (ARGV[a] == "-z" || ARGV[a] == "--compact") {
220 BF_COMMENTS_COMPACT = 1
221 delete ARGV[a]
222 } else if (ARGV[a] == "-Z" || ARGV[a] == "--no-compact") {
223 BF_COMMENTS_COMPACT = 0
224 delete ARGV[a]
225 } else if (ARGV[a] == "-x" || ARGV[a] == "--execute") {
226 BF_EXECUTE = 1
227 delete ARGV[a]
228 } else if (ARGV[a] == "-X" || ARGV[a] == "--no-execute") {
229 BF_EXECUTE = 0
230 delete ARGV[a]
231 } else if (ARGV[a] == "-t" || ARGV[a] == "--trainfuck") {
232 BF_MODE = "trainfuck"
233 BF_MODE_FORCE = 1
234 delete ARGV[a]
235 } else if (ARGV[a] == "-b" || ARGV[a] == "--brainfuck") {
236 BF_MODE = "brainfuck"
237 BF_MODE_FORCE = 1
238 delete ARGV[a]
239 }
240 }
241 if (! BF_MODE_FORCE) {
242 if (ARGV[1] ~ /\.tf$/ || ARGV[1] ~ /\.trainfuck$/) {
243 BF_MODE = "trainfuck"
244 } else if (ARGV[1] ~ /\.bf$/ || ARGV[1] ~ /\.brainfuck$/) {
245 BF_MODE = "brainfuck"
246 }
247 }
248 if (BF_MODE == "brainfuck") {
249 BF_EXECUTE = 1
250 }
251}
252
253function tf_convert(t)
254{
255 if (! match(t, /CHUGGA|CHUG|CHOO|CLICK|CLICKETY|CLACK|TICKETSPLEASE|YOURTICKETPLEASE|$/)) {
256 die("Derailed at input line " FNR, ERR_SYNTAX)
257 }
258 pre = substr(t, 1, RSTART - 1)
259 tok = substr(t, RSTART, RLENGTH)
260 pst = substr(t, RSTART + RLENGTH)
261 if (tok == "CHUGGA") { # needs to be first
262 tok = "-"
263 return (pre tok tf_convert(pst))
264 }
265 if (tok == "CHUG") {
266 tok = "+"
267 return (pre tok tf_convert(pst))
268 }
269 if (tok == "CHOO") {
270 if (substr(pst, 1, 4) == "CHOO") {
271 tok = "<"
272 sub(/CHOO/, "", pst)
273 } else {
274 tok = ">"
275 }
276 return (pre tok tf_convert(pst))
277 }
278 if (tok == "CLICK" || tok == "CLICKETY") {
279 tok = "."
280 return (pre tok tf_convert(pst))
281 }
282 if (tok == "CLACK") {
283 tok = ","
284 return (pre tok tf_convert(pst))
285 }
286 if (tok == "TICKETSPLEASE") {
287 tok = "["
288 return (pre tok tf_convert(pst))
289 }
290 if (tok == "YOURTICKETPLEASE") {
291 tok = "]"
292 return (pre tok tf_convert(pst))
293 }
294}
295
296function usage()
297{
298 eprint("TRAINFUCK: CHOO CHOO")
299 eprint("Usage: ")
300 eprint(EXE_NAME " -h|--help")
301 eprint(EXE_NAME " [-w WIDTH] [FLAGS...] INPUTFILE [-o OUTPUTFILE]")
302 eprint()
303 eprint("Parameters:")
304 eprint(" INPUTFILE\tThe trainfuck file to process.")
305 eprint("\t\tIf INPUTFILE ends in .tf or .trainfuck, it will be interpreted")
306 eprint("\t\tas a TRAINFUCK file; if it ends in .bf or .brainfuck, it will ")
307 eprint("\t\tbe interpreted as a BRAINFUCK file. Otherwise, the file will ")
308 eprint("\t\tbe assumed to be the default filetype (" BF_MODE ").")
309 eprint(" -w WIDTH\tSet the brainfuck output width (default: " BF_WIDTH ").")
310 eprint(" -o OUTPUTFILE\tWhere to send transpiled brainfuck (default: " BF_OUTPUT ").")
311 eprint()
312 eprint("FLAGS:")
313 eprint(" -h, --help\t\tShow this help")
314 eprint(" -c, --comments\t\tShow comments" (BF_PRINT_COMMENTS ? " (default)" : ""))
315 eprint(" -C, --no-comments\tHide comments" (BF_PRINT_COMMENTS ? "" : " (default)"))
316 eprint(" -z, --compact\t\tShow \"compact\" comments" (BF_COMMENTS_COMPACT ? " (default)" : ""))
317 eprint(" -Z, --no-compact\tShow \"wide\" comments" (BF_COMMENTS_COMPACT ? "" : " (default)"))
318 eprint(" -x, --execute\t\tExecute trainspiled brainfuck" (BF_EXECUTE ? " (default)" : ""))
319 eprint(" -X, --no-execute\tOnly trainspile, do not execute" (BF_EXECUTE ? "" : " (default)"))
320 exit
321}