CodeGenerator.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /*
  2. * Copyright (C) 2022 The V-Gears Team
  3. *
  4. * This file is part of V-Gears
  5. *
  6. * V-Gears is free software: you can redistribute it and/or modify it under
  7. * terms of the GNU General Public License as published by the Free Software
  8. * Foundation, version 3.0 (GPLv3) of the License.
  9. *
  10. * V-Gears is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #pragma once
  16. #include <ostream>
  17. #include <utility>
  18. #include <memory>
  19. #include <boost/intrusive_ptr.hpp>
  20. #include "DecompilerException.h"
  21. #include "Graph.h"
  22. #include "LuaLanguage.h"
  23. #include "Value.h"
  24. class Engine;
  25. class Function;
  26. const int INDENT_SPACES = 4; ///< How many spaces to use for each indent.
  27. /**
  28. * Different argument/operand orderings.
  29. */
  30. enum ARGUMENT_ORDER{
  31. /**
  32. * First argument is pushed to stack first.
  33. */
  34. FIFO_ARGUMENT_ORDER,
  35. /**
  36. * First argument is pushed to stack last.
  37. */
  38. LIFO_ARGUMENT_ORDER
  39. };
  40. /**
  41. * Base class for code generators.
  42. *
  43. * This is to be overriden by each engine.
  44. */
  45. class CodeGenerator {
  46. public:
  47. /**
  48. * Constructor
  49. *
  50. * @param[in] engine The engine used for the script.
  51. * @param[out] output The stream to output the code to.
  52. * @param[in] bin_order Order of arguments for binary operators.
  53. * @param[in] call_order Order of arguments for function calls.
  54. */
  55. CodeGenerator(
  56. Engine *engine, std::ostream &output, ARGUMENT_ORDER bin_order, ARGUMENT_ORDER call_order
  57. );
  58. /**
  59. * Destructor.
  60. *
  61. * Does nothing.
  62. */
  63. virtual ~CodeGenerator();
  64. /**
  65. * Retrieves the target language.
  66. */
  67. LuaLanguage& GetLanguage();
  68. /**
  69. * Writes a function call.
  70. *
  71. * @param[in] function_name The name of the function.
  72. * @param[in] param_format Characters indicating the parameter format.
  73. * 'b' for boolean parameters, 'n' for integers (treated as unsigned)
  74. * or 'f' for floats.
  75. * @param[in] params The list of parameters.
  76. */
  77. void WriteFunctionCall(
  78. std::string function_name, std::string param_format, const std::vector<ValuePtr>& params
  79. );
  80. /**
  81. * Generates code from the provided graph and outputs it to stdout.
  82. *
  83. * @param[in] insts The list of instructions.
  84. * @param[in] graph The annotated graph of the script.
  85. */
  86. virtual void Generate(InstVec& insts, const Graph &graph);
  87. /**
  88. * Adds a line of code to the current group.
  89. *
  90. * @param[in] line The line to add.
  91. * @param[in] unindent_before Whether or not to remove an indentation
  92. * level before the line. Defaults to false.
  93. * @param[in] indent_after Whether or not to add an indentation level
  94. * after the line. Defaults to false.
  95. */
  96. virtual void AddOutputLine(
  97. std::string line, bool unindent_before = false, bool indent_after = false
  98. );
  99. /**
  100. * Writes a comment line indicating an unimplemented opcode.
  101. *
  102. * @param[in] class_name The class where the instruction is. Unused.
  103. * @param[in] instruction The unimplemented instruction.
  104. */
  105. void WriteTodo(std::string class_name, std::string instruction);
  106. /**
  107. * Generate an assignment statement.
  108. *
  109. * @param[in] dst The variable being assigned to.
  110. * @param[in] src The value being assigned.
  111. */
  112. void WriteAssignment(ValuePtr dst, ValuePtr src);
  113. /**
  114. * Add an argument to the argument list.
  115. *
  116. * @param[in] arg The argument to add.
  117. */
  118. void AddArg(ValuePtr arg);
  119. /**
  120. * Process a single character of metadata.
  121. *
  122. * @param[in] inst The instruction being processed. Unused.
  123. * @param[in] c The character signifying the action to be taken. The
  124. * only valid one is 'p'.
  125. * @param[in] pos The position at which c occurred in the metadata.
  126. * Unused.
  127. */
  128. virtual void ProcessSpecialMetadata(const InstPtr inst, char c, int pos);
  129. /**
  130. * Retrieves the argument list.
  131. *
  132. * @return The argument list.
  133. */
  134. virtual ValueList GetArgList();
  135. /**
  136. * Retrieves the order of operands for binary operations.
  137. *
  138. * @return The order of operands
  139. */
  140. virtual ARGUMENT_ORDER GetBinaryOrder();
  141. protected:
  142. /**
  143. * Processes an instruction. Called by {@see Process()} for each
  144. * instruction. Call the base class implementation for opcodes not
  145. * handled by an implemented engine, or where the base class
  146. * implementation is preferable.
  147. *
  148. * @param[in] function The function the instruction is is.
  149. * @param[in] inst The instruction to process.
  150. * @param[in] insts Every instruction in the function.
  151. */
  152. void ProcessInst(Function& function, InstVec& insts, const InstPtr inst);
  153. /**
  154. * Processes an unconditional jump instruction. Called by
  155. * {@see ProcessInst()} for those instructions. Call the base class
  156. * implementation for opcodes not handled by an implemented engine,
  157. * or where the base class implementation is preferable.
  158. *
  159. * @param[in] function The function the instruction is is.
  160. * @param[in] inst The instruction to process.
  161. * @param[in] insts Every instruction in the function.
  162. */
  163. void ProcessUncondJumpInst(Function& function, InstVec& insts, const InstPtr inst);
  164. /**
  165. * Processes a conditional jump instruction. Called by
  166. * {@see ProcessInst()} for those instructions. Call the base class
  167. * implementation for opcodes not handled by an implemented engine,
  168. * or where the base class implementation is preferable.
  169. *
  170. * @param[in] inst The instruction to process.
  171. */
  172. void ProcessCondJumpInst(const InstPtr inst);
  173. /**
  174. * Indents a string according to the current indentation level.
  175. *
  176. * @param[in] s The string to indent.
  177. * @result The indented string.
  178. */
  179. std::string IndentString(std::string s);
  180. /**
  181. * Construct the signature for a function.
  182. *
  183. * @param[in] function Reference to the function to construct the
  184. * signature for.
  185. * @return For this base class, an empty string.
  186. */
  187. virtual std::string ConstructFuncSignature(const Function& function);
  188. /**
  189. * Adds lines to the script before a function.
  190. *
  191. * Called before writing a function start. For this base class, it
  192. * does nothing.
  193. *
  194. * @param[in] function The function about to start.
  195. */
  196. virtual void OnBeforeStartFunction(const Function& function);
  197. /**
  198. * Adds lines to the script at the end a function.
  199. *
  200. * Called after writing a function. For this base class, it adds a
  201. * closing bracer "}".
  202. *
  203. * @param[in] function The function about to end.
  204. */
  205. virtual void OnEndFunction(const Function& function);
  206. /**
  207. * Adds lines to the script before a function instructions.
  208. *
  209. * Called after writing a function start. For this base class, it
  210. * does nothing.
  211. *
  212. * @param[in] function The function starting.
  213. */
  214. virtual void OnStartFunction(const Function& function);
  215. /**
  216. * Checks if only required labels are to be written.
  217. *
  218. * @return Always false.
  219. */
  220. virtual bool OutputOnlyRequiredLabels() const;
  221. /**
  222. * Generates a pass.
  223. *
  224. * @param[in] insts The list of instructions.
  225. * @param[in] graph The code graph.
  226. * @todo Understand and explain.
  227. */
  228. void GeneratePass(InstVec& insts, const Graph& graph);
  229. /**
  230. * Indicates if a label is being processed.
  231. */
  232. bool is_label_pass_ = true;
  233. /**
  234. * The group currently being processed.
  235. */
  236. GroupPtr cur_group_;
  237. /**
  238. * The engine used for teh script.
  239. */
  240. Engine *engine_;
  241. /**
  242. * The stream to output the code to.
  243. */
  244. std::ostream &output_;
  245. /**
  246. * The stack currently being processed.
  247. */
  248. ValueStack stack_;
  249. /**
  250. * Current indentation level.
  251. */
  252. uint indent_level_;
  253. /**
  254. * Graph vertex currently being processed.
  255. */
  256. GraphVertex cur_vertex_;
  257. /**
  258. * The target language.
  259. */
  260. std::unique_ptr<LuaLanguage> target_lang_;
  261. private:
  262. /**
  263. * Processes a GraphVertex.
  264. *
  265. * @param[in] function The function to process.
  266. * @param[in] insts The list of instructions.
  267. * @param[in] vertex The vertex to process.
  268. */
  269. void Process(Function& function, InstVec& insts, GraphVertex vertex);
  270. /**
  271. * The annotated graph of the script.
  272. */
  273. Graph graph_;
  274. /**
  275. * Order of operands for binary operations.
  276. */
  277. const ARGUMENT_ORDER bin_order_;
  278. /**
  279. * Order of operands for call arguments.
  280. */
  281. const ARGUMENT_ORDER call_order_;
  282. /**
  283. * Lists of arguments to be built when processing function calls.
  284. */
  285. ValueList arg_list_;
  286. };