CodeGenerator.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. class CodeGenerator {
  44. public:
  45. LuaLanguage& TargetLang()
  46. {
  47. assert(target_lang_);
  48. return *target_lang_;
  49. }
  50. void writeFunctionCall(std::string functionName, std::string paramsFormat, const std::vector<ValuePtr>& params);
  51. const ARGUMENT_ORDER _binOrder; ///< Order of operands for binary operations.
  52. const ARGUMENT_ORDER _callOrder; ///< Order of operands for call arguments.
  53. ValueList _argList; ///< Storage for lists of arguments to be built when processing function calls.
  54. GroupPtr cur_group_; ///< Pointer to the group currently being processed.
  55. virtual ~CodeGenerator() { }
  56. /**
  57. * Constructor for CodeGenerator.
  58. *
  59. * @param engine Pointer to the Engine used for the script.
  60. * @param output The std::ostream to output the code to.
  61. * @param binOrder Order of arguments for binary operators.
  62. * @param callOrder Order of arguments for function calls.
  63. */
  64. CodeGenerator(Engine *engine, std::ostream &output, ARGUMENT_ORDER binOrder, ARGUMENT_ORDER callOrder);
  65. /**
  66. * Generates code from the provided graph and outputs it to stdout.
  67. *
  68. * @param g The annotated graph of the script.
  69. */
  70. virtual void Generate(InstVec& insts, const Graph &g);
  71. /**
  72. * Adds a line of code to the current group.
  73. *
  74. * @param s The line to add.
  75. * @param unindentBefore Whether or not to remove an indentation level before the line. Defaults to false.
  76. * @param indentAfter Whether or not to add an indentation level after the line. Defaults to false.
  77. */
  78. virtual void AddOutputLine(std::string s, bool unindentBefore = false, bool indentAfter = false);
  79. /**
  80. * Writes a comment line indicating an unimplemented opcode.
  81. *
  82. * @param code_gen[in|out] The code generator.
  83. * @param class_name[in] The class where the instruction is. Unused.
  84. * @param instruction[in] The unimplemented instruction.
  85. */
  86. void WriteTodo(std::string class_name, std::string instruction){
  87. AddOutputLine("-- UNIMPLMENTED INSTRUCTION: \"" + instruction + "\")");
  88. }
  89. /**
  90. * Generate an assignment statement.
  91. *
  92. * @param dst The variable being assigned to.
  93. * @param src The value being assigned.
  94. */
  95. void writeAssignment(ValuePtr dst, ValuePtr src);
  96. /**
  97. * Add an argument to the argument list.
  98. *
  99. * @param p The argument to add.
  100. */
  101. void addArg(ValuePtr p);
  102. /**
  103. * Process a single character of metadata.
  104. *
  105. * @param inst The instruction being processed.
  106. * @param c The character signifying the action to be taken.
  107. * @param pos The position at which c occurred in the metadata.
  108. */
  109. virtual void ProcessSpecialMetadata(const InstPtr inst, char c, int pos);
  110. protected:
  111. Engine *_engine; ///< Pointer to the Engine used for the script.
  112. std::ostream &_output; ///< The std::ostream to output the code to.
  113. ValueStack _stack; ///< The stack currently being processed.
  114. uint _indentLevel; ///< Indentation level.
  115. GraphVertex _curVertex; ///< Graph vertex currently being processed.
  116. std::unique_ptr<LuaLanguage> target_lang_;
  117. /**
  118. * Processes an instruction. Called by process() for each instruction.
  119. * Call the base class implementation for opcodes you cannot handle yourself,
  120. * or where the base class implementation is preferable.
  121. *
  122. * @param inst The instruction to process.
  123. */
  124. void ProcessInst(Function& func, InstVec& insts, const InstPtr inst);
  125. void ProcessUncondJumpInst(Function& func, InstVec& insts, const InstPtr inst);
  126. void ProcessCondJumpInst(const InstPtr inst);
  127. /**
  128. * Indents a string according to the current indentation level.
  129. *
  130. * @param s The string to indent.
  131. * @result The indented string.
  132. */
  133. std::string indentString(std::string s);
  134. /**
  135. * Construct the signature for a function.
  136. *
  137. * @param func Reference to the function to construct the signature for.
  138. */
  139. virtual std::string ConstructFuncSignature(const Function& func);
  140. virtual void OnBeforeStartFunction(const Function& func);
  141. virtual void OnEndFunction(const Function& func);
  142. virtual void OnStartFunction(const Function&) { }
  143. virtual bool OutputOnlyRequiredLabels() const { return false; }
  144. void generatePass(InstVec& insts, const Graph& g);
  145. bool mIsLabelPass = true;
  146. private:
  147. Graph _g; ///< The annotated graph of the script.
  148. /**
  149. * Processes a GraphVertex.
  150. *
  151. * @param v The vertex to process.
  152. */
  153. void process(Function& func, InstVec& insts, GraphVertex v);
  154. };