Skip to content

Instantly share code, notes, and snippets.

@willeccles
Last active July 20, 2019 23:31
Show Gist options
  • Save willeccles/abb39d8e49b0c49e7653bfefd5f85531 to your computer and use it in GitHub Desktop.
Save willeccles/abb39d8e49b0c49e7653bfefd5f85531 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <cstdlib>
#include <cstring>
int instr_mov(
const std::string& arg1,
const std::string& arg2,
const std::string& arg3,
const std::size_t& linenum,
std::ofstream& outfile
) {
if (arg1.empty()) {
std::cerr << "Error at line " << linenum << ": Not enough arguments to MOV\n";
return 1;
}
if (arg1[0] != '%') {
std::cerr << "Error at line " << linenum << ": Register expected\n";
return 1;
}
if (arg2.empty()) {
std::cerr << "Error at line " << linenum << ": Not enough arguments to MOV\n";
return 1;
}
if ((arg2[0] != '%' && arg2[0] != '$') || arg2.length() == 1) {
std::cerr << "Error at line " << linenum << ": Register or value expected\n";
return 1;
}
if (!arg3.empty()) {
std::cerr << "Error at line " << linenum << ": Too many arguments to MOV\n";
return 1;
}
if (arg1[0] == '%' && ((arg1[1] == 'r' && (arg1[2] >= '1' && arg1[2] <= '5')) || arg1.substr(1) == "acc" || arg1.substr(1) == "ret")) {
outfile << arg1.substr(1) << '=';
}
if (arg2[0] == '$') {
outfile << std::atoi(arg2.c_str() + 1) << ';';
}
else if (arg2[0] == '%' && ((arg2[1] == 'r' && (arg2[2] >= '1' && arg2[2] <= '5')) || arg2.substr(1) == "acc" || arg2.substr(1) == "ret")) {
outfile << arg2.substr(1) << ';';
}
return 0;
}
int main(int argc, char** argv) {
if (argc == 0) {
std::cerr << "Please provide an input file.\n";
return 1;
}
std::string filename(argv[1]);
std::ifstream infile(filename);
if (!infile) {
std::cerr << "Error opening file: " << filename << '\n';
return 1;
}
char tmpname[] = "/tmp/XXXXXX.c";
mkstemps(tmpname, 2);
std::ofstream outfile(tmpname);
if (!outfile) {
std::cerr << "Error creating temporary file: " << tmpname << '\n';
return 1;
}
std::cout << "Using temp file " << tmpname << '\n';
// write basic parts of the file to outfile
outfile << "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\nint acc,ret,r1,r2,r3,r4,r5;int main(void){";
std::string line, instr, arg1, arg2, arg3;
std::stringstream ss;
std::size_t linenum = 0ULL;
int status = 0;
while (std::getline(infile, line)) {
ss = std::stringstream(line);
ss >> instr;
if (!instr.empty()) {
linenum++;
} else {
break;
}
if (instr[0] == '#') { // ignore comments
continue;
}
// MOV instruction
if ("MOV" == instr) {
ss >> arg1 >> arg2 >> arg3;
status = instr_mov(arg1, arg2, arg3, linenum, outfile);
}
if (status) return status;
}
infile.close();
outfile << "printf(\"acc: %d\\nret: %d\\nr1: %d\\nr2: %d\\nr3: %d\\nr4: %d\\nr5: %d\\n\",acc,ret,r1,r2,r3,r4,r5);return ret;}\n";
outfile.close();
std::string cmd = "gcc " + std::string(tmpname) + " -o testout.o > comp.log 2>&1";
int s = system(cmd.c_str());
if (s) {
std::cerr << "Error compiling. Check comp.log for details.\n";
return 1;
}
std::cout << "Compiled " << argv[1] << " to testout.o\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment