diff options
-rw-r--r-- | subx/001help.cc | 2 | ||||
-rw-r--r-- | subx/028translate.cc | 49 | ||||
-rw-r--r-- | subx/Readme.md | 4 | ||||
-rw-r--r-- | subx/apps/crenshaw2-1.subx | 2 | ||||
-rw-r--r-- | subx/apps/factorial.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex1.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex10.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex11.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex12.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex2.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex3.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex4.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex5.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex6.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex7.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex8.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex9.subx | 2 | ||||
-rwxr-xr-x | subx/gen | 4 | ||||
-rwxr-xr-x | subx/test_layers | 2 |
19 files changed, 58 insertions, 31 deletions
diff --git a/subx/001help.cc b/subx/001help.cc index efb3ac46..bf06aee3 100644 --- a/subx/001help.cc +++ b/subx/001help.cc @@ -73,7 +73,7 @@ void init_help() { " subx --help\n" "- Convert a textual SubX program into a standard ELF binary that you can\n" " run on your computer:\n" - " subx translate <input 'source' file> <output ELF binary>\n" + " subx translate <input 'source' file> -o <output ELF binary>\n" "- Run a SubX binary using SubX itself (for better error messages):\n" " subx run <ELF binary>\n" "Add '--trace' to any of these commands to also emit a trace, for debugging purposes.\n" diff --git a/subx/028translate.cc b/subx/028translate.cc index 174a863a..303d6219 100644 --- a/subx/028translate.cc +++ b/subx/028translate.cc @@ -19,30 +19,57 @@ :(before "End Main") if (is_equal(argv[1], "translate")) { START_TRACING_UNTIL_END_OF_SCOPE; - assert(argc > 3); reset(); program p; - ifstream fin(argv[2]); - if (!fin) { - cerr << "could not open " << argv[2] << '\n'; - return 1; + string output_filename; + for (int i = /*skip 'subx translate'*/2; i < argc; ++i) { + if (is_equal(argv[i], "-o")) { + ++i; + if (i >= argc) { + print_translate_usage(); + cerr << "'-o' must be followed by a filename to write results to\n"; + exit(1); + } + output_filename = argv[i]; + } + else { + ifstream fin(argv[i]); + if (!fin) { + cerr << "could not open " << argv[i] << '\n'; + return 1; + } + parse(fin, p); + if (trace_contains_errors()) return 1; + } + } + if (p.segments.empty()) { + print_translate_usage(); + cerr << "nothing to do; must provide at least one file to read\n"; + exit(1); + } + if (output_filename.empty()) { + print_translate_usage(); + cerr << "must provide a filename to write to using '-o'\n"; + exit(1); } - parse(fin, p); - if (trace_contains_errors()) return 1; transform(p); if (trace_contains_errors()) return 1; - save_elf(p, argv[3]); + save_elf(p, output_filename); if (trace_contains_errors()) { - unlink(argv[3]); + unlink(output_filename.c_str()); return 1; } return 0; } :(code) +void print_translate_usage() { + cerr << "Usage: subx translate <input.subx> -o <output_ELF>\n"; +} + // write out a program to a bare-bones ELF file -void save_elf(const program& p, const char* filename) { - ofstream out(filename, ios::binary); +void save_elf(const program& p, const string& filename) { + ofstream out(filename.c_str(), ios::binary); write_elf_header(out, p); for (size_t i = 0; i < p.segments.size(); ++i) write_segment(p.segments.at(i), out); diff --git a/subx/Readme.md b/subx/Readme.md index 67a7e5e1..baba8e1b 100644 --- a/subx/Readme.md +++ b/subx/Readme.md @@ -111,7 +111,7 @@ Running `subx` will transparently compile it as necessary. * `subx test`: runs all automated tests. -* `subx translate <input file> <output ELF binary>`: translates a text file +* `subx translate <input file> -o <output ELF binary>`: translates a text file containing hex bytes and macros into an executable ELF binary. * `subx run <ELF binary>`: simulates running the ELF binaries emitted by `subx @@ -123,7 +123,7 @@ Putting them together, build and run one of the example programs: <img alt='apps/factorial.subx' src='../html/subx/factorial.png'> ``` -$ ./subx translate apps/factorial.subx apps/factorial +$ ./subx translate apps/factorial.subx -o apps/factorial $ ./subx run apps/factorial # returns the factorial of 5 $ echo $? 120 diff --git a/subx/apps/crenshaw2-1.subx b/subx/apps/crenshaw2-1.subx index b1df5889..ef0ee70e 100644 --- a/subx/apps/crenshaw2-1.subx +++ b/subx/apps/crenshaw2-1.subx @@ -2,7 +2,7 @@ # corresponds to the section "single digits" in https://compilers.iecc.com/crenshaw/tutor2.txt # # To run: -# $ subx translate apps/crenshaw2.1.subx crenshaw 2.1 +# $ subx translate apps/crenshaw2.1.subx -o crenshaw 2.1 # $ echo '3' |subx run apps/crenshaw2.1 |xxd - # Expected output: # TODO diff --git a/subx/apps/factorial.subx b/subx/apps/factorial.subx index b4f8867e..80ff7418 100644 --- a/subx/apps/factorial.subx +++ b/subx/apps/factorial.subx @@ -1,7 +1,7 @@ ## compute the factorial of 5, and return the result in the exit code # # To run: -# $ subx translate apps/factorial.subx apps/factorial +# $ subx translate apps/factorial.subx -o apps/factorial # $ subx run apps/factorial # Expected result: # $ echo $? diff --git a/subx/examples/ex1.subx b/subx/examples/ex1.subx index a355ef6b..ae909777 100644 --- a/subx/examples/ex1.subx +++ b/subx/examples/ex1.subx @@ -2,7 +2,7 @@ # Just return 42. # # To run: -# $ subx translate ex1.2.subx ex1 +# $ subx translate ex1.2.subx -o ex1 # $ subx run ex1 # Expected result: # $ echo $? diff --git a/subx/examples/ex10.subx b/subx/examples/ex10.subx index 92e9f1f4..64a92f2c 100644 --- a/subx/examples/ex10.subx +++ b/subx/examples/ex10.subx @@ -1,7 +1,7 @@ ## String comparison: return 1 iff the two args passed in at the commandline are equal. # # To run: -# $ subx translate ex10.subx ex10 +# $ subx translate ex10.subx -o ex10 # $ subx run ex10 abc abd # Expected result: # $ echo $? diff --git a/subx/examples/ex11.subx b/subx/examples/ex11.subx index 8c2c9625..0159be69 100644 --- a/subx/examples/ex11.subx +++ b/subx/examples/ex11.subx @@ -6,7 +6,7 @@ # (length-prefixed) literal string "target". # # To run: -# $ subx translate ex11.subx ex11 +# $ subx translate ex11.subx -o ex11 # $ subx run ex11 # runs a series of tests # ...... # all tests pass # diff --git a/subx/examples/ex12.subx b/subx/examples/ex12.subx index 50c57928..86250d4d 100644 --- a/subx/examples/ex12.subx +++ b/subx/examples/ex12.subx @@ -2,7 +2,7 @@ # Create a new segment using mmap, save the address, write to it. # # To run: -# $ subx translate ex12.subx ex12 +# $ subx translate ex12.subx -o ex12 # $ subx run ex12 # You shouldn't get a segmentation fault. diff --git a/subx/examples/ex2.subx b/subx/examples/ex2.subx index e0c76712..62294b83 100644 --- a/subx/examples/ex2.subx +++ b/subx/examples/ex2.subx @@ -1,7 +1,7 @@ ## add 1 and 1, and return the result in the exit code # # To run: -# $ subx translate ex2.subx ex2 +# $ subx translate ex2.subx -o ex2 # $ subx run ex2 # Expected result: # $ echo $? diff --git a/subx/examples/ex3.subx b/subx/examples/ex3.subx index 30a8d5d3..50edd923 100644 --- a/subx/examples/ex3.subx +++ b/subx/examples/ex3.subx @@ -1,7 +1,7 @@ ## add the first 10 numbers, and return the result in the exit code # # To run: -# $ subx translate ex3.subx ex3 +# $ subx translate ex3.subx -o ex3 # $ subx run ex3 # Expected result: # $ echo $? diff --git a/subx/examples/ex4.subx b/subx/examples/ex4.subx index 810278e6..89926a62 100644 --- a/subx/examples/ex4.subx +++ b/subx/examples/ex4.subx @@ -1,7 +1,7 @@ ## read a character from stdin, save it to a global, write it to stdout # # To run: -# $ subx translate ex4.subx ex4 +# $ subx translate ex4.subx -o ex4 # $ subx run ex4 == code diff --git a/subx/examples/ex5.subx b/subx/examples/ex5.subx index 51bc19a0..e00289a2 100644 --- a/subx/examples/ex5.subx +++ b/subx/examples/ex5.subx @@ -1,7 +1,7 @@ ## read a character from stdin, save it to a local on the stack, write it to stdout # # To run: -# $ subx translate ex5.subx ex5 +# $ subx translate ex5.subx -o ex5 # $ subx run ex5 == code diff --git a/subx/examples/ex6.subx b/subx/examples/ex6.subx index 0213ad7e..f9adcc5a 100644 --- a/subx/examples/ex6.subx +++ b/subx/examples/ex6.subx @@ -1,7 +1,7 @@ ## print out a (global variable) string to stdout # # To run: -# $ subx translate ex6.subx ex6 +# $ subx translate ex6.subx -o ex6 # $ subx run ex6 # Hello, world! diff --git a/subx/examples/ex7.subx b/subx/examples/ex7.subx index a1bb19c8..b6dc639a 100644 --- a/subx/examples/ex7.subx +++ b/subx/examples/ex7.subx @@ -4,7 +4,7 @@ # the character read. # # To run: -# $ subx translate ex8.subx ex8 +# $ subx translate ex8.subx -o ex8 # $ subx run ex8 # Expected result: # $ echo $? diff --git a/subx/examples/ex8.subx b/subx/examples/ex8.subx index 1a094b89..ba0ddcd3 100644 --- a/subx/examples/ex8.subx +++ b/subx/examples/ex8.subx @@ -1,7 +1,7 @@ ## Example reading commandline arguments: compute length of first arg. # # To run: -# $ subx translate ex8.subx ex8 +# $ subx translate ex8.subx -o ex8 # $ subx run ex8 abc de fghi # Expected result: # $ echo $? diff --git a/subx/examples/ex9.subx b/subx/examples/ex9.subx index 8c0fba29..3590839f 100644 --- a/subx/examples/ex9.subx +++ b/subx/examples/ex9.subx @@ -3,7 +3,7 @@ # letter of second arg. # # To run: -# $ subx translate ex9.subx ex9 +# $ subx translate ex9.subx -o ex9 # $ subx run ex9 z x # Expected result: # $ echo $? diff --git a/subx/gen b/subx/gen index 464506b3..a73d763b 100755 --- a/subx/gen +++ b/subx/gen @@ -3,9 +3,9 @@ if [[ $1 == 'ex'* ]] then - CFLAGS=-g subx translate examples/$1.subx examples/`echo $1 |sed 's/\..*//'` + CFLAGS=-g subx translate examples/$1.subx -o examples/`echo $1 |sed 's/\..*//'` exit $? fi -CFLAGS=-g subx translate apps/$1.subx apps/`echo $1 |sed 's/\..*//'` +CFLAGS=-g subx translate apps/$1.subx -o apps/`echo $1 |sed 's/\..*//'` exit $? diff --git a/subx/test_layers b/subx/test_layers index 12867b21..b1a2b3a6 100755 --- a/subx/test_layers +++ b/subx/test_layers @@ -15,7 +15,7 @@ for f in examples/ex*.subx apps/*.subx do echo checking $f target=`echo $f |sed 's/\..*//'` - CFLAGS=-g ./subx translate $f $target + CFLAGS=-g ./subx translate $f -o $target git diff --quiet $target || exit 1 echo $target generated as expected done |