Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- namespace options {
- enum options {
- empty = 0,
- noflags = 00001,
- debug = 00002,
- help = 00004,
- ofile_set = 00010,
- nextarg_ofile = 00300,
- nextarg_bacon0 = 00500,
- nextarg_bacon1 = 00600,
- nextarg_bacon2 = 01100,
- nextarg_bacon3 = 01200,
- nextarg_bacon4 = 01400,
- nextarg_bacon5 = 02100,
- nextarg_bacon6 = 02200,
- nextarg_bacon7 = 02400,
- nextarg_bacon8 = 03000,
- nextarg_bacon9 = 04100,
- nextarg_bacon10 = 04200,
- nextarg_bacon11 = 04400,
- nextarg_bacon12 = 05000,
- nextarg_bacon13 = 06000,
- argumented = 07700
- };
- }
- #define fixop(t, o, t2) t& operator o##= (t& a, t2 b) {return a = (t)(a o b);}
- fixop(options::options, |, int)
- fixop(options::options, &, int)
- const int SIZ = 500;
- const char* polecenia[] = {
- "halt", // return 0
- "read", // scanf("%lld", &arg)
- "write", // printf("%lld\n", arg)
- "load", // *m = arg
- "store", // arg = *m
- "add", // *m += arg
- "sub", // *m -= arg
- "mult", // *m *= arg
- "div", // *m /= arg
- "jump", // goto arg
- "jgtz", // if (*m>0) goto arg
- "jzero" // if (!*m) goto arg
- };
- const char* formats[] = {
- "return 0;",
- "scanf(\"%%lld\", &%s);",
- "printf(\"%%lld\\n\", %s);",
- "*m = %s;",
- "%s = *m;",
- "*m += %s;",
- "*m -= %s;",
- "*m *= %s;",
- "*m /= %s;",
- "goto %s;",
- "if (*m>0) goto %s;",
- "if (!*m) goto %s;"
- };
- //BEGIN: trie_algo
- // #define i27 int[27]
- #ifndef i27
- template<typename T,int S>
- class simple_arr {
- T arr[S];
- public: T& operator[](int x) {
- return arr[x];
- }
- };
- typedef simple_arr<int,27> i27;
- #endif
- std::vector<i27> G(102);
- int lastfree;
- void trie_put(std::string s, int j) {
- int len=s.size(), u, i;
- G.resize(std::min(1000002, lastfree+len+3));
- for (i=u=0; i<len; i++) {
- if (G[u][s[i]-'a']==0)
- G[u][s[i]-'a']=++lastfree;
- u=G[u][s[i]-'a'];
- }
- G[u][26]=j;
- if (j==4)
- G[u]['a'-'a'] = G[G[G[1]['r'-'a']]['e'-'a']]['a'-'a'];
- }
- void trie_init() {
- static int s = sizeof(polecenia)/sizeof(*polecenia);
- for (int i=0; i<s; i++)
- trie_put(polecenia[i], i);
- }
- //END: trie_algo
- void build(std::string& s, int val, int a) {
- int i;
- if (s.size()) {
- for (i=s.size()-1; i>=0; i--) {
- if (s[i] != '_') return;
- s.erase(i);
- }
- }
- std::stringstream ss;
- for (i=0; i<a; i++)
- ss << "m[";
- if (a && val<0)
- val = 0; // SECURITY
- ss << val;
- for (i=0; i<a; i++)
- ss << "]";
- s = ss.str();
- }
- int process(FILE* ifile, FILE* ofile, options::options flags) {
- fputs("#include <bits/stdc++.h>\r\n", ofile);
- fputs("int main() {\r\n", ofile);
- fputs("\tlong long int m[1000002];\r\n", ofile);
- fflush(ofile);
- char s[SIZ+1];
- *s = '_';
- std::string arg;
- bool labelset;
- int argum, addr, node, i, mult;
- while (fgets(s+1, SIZ, ifile)) {
- labelset = false;
- addr = mult = 1;
- argum = node = 0;
- arg = "";
- for (i=0; s[i]; i++) {
- if (s[i] == '#') break;
- if (s[i] == ':') {
- argum = node = 0;
- arg = "";
- if (labelset)
- s[i] = '_'; // SECURITY
- else {
- s[i] = '\0';
- fprintf(ofile, "%s:", s);
- labelset = true;
- s[i] = '_';
- continue;
- }
- }
- /* BEGIN SECURITY */
- if (s[i]<'0' && s[i]!='-')
- s[i] = '_';
- if (s[i]>'9' && s[i]!='=' && s[i]<'A')
- s[i] = '_';
- if (s[i]>'Z' && s[i]<'^')
- s[i] = '_';
- if (s[i]>'z' || s[i] == '`')
- s[i] = '_';
- /* END SECURITY */
- if ('0'<=s[i] && s[i]<='9') {
- argum *= 10;
- argum += s[i]-'0';
- }
- if (s[i] == '-')
- mult = -1;
- if (s[i] == '^')
- addr++;
- if (s[i] == '=')
- addr = 0;
- if (G[node][26]>8) {
- if (('a'<=s[i] && s[i]<='z') || ('A'<=s[i] && s[i]<='Z') || s[i]=='_') {
- argum = 0;
- mult = 1;
- arg += s[i];
- }
- }
- else {
- if ('A'<=s[i] && s[i]<='Z' && G[node][26]<9)
- node = G[node][s[i]-'A'];
- if ('a'<=s[i] && s[i]<='z' && G[node][26]<9)
- node = G[node][s[i]-'a'];
- }
- }
- if (node) {
- build(arg, argum * mult, addr);
- fputc('\t', ofile);
- fprintf(ofile, formats[G[node][26]], arg.c_str());
- // fprintf(ofile, " // node %d, argum %d, addr %d, arg %s", node, argum*mult, addr, arg.c_str());
- }
- fprintf(ofile, "\r\n");
- }
- fputs("}\r\n", ofile);
- return 0;
- }
- int main(int argc, char *argv[]) {
- int i;
- FILE* ofile = stdout;
- FILE* ifile;
- std::vector<std::string> args, ifiles;
- options::options flags = options::empty;
- for (i=0; i<argc; i++)
- args.push_back(argv[i]);
- for (i=1; i<argc; i++) {
- if (flags & options::argumented) {
- if (flags & options::nextarg_ofile) {
- flags &= ~options::ofile_set;
- if (args[i] == "-")
- ofile = stdin;
- else {
- flags |= options::ofile_set;
- if (!(ofile = fopen(argv[i], "w"))) {
- fprintf(stderr, "Error: '%s' file cannot be opened for write\n", argv[i]);
- return 1;
- }
- }
- }
- flags &= ~options::argumented;
- continue;
- }
- if (!(flags & options::noflags)) {
- if (args[i] == "--") {
- flags |= options::noflags;
- continue;
- }
- if (args[i] == "-o" || args[i] == "--out") {
- if (flags & options::ofile_set) {
- fprintf(stderr, "Warning: multiple output files: only last one is used\n");
- fclose(ofile);
- }
- flags |= options::nextarg_ofile;
- continue;
- }
- if (args[i] == "-v" || args[i] == "--verbose" || args[i] == "--debug") {
- flags |= options::debug;
- continue;
- }
- if (args[i] == "-h" || args[i] == "--help") {
- flags |= options::help;
- continue;
- }
- }
- ifiles.push_back(args[i]);
- }
- if (flags & options::argumented) {
- fprintf(stderr, "Error: '%s' flag requires an argument!\n", args.back().c_str());
- return 1;
- }
- if (ifiles.size() == 0) {
- fprintf(stderr, "No files specified.\n");
- flags |= options::help;
- }
- if (flags & options::debug) {
- fprintf(stderr, "[DEBUG] Flags are %d (0x%x)\n", flags, flags);
- }
- if (flags & options::help) {
- fprintf(stderr, "Usage: %s [-v] [-o <outfile>] [--] <infile>\n", argv[0]);
- return 1;
- }
- trie_init();
- for (std::vector<std::string>::iterator it=ifiles.begin(); it!=ifiles.end(); it++) {
- ifile = fopen(it->c_str(), "r");
- if (!ifile) {
- fprintf(stderr, "Error: file '%s' could not be opened for read\n", it->c_str());
- continue;
- }
- i = process(ifile, ofile, flags);
- fclose(ifile);
- if (i) return 1;
- }
- if (flags & options::ofile_set)
- fclose(ofile);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment