#include #include "parser.h" #include #include #include #include #include #include static char preprocessed_fname[] = "/tmp/cxlppXXXXXX"; static char c_fname[] = "/tmp/cxlcXXXXXX.c"; static bool preprocessed_fname_created = false; static bool c_fname_created = false; bool preprocess(const char * input_fname) { int fd = mkstemp(preprocessed_fname); if (fd < 0) { perror("mkstemp"); return false; } preprocessed_fname_created = true; pid_t pid = fork(); if (pid < 0) { perror("fork"); return false; } else if (pid == 0) { dup2(fd, STDOUT_FILENO); close(fd); execlp("gcc", "gcc", "-x", "c", "-E", input_fname, NULL); } else { close(fd); waitpid(pid, NULL, 0); } return true; } void write_node(FILE * file, Node * node) { switch (node->type) { case NODE_TYPE_LIST: { bool space = false; for (auto subnode : *node->list) { if (space) { fprintf(file, " "); } write_node(file, subnode); space = true; } } break; case NODE_TYPE_TOKEN: fprintf(file, "%s", node->token.text->c_str()); if (*node->token.text == ";") { fprintf(file, "\n"); } break; } } bool emit_c(Node * node) { int fd = mkstemps(c_fname, 2); if (fd < 0) { perror("mkstemp"); return false; } FILE * file = fdopen(fd, "w"); c_fname_created = true; write_node(file, node); fclose(file); return true; } bool compile() { pid_t pid = fork(); if (pid < 0) { perror("fork"); return false; } else if (pid == 0) { execlp("gcc", "gcc", "-c", c_fname, "-o", "out.o", NULL); } else { waitpid(pid, NULL, 0); } return true; } int main(int argc, char * argv[]) { bool preprocess_successful = preprocess(argv[1]); if (preprocess_successful) { Node * node = parse(preprocessed_fname); if (node != nullptr) { if (emit_c(node)) { compile(); } } } /* Clean up temporary files. */ if (preprocessed_fname_created) { unlink(preprocessed_fname); } if (c_fname_created) { unlink(c_fname); } return 0; }