bfscript2.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "includes.hpp"
  2. #include "functions.hpp"
  3. #include "color.hpp"
  4. #include "code_generator.hpp"
  5. #include "pointer.hpp"
  6. using namespace std;
  7. #define IS_SPECIAL_CHARACTER(c) (c == ' ' || c == '(' || c == ')' || c == ',' || c == '\"' || c == ';')
  8. struct Flags
  9. {
  10. public:
  11. bool valid; // Input files were given
  12. string invalid_reason;
  13. bool help;
  14. string ifile;
  15. string ofile;
  16. Flags(int argc, char** argv)
  17. {
  18. help = false;
  19. valid = true;
  20. if (argc == 1)
  21. {
  22. valid = false;
  23. invalid_reason = "no input files\n";
  24. }
  25. else if (argc == 2)
  26. {
  27. if ((string)argv[1] == "-h" || (string)argv[1] == "--help")
  28. {
  29. help = true;
  30. }
  31. else
  32. {
  33. ifile = argv[1];
  34. ofile = "out.bf";
  35. }
  36. }
  37. else if (argc == 3)
  38. {
  39. if ((string)argv[1] == "-o")
  40. {
  41. valid = false;
  42. invalid_reason = "no input files\n"; // Last argument is output file
  43. }
  44. else
  45. {
  46. if ((string)argv[1] == "-h" || (string)argv[1] == "--help" || (string)argv[2] == "-h" || (string)argv[2] == "--help")
  47. {
  48. help = true;
  49. }
  50. else
  51. {
  52. valid = false;
  53. invalid_reason = "invalid usage of translator\ntry bfscript -h or bfscript --help\n";
  54. }
  55. }
  56. }
  57. else if (argc == 4)
  58. {
  59. if ((string)argv[1] == "-o")
  60. {
  61. ofile = argv[2];
  62. ifile = argv[3];
  63. }
  64. else
  65. {
  66. if ((string)argv[2] == "-o")
  67. {
  68. ofile = argv[3];
  69. ifile = argv[1];
  70. }
  71. else
  72. {
  73. valid = false;
  74. invalid_reason = "invalid usage of translator\ntry bfscript -h or bfscript --help\n";
  75. }
  76. }
  77. }
  78. }
  79. };
  80. int main(int argc, char** argv)
  81. {
  82. Flags flags(argc, argv);
  83. if (!flags.valid)
  84. {
  85. cout<<BOLD_MSG("bfscript: ")<<ERROR_MSG("fatal error: ")<<flags.invalid_reason;
  86. cout<<"translation terminated\n";
  87. return -1;
  88. }
  89. if (flags.help)
  90. {
  91. std::cout<<"Usage: bfscript [options] file\n"<<
  92. "Examples:\n\n"<<
  93. "bfscript file.bfs\n"<<
  94. "# That command will translate file.bfs, and will write result in out.bf\n\n"<<
  95. "bfscript file.bfs -o file.bf\n"<<
  96. "# That command will translate file.bfs, and will write result in file.bf\n";
  97. return 0;
  98. }
  99. else
  100. {
  101. ifstream ifile(flags.ifile);
  102. if (!ifile.is_open())
  103. {
  104. cout<<BOLD_MSG("bfscript: ")<<ERROR_MSG("error: ")<<"input file not found\n";
  105. cout<<BOLD_MSG("bfscript: ")<<ERROR_MSG("fatal error: ")<<"no input files\n";
  106. cout<<"translation terminated\n";
  107. return -1;
  108. }
  109. string line;
  110. int line_num = 0;
  111. bool in_string = false;
  112. int current_cell = 0;
  113. string ident = "";
  114. string bfcode = "";
  115. vector<string> tokens;
  116. bool funcdef = false;
  117. int func_depth = 0;
  118. map<string, Pointer*> pointers;
  119. map<string, string> aliases;
  120. string current_operator = "";
  121. // Generating tokens
  122. while (getline(ifile, line))
  123. {
  124. ++line_num;
  125. if (in_string)
  126. {
  127. cout<<BOLD_MSG("bfscript: lexer: ")<<ERROR_MSG("error: ")<<"string on line "<<line_num-1<<" is not closed\n";
  128. cout<<BOLD_MSG("bfscript: lexer: ")<<"lexing analysis terminated\n";
  129. cout<<"translation terminated\n";
  130. return -2;
  131. }
  132. for (char c: line)
  133. {
  134. if (c == '#' && !in_string)
  135. {
  136. break; // Comment
  137. }
  138. if (c == '$' && !in_string)
  139. {
  140. tokens.push_back((string)"loadalias");
  141. ident = "";
  142. continue;
  143. }
  144. if (c == '=' && !in_string)
  145. {
  146. tokens.push_back((string)"assigment");
  147. ident = "";
  148. continue;
  149. }
  150. if (c == '&' && !in_string)
  151. {
  152. tokens.push_back((string)"bypointer");
  153. ident = "";
  154. continue;
  155. }
  156. if (c == '@' && !in_string)
  157. {
  158. tokens.push_back((string)"byarray");
  159. ident = "";
  160. continue;
  161. }
  162. if (c == '*' && !in_string)
  163. {
  164. tokens.push_back((string)"loadpointer");
  165. ident = "";
  166. continue;
  167. }
  168. if (c == ':' && !in_string)
  169. {
  170. tokens.push_back((string)"loadarray");
  171. ident = "";
  172. continue;
  173. }
  174. if (!IS_SPECIAL_CHARACTER(c) || (in_string && !(c == '\"')))
  175. {
  176. ident.push_back(c);
  177. }
  178. else if (c == '\"')
  179. {
  180. ident.push_back(c);
  181. if (!in_string)
  182. {
  183. in_string = true;
  184. }
  185. else
  186. {
  187. in_string = false;
  188. tokens.push_back(ident);
  189. ident = "";
  190. }
  191. }
  192. else
  193. {
  194. tokens.push_back(ident);
  195. ident = "";
  196. }
  197. }
  198. tokens.push_back((string)"newline");
  199. }
  200. tokens.push_back(ident); // I'm not know why, but last ident isn't pushing
  201. vector<string> tmp;
  202. for (int j = 0; j < tokens.size(); j++)
  203. {
  204. if (tokens[j] != "")
  205. {
  206. tmp.push_back(tokens[j]);
  207. }
  208. } // Deleting void strings
  209. /*for (auto s: tmp)
  210. {
  211. cout<<s<<endl; // Nice debug
  212. }//*/
  213. tokens = tmp;
  214. cout<<BOLD_MSG("bfscript: lexer: ")<<GOOD_MSG("lexing analisys finished\n");
  215. int i = 0;
  216. line_num = 1;
  217. bool error = false;
  218. for (i; i < tokens.size(); i++)
  219. {
  220. bfcode += generate(tokens, i, aliases, pointers, line_num, current_cell, error);
  221. if (error)
  222. {
  223. return -3;
  224. }
  225. }
  226. cout<<BOLD_MSG("bfscript: code generator: ")<<GOOD_MSG("code generating finished\n");
  227. ofstream ofile(flags.ofile);
  228. ofile<<bfcode;
  229. }
  230. return 0;
  231. }