CodeGenerator.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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 "LuaLanguage.h"
  21. #include "graph.h"
  22. #include "value.h"
  23. #include "unknown_opcode_exception.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 engine[in] The engine used for the script.
  51. * @param output[out] The stream to output the code to.
  52. * @param bin_order[in] Order of arguments for binary operators.
  53. * @param call_order[in] 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 function_name[in] The name of the function.
  72. * @param param_format[in] Characters indicating the parameter format.
  73. * 'b' for boolean parameters, 'n' for integers (treated as unsigned)
  74. * or 'f' for floats.
  75. * @param params[in] 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 insts[in] The list of instructions.
  84. * @param graph[in] 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 line[in] The line to add.
  91. * @param unindent_before[in] Whether or not to remove an indentation
  92. * level before the line. Defaults to false.
  93. * @param indent_after[in] 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 code_gen[in|out] The code generator.
  103. * @param class_name[in] The class where the instruction is. Unused.
  104. * @param instruction[in] The unimplemented instruction.
  105. */
  106. void WriteTodo(std::string class_name, std::string instruction);
  107. /**
  108. * Generate an assignment statement.
  109. *
  110. * @param dst[in] The variable being assigned to.
  111. * @param src[in] The value being assigned.
  112. */
  113. void WriteAssignment(ValuePtr dst, ValuePtr src);
  114. /**
  115. * Add an argument to the argument list.
  116. *
  117. * @param arg[in] The argument to add.
  118. */
  119. void AddArg(ValuePtr arg);
  120. /**
  121. * Process a single character of metadata.
  122. *
  123. * @param inst[in] The instruction being processed. Unused.
  124. * @param c[in] The character signifying the action to be taken. The
  125. * only valid one is 'p'.
  126. * @param pos[in] The position at which c occurred in the metadata.
  127. * Unused.
  128. */
  129. virtual void ProcessSpecialMetadata(const InstPtr inst, char c, int pos);
  130. /**
  131. * Retrieves the argument list.
  132. *
  133. * @return The argument list.
  134. */
  135. virtual ValueList GetArgList();
  136. /**
  137. * Retrieves the order of operands for binary operations.
  138. *
  139. * @return The order of operands
  140. */
  141. virtual ARGUMENT_ORDER GetBinaryOrder();
  142. protected:
  143. /**
  144. * Processes an instruction. Called by {@see Process()} for each
  145. * instruction. Call the base class implementation for opcodes not
  146. * handled by an implemented engine, or where the base class
  147. * implementation is preferable.
  148. *
  149. * @param function[in] The function the instruction is is.
  150. * @param inst[in] The instruction to process.
  151. * @param insts[in] Every instruction in the function.
  152. */
  153. void ProcessInst(Function& function, InstVec& insts, const InstPtr inst);
  154. /**
  155. * Processes an unconditional jump instruction. Called by
  156. * {@see ProcessInst()} for those instructions. Call the base class
  157. * implementation for opcodes not handled by an implemented engine,
  158. * or where the base class implementation is preferable.
  159. *
  160. * @param function[in] The function the instruction is is.
  161. * @param inst[in] The instruction to process.
  162. * @param insts[in] Every instruction in the function.
  163. */
  164. void ProcessUncondJumpInst(Function& function, InstVec& insts, const InstPtr inst);
  165. /**
  166. * Processes a conditional jump instruction. Called by
  167. * {@see ProcessInst()} for those instructions. Call the base class
  168. * implementation for opcodes not handled by an implemented engine,
  169. * or where the base class implementation is preferable.
  170. *
  171. * @param inst[in] The instruction to process.
  172. */
  173. void ProcessCondJumpInst(const InstPtr inst);
  174. /**
  175. * Indents a string according to the current indentation level.
  176. *
  177. * @param s[in] The string to indent.
  178. * @result The indented string.
  179. */
  180. std::string IndentString(std::string s);
  181. /**
  182. * Construct the signature for a function.
  183. *
  184. * @param function[in] Reference to the function to construct the
  185. * signature for.
  186. * @return For this base class, an empty string.
  187. */
  188. virtual std::string ConstructFuncSignature(const Function& function);
  189. /**
  190. * Adds lines to the script before a function.
  191. *
  192. * Called before writing a function start. For this base class, it
  193. * does nothing.
  194. *
  195. * @param function[in] The function about to start.
  196. */
  197. virtual void OnBeforeStartFunction(const Function& function);
  198. /**
  199. * Adds lines to the script at the end a function.
  200. *
  201. * Called after writing a function. For this base class, it adds a
  202. * closing bracer "}".
  203. *
  204. * @param function[in] The function about to end.
  205. */
  206. virtual void OnEndFunction(const Function& function);
  207. /**
  208. * Adds lines to the script before a function instructions.
  209. *
  210. * Called after writing a function start. For this base class, it
  211. * does nothing.
  212. *
  213. * @param function[in] The function starting.
  214. */
  215. virtual void OnStartFunction(const Function& function);
  216. /**
  217. * Checks if only required labels are to be written.
  218. *
  219. * @return Always false.
  220. */
  221. virtual bool OutputOnlyRequiredLabels() const;
  222. /**
  223. * Generates a pass.
  224. *
  225. * @param insts[in] The list of instructions.
  226. * @param graph[in] The code graph.
  227. * @todo Understand and explain.
  228. */
  229. void GeneratePass(InstVec& insts, const Graph& g);
  230. /**
  231. * Indicates if a label is being processed.
  232. */
  233. bool is_label_pass_ = true;
  234. /**
  235. * The group currently being processed.
  236. */
  237. GroupPtr cur_group_;
  238. /**
  239. * The engine used for teh script.
  240. */
  241. Engine *engine_;
  242. /**
  243. * The stream to output the code to.
  244. */
  245. std::ostream &output_;
  246. /**
  247. * The stack currently being processed.
  248. */
  249. ValueStack stack_;
  250. /**
  251. * Current indentation level.
  252. */
  253. uint indent_level_;
  254. /**
  255. * Graph vertex currently being processed.
  256. */
  257. GraphVertex cur_vertex_;
  258. /**
  259. * The target language.
  260. */
  261. std::unique_ptr<LuaLanguage> target_lang_;
  262. private:
  263. /**
  264. * Processes a GraphVertex.
  265. *
  266. * @param vertex[in] The vertex to process.
  267. */
  268. void Process(Function& function, InstVec& insts, GraphVertex vertex);
  269. /**
  270. * The annotated graph of the script.
  271. */
  272. Graph graph_;
  273. /**
  274. * Order of operands for binary operations.
  275. */
  276. const ARGUMENT_ORDER bin_order_;
  277. /**
  278. * Order of operands for call arguments.
  279. */
  280. const ARGUMENT_ORDER call_order_;
  281. /**
  282. * Lists of arguments to be built when processing function calls.
  283. */
  284. ValueList arg_list_;
  285. };