Last active
July 20, 2019 23:31
-
-
Save willeccles/abb39d8e49b0c49e7653bfefd5f85531 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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