Arusekk

ram2c.cpp

Sep 20th, 2015
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.49 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. namespace options {
  4.   enum options {
  5.     empty = 0,
  6.     noflags = 00001,
  7.     debug = 00002,
  8.     help = 00004,
  9.     ofile_set = 00010,
  10.     nextarg_ofile = 00300,
  11.     nextarg_bacon0 = 00500,
  12.     nextarg_bacon1 = 00600,
  13.     nextarg_bacon2 = 01100,
  14.     nextarg_bacon3 = 01200,
  15.     nextarg_bacon4 = 01400,
  16.     nextarg_bacon5 = 02100,
  17.     nextarg_bacon6 = 02200,
  18.     nextarg_bacon7 = 02400,
  19.     nextarg_bacon8 = 03000,
  20.     nextarg_bacon9 = 04100,
  21.     nextarg_bacon10 = 04200,
  22.     nextarg_bacon11 = 04400,
  23.     nextarg_bacon12 = 05000,
  24.     nextarg_bacon13 = 06000,
  25.     argumented = 07700
  26.   };
  27. }
  28.  
  29. #define fixop(t, o, t2) t& operator o##= (t& a, t2 b) {return a = (t)(a o b);}
  30. fixop(options::options, |, int)
  31. fixop(options::options, &, int)
  32.  
  33. const int SIZ = 500;
  34.  
  35. const char* polecenia[] = {
  36.   "halt", // return 0
  37.   "read", // scanf("%lld", &arg)
  38.   "write", // printf("%lld\n", arg)
  39.   "load", // *m = arg
  40.   "store", // arg = *m
  41.   "add", // *m += arg
  42.   "sub", // *m -= arg
  43.   "mult", // *m *= arg
  44.   "div", // *m /= arg
  45.   "jump", // goto arg
  46.   "jgtz", // if (*m>0) goto arg
  47.   "jzero" // if (!*m) goto arg
  48. };
  49.  
  50. const char* formats[] = {
  51.   "return 0;",
  52.   "scanf(\"%%lld\", &%s);",
  53.   "printf(\"%%lld\\n\", %s);",
  54.   "*m = %s;",
  55.   "%s = *m;",
  56.   "*m += %s;",
  57.   "*m -= %s;",
  58.   "*m *= %s;",
  59.   "*m /= %s;",
  60.   "goto %s;",
  61.   "if (*m>0) goto %s;",
  62.   "if (!*m) goto %s;"
  63. };
  64.  
  65. //BEGIN: trie_algo
  66.  
  67. // #define i27 int[27]
  68. #ifndef i27
  69. template<typename T,int S>
  70. class simple_arr {
  71.   T arr[S];
  72.   public: T& operator[](int x) {
  73.     return arr[x];
  74.   }
  75. };
  76. typedef simple_arr<int,27> i27;
  77. #endif
  78.  
  79. std::vector<i27> G(102);
  80. int lastfree;
  81.  
  82. void trie_put(std::string s, int j) {
  83.   int len=s.size(), u, i;
  84.   G.resize(std::min(1000002, lastfree+len+3));
  85.   for (i=u=0; i<len; i++) {
  86.     if (G[u][s[i]-'a']==0)
  87.       G[u][s[i]-'a']=++lastfree;
  88.     u=G[u][s[i]-'a'];
  89.   }
  90.   G[u][26]=j;
  91.   if (j==4)
  92.     G[u]['a'-'a'] = G[G[G[1]['r'-'a']]['e'-'a']]['a'-'a'];
  93. }
  94.  
  95. void trie_init() {
  96.   static int s = sizeof(polecenia)/sizeof(*polecenia);
  97.   for (int i=0; i<s; i++)
  98.     trie_put(polecenia[i], i);
  99. }
  100.  
  101. //END: trie_algo
  102.  
  103. void build(std::string& s, int val, int a) {
  104.   int i;
  105.   if (s.size()) {
  106.     for (i=s.size()-1; i>=0; i--) {
  107.       if (s[i] != '_') return;
  108.       s.erase(i);
  109.     }
  110.   }
  111.   std::stringstream ss;
  112.   for (i=0; i<a; i++)
  113.     ss << "m[";
  114.   if (a && val<0)
  115.     val = 0; // SECURITY
  116.   ss << val;
  117.   for (i=0; i<a; i++)
  118.     ss << "]";
  119.   s = ss.str();
  120. }
  121.  
  122. int process(FILE* ifile, FILE* ofile, options::options flags) {
  123.   fputs("#include <bits/stdc++.h>\r\n", ofile);
  124.   fputs("int main() {\r\n", ofile);
  125.   fputs("\tlong long int m[1000002];\r\n", ofile);
  126.   fflush(ofile);
  127.   char s[SIZ+1];
  128.   *s = '_';
  129.   std::string arg;
  130.   bool labelset;
  131.   int argum, addr, node, i, mult;
  132.   while (fgets(s+1, SIZ, ifile)) {
  133.     labelset = false;
  134.     addr = mult = 1;
  135.     argum = node = 0;
  136.     arg = "";
  137.     for (i=0; s[i]; i++) {
  138.       if (s[i] == '#') break;
  139.       if (s[i] == ':') {
  140.     argum = node = 0;
  141.     arg = "";
  142.     if (labelset)
  143.       s[i] = '_'; // SECURITY
  144.     else {
  145.       s[i] = '\0';
  146.       fprintf(ofile, "%s:", s);
  147.       labelset = true;
  148.       s[i] = '_';
  149.       continue;
  150.     }
  151.       }
  152.       /* BEGIN SECURITY */
  153.       if (s[i]<'0' && s[i]!='-')
  154.     s[i] = '_';
  155.       if (s[i]>'9' && s[i]!='=' && s[i]<'A')
  156.     s[i] = '_';
  157.       if (s[i]>'Z' && s[i]<'^')
  158.     s[i] = '_';
  159.       if (s[i]>'z' || s[i] == '`')
  160.     s[i] = '_';
  161.       /* END SECURITY */
  162.       if ('0'<=s[i] && s[i]<='9') {
  163.     argum *= 10;
  164.     argum += s[i]-'0';
  165.       }
  166.       if (s[i] == '-')
  167.     mult = -1;
  168.       if (s[i] == '^')
  169.     addr++;
  170.       if (s[i] == '=')
  171.     addr = 0;
  172.       if (G[node][26]>8) {
  173.     if (('a'<=s[i] && s[i]<='z') || ('A'<=s[i] && s[i]<='Z') || s[i]=='_') {
  174.       argum = 0;
  175.       mult = 1;
  176.       arg += s[i];
  177.     }
  178.       }
  179.       else {
  180.     if ('A'<=s[i] && s[i]<='Z' && G[node][26]<9)
  181.       node = G[node][s[i]-'A'];
  182.     if ('a'<=s[i] && s[i]<='z' && G[node][26]<9)
  183.       node = G[node][s[i]-'a'];
  184.       }
  185.     }
  186.     if (node) {
  187.       build(arg, argum * mult, addr);
  188.       fputc('\t', ofile);
  189.       fprintf(ofile, formats[G[node][26]], arg.c_str());
  190. //       fprintf(ofile, " // node %d, argum %d, addr %d, arg %s", node, argum*mult, addr, arg.c_str());
  191.     }
  192.     fprintf(ofile, "\r\n");
  193.   }
  194.   fputs("}\r\n", ofile);
  195.   return 0;
  196. }
  197.  
  198. int main(int argc, char *argv[]) {
  199.   int i;
  200.   FILE* ofile = stdout;
  201.   FILE* ifile;
  202.   std::vector<std::string> args, ifiles;
  203.   options::options flags = options::empty;
  204.   for (i=0; i<argc; i++)
  205.     args.push_back(argv[i]);
  206.  
  207.   for (i=1; i<argc; i++) {
  208.     if (flags & options::argumented) {
  209.       if (flags & options::nextarg_ofile) {
  210.     flags &= ~options::ofile_set;
  211.     if (args[i] == "-")
  212.       ofile = stdin;
  213.     else {
  214.       flags |= options::ofile_set;
  215.       if (!(ofile = fopen(argv[i], "w"))) {
  216.         fprintf(stderr, "Error: '%s' file cannot be opened for write\n", argv[i]);
  217.         return 1;
  218.       }
  219.     }
  220.       }
  221.       flags &= ~options::argumented;
  222.       continue;
  223.     }
  224.  
  225.     if (!(flags & options::noflags)) {
  226.       if (args[i] == "--") {
  227.     flags |= options::noflags;
  228.     continue;
  229.       }
  230.  
  231.       if (args[i] == "-o" || args[i] == "--out") {
  232.     if (flags & options::ofile_set) {
  233.       fprintf(stderr, "Warning: multiple output files: only last one is used\n");
  234.       fclose(ofile);
  235.     }
  236.     flags |= options::nextarg_ofile;
  237.     continue;
  238.       }
  239.       if (args[i] == "-v" || args[i] == "--verbose" || args[i] == "--debug") {
  240.     flags |= options::debug;
  241.     continue;
  242.       }
  243.       if (args[i] == "-h" || args[i] == "--help") {
  244.     flags |= options::help;
  245.     continue;
  246.       }
  247.     }
  248.     ifiles.push_back(args[i]);
  249.   }
  250.   if (flags & options::argumented) {
  251.     fprintf(stderr, "Error: '%s' flag requires an argument!\n", args.back().c_str());
  252.     return 1;
  253.   }
  254.   if (ifiles.size() == 0) {
  255.     fprintf(stderr, "No files specified.\n");
  256.     flags |= options::help;
  257.   }
  258.   if (flags & options::debug) {
  259.     fprintf(stderr, "[DEBUG] Flags are %d (0x%x)\n", flags, flags);
  260.   }
  261.   if (flags & options::help) {
  262.     fprintf(stderr, "Usage: %s [-v] [-o <outfile>] [--] <infile>\n", argv[0]);
  263.     return 1;
  264.   }
  265.   trie_init();
  266.   for (std::vector<std::string>::iterator it=ifiles.begin(); it!=ifiles.end(); it++) {
  267.     ifile = fopen(it->c_str(), "r");
  268.     if (!ifile) {
  269.       fprintf(stderr, "Error: file '%s' could not be opened for read\n", it->c_str());
  270.       continue;
  271.     }
  272.     i = process(ifile, ofile, flags);
  273.     fclose(ifile);
  274.     if (i) return 1;
  275.   }
  276.   if (flags & options::ofile_set)
  277.     fclose(ofile);
  278.  
  279.   return 0;
  280. }
Advertisement
Add Comment
Please, Sign In to add comment