Add a parser to your MSDscript implementation, and change your msdscript
executable to accept any of the following flags:
--test
: run tests and exit with a 0 status if all pass, a non-zero status if there are any failures--interp
: accept a single expression on standard input, parse it, interp it, print the result to standard output, and print a newline, exiting with a 0 status--print
: accept a single expression on standard input and print it back out to standard output using the print
method of Expr
, print a newline, and exit with a 0 status--pretty-print
: accept a single expression on standard input and print it back out to standard output using the pretty_print
method of Expr
, print a newline, and exit with a 0 status; keep in mind that your pretty_print
method may expect a string output port, so you might instead use something like a to_pretty_string
method and then print the string to standard outputNote that if you run your interpreter at the command line and type input, you'll need to send an “end of file” after your expression with Ctl-D (typically on a new line). Otherwise, your parser will probably be trying to skip whitespace and still waiting for more input.
If interpreting the expression for --interp
triggers an error (for a variable that does not have an enclosing _let
), or if standard input does not have a syntactically valid expression for --interp
, --print
, or --pretty-print
, then print an error to standard output and exit with a non-0 status (maybe through an uncaught exception).
You can choose what happens if multiple flags or additional flags provided, as long as your msdscript
behaves as above for a single command-line argument.
To organize your code, you'll probably find it convenient to have a Expr *parse(std::istream &in)
function to call from main
plus a Expr *parse_str(std::string s)
wrapper for testing. Recall that Videos: I/O Testing / Accumulators shows how to test functions that take a std::istream
argument.