main: add support for C source code output

This commit is contained in:
Zack Buhman 2023-08-24 09:33:27 +00:00
parent ad7e128bb4
commit c9a478f7df
2 changed files with 52 additions and 18 deletions

View File

@ -10,6 +10,13 @@ Usage:
scu-dsp-asm input-file.asm output-file.bin 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. If no arguments are given, scu-dsp-asm starts a basic REPL.
Wherever possible, scu-dsp-asm attempts to preserve compatibility with Wherever possible, scu-dsp-asm attempts to preserve compatibility with

View File

@ -4,6 +4,8 @@
#include <optional> #include <optional>
#include <bitset> #include <bitset>
#include <sstream> #include <sstream>
#include <array>
#include <iomanip>
#include "lexer.hpp" #include "lexer.hpp"
#include "token.hpp" #include "token.hpp"
@ -18,18 +20,35 @@ bool had_error = false;
} }
static void write(std::ostream& os, uint32_t v) template <typename T>
static std::array<T, 4> uint32_be(uint32_t v)
{ {
const char out[4] = { return {
static_cast<char>((v >> 24) & 0xff), static_cast<T>((v >> 24) & 0xff),
static_cast<char>((v >> 16) & 0xff), static_cast<T>((v >> 16) & 0xff),
static_cast<char>((v >> 8 ) & 0xff), static_cast<T>((v >> 8 ) & 0xff),
static_cast<char>((v >> 0 ) & 0xff), static_cast<T>((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<int>(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<char>(v);
os.write(out.data(), 4);
}
static void run(std::ostream& os, std::string source, bool hex_output, bool verbose)
{ {
using namespace dsp; using namespace dsp;
@ -43,16 +62,19 @@ static void run(std::ostream& os, std::string source)
ast::variables_t variables; ast::variables_t variables;
ast::resolver_t resolver(pc, variables); ast::resolver_t resolver(pc, variables);
while (auto stmt_o = pass1.statement()) { while (auto stmt_o = pass1.statement()) {
(*stmt_o)->accept(&printer); if (verbose) {
std::cout << std::endl << std::flush; (*stmt_o)->accept(&printer);
std::cout << std::endl << std::flush;
}
(*stmt_o)->accept(&resolver); (*stmt_o)->accept(&resolver);
} }
ast::emitter_t emitter(variables); ast::emitter_t emitter(variables);
while (auto stmt_o = pass2.statement()) { while (auto stmt_o = pass2.statement()) {
uint32_t output = (*stmt_o)->accept(&emitter); uint32_t output = (*stmt_o)->accept(&emitter);
if (output != 0xffff'ffff) { if (output != 0xffff'ffff) {
std::cout << std::bitset<32>(output) << std::endl; //std::cout << std::bitset<32>(output) << std::endl;
write(os, output); if (hex_output) write_hex(os, output);
else write_raw(os, output);
} }
} }
} }
@ -63,13 +85,12 @@ static void run_prompt()
std::string line; std::string line;
std::cout << prompt << std::flush; std::cout << prompt << std::flush;
while (std::getline(std::cin, line)) { while (std::getline(std::cin, line)) {
std::ostringstream os; run(std::cout, line, true, true);
run(os, line);
std::cout << prompt << std::flush; 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}; std::ifstream is {input_filename, std::ios::binary | std::ios::ate};
if (!is.is_open()) { if (!is.is_open()) {
@ -85,7 +106,7 @@ static int run_file(char const * const input_filename, char const * const output
} }
std::ostringstream os; std::ostringstream os;
run(os, buf); run(os, buf, hex_output, false);
if (!dsp::had_error) { if (!dsp::had_error) {
std::ofstream ofs {output_filename, std::ios::binary | std::ios::trunc}; 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[]) int main(const int argc, char const * const argv[])
{ {
const std::string c_source("-s");
switch (argc) { switch (argc) {
case 1: run_prompt(); return dsp::had_error; 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: 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; return -1;
} }
} }