From c9a478f7df54a0b84a9ad4cdaee6d5b6e978ecc8 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Thu, 24 Aug 2023 09:33:27 +0000 Subject: [PATCH] main: add support for C source code output --- README.rst | 7 ++++++ main.cpp | 63 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/README.rst b/README.rst index bfd1227..06d30ba 100644 --- a/README.rst +++ b/README.rst @@ -10,6 +10,13 @@ Usage: scu-dsp-asm input-file.asm output-file.bin +Alternately, use the ``-s`` (source code) command-line argument to +emit a C-syntax source code fragment: + +.. code:: + + scu-dsp-asm -s input-file.asm output-file.inc + If no arguments are given, scu-dsp-asm starts a basic REPL. Wherever possible, scu-dsp-asm attempts to preserve compatibility with diff --git a/main.cpp b/main.cpp index d9aba38..f746505 100644 --- a/main.cpp +++ b/main.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "lexer.hpp" #include "token.hpp" @@ -18,18 +20,35 @@ bool had_error = false; } -static void write(std::ostream& os, uint32_t v) +template +static std::array uint32_be(uint32_t v) { - const char out[4] = { - static_cast((v >> 24) & 0xff), - static_cast((v >> 16) & 0xff), - static_cast((v >> 8 ) & 0xff), - static_cast((v >> 0 ) & 0xff), + return { + static_cast((v >> 24) & 0xff), + static_cast((v >> 16) & 0xff), + static_cast((v >> 8 ) & 0xff), + static_cast((v >> 0 ) & 0xff), }; - os.write(out, 4); } -static void run(std::ostream& os, std::string source) +static void write_hex(std::ostream& os, uint32_t v) +{ + const auto out = uint32_be(v); + os << std::setfill('0') << std::right << std::hex + << "0x" + << std::setw(2) << out[0] + << std::setw(2) << out[1] + << std::setw(2) << out[2] + << std::setw(2) << out[3] << ',' << std::endl; +} + +static void write_raw(std::ostream& os, uint32_t v) +{ + const auto out = uint32_be(v); + os.write(out.data(), 4); +} + +static void run(std::ostream& os, std::string source, bool hex_output, bool verbose) { using namespace dsp; @@ -43,16 +62,19 @@ static void run(std::ostream& os, std::string source) ast::variables_t variables; ast::resolver_t resolver(pc, variables); while (auto stmt_o = pass1.statement()) { - (*stmt_o)->accept(&printer); - std::cout << std::endl << std::flush; + if (verbose) { + (*stmt_o)->accept(&printer); + std::cout << std::endl << std::flush; + } (*stmt_o)->accept(&resolver); } ast::emitter_t emitter(variables); while (auto stmt_o = pass2.statement()) { uint32_t output = (*stmt_o)->accept(&emitter); if (output != 0xffff'ffff) { - std::cout << std::bitset<32>(output) << std::endl; - write(os, output); + //std::cout << std::bitset<32>(output) << std::endl; + if (hex_output) write_hex(os, output); + else write_raw(os, output); } } } @@ -63,13 +85,12 @@ static void run_prompt() std::string line; std::cout << prompt << std::flush; while (std::getline(std::cin, line)) { - std::ostringstream os; - run(os, line); + run(std::cout, line, true, true); std::cout << prompt << std::flush; } } -static int run_file(char const * const input_filename, char const * const output_filename) +static int run_file(char const * const input_filename, char const * const output_filename, bool hex_output) { std::ifstream is {input_filename, std::ios::binary | std::ios::ate}; if (!is.is_open()) { @@ -85,7 +106,7 @@ static int run_file(char const * const input_filename, char const * const output } std::ostringstream os; - run(os, buf); + run(os, buf, hex_output, false); if (!dsp::had_error) { std::ofstream ofs {output_filename, std::ios::binary | std::ios::trunc}; @@ -101,11 +122,17 @@ static int run_file(char const * const input_filename, char const * const output int main(const int argc, char const * const argv[]) { + const std::string c_source("-s"); + switch (argc) { case 1: run_prompt(); return dsp::had_error; - case 3: return run_file(argv[1], argv[2]); + case 3: return run_file(argv[1], argv[2], false); + case 4: + if (c_source.compare(argv[1]) == 0) return run_file(argv[2], argv[3], true); + else + [[fallthrough]]; default: - std::cerr << "Usage: " << argv[0] << " [input-filename output-filename]" << std::endl; + std::cerr << "Usage: " << argv[0] << " [[-s] input-filename output-filename]" << std::endl; return -1; } }