Advertisement
Guest User

Untitled

a guest
Jul 21st, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.69 KB | None | 0 0
  1. %{
  2. #include "exprdefs.h"
  3. #include "llvm/IR/DerivedTypes.h"
  4. #include "llvm/IR/LLVMContext.h"
  5. #include "llvm/IR/Module.h"
  6. #include "llvm/IR/Verifier.h"
  7. #include "llvm/IR/IRBuilder.h"
  8. #include <cstdio>
  9. #include <stdexcept>
  10.  
  11. using namespace llvm;
  12. typedef Value descriptor;
  13.  
  14. #include "symboltable.cc"
  15.  
  16. // syms contains all the variable names used
  17. symboltable syms;
  18.  
  19. // this global variable contains all the generated code
  20. static Module *TheModule;
  21.  
  22. // this is the method used to construct the LLVM intermediate code (IR)
  23. static LLVMContext TheContext;
  24. static IRBuilder<> Builder(TheContext);
  25.  
  26. // the calls to TheContext in the init above and in the
  27. // following code ensures that we are incrementally generating
  28. // instructions in the right order
  29.  
  30. static Function *TheFunction = 0;
  31.  
  32. /// ExprAST - Base class for all expression nodes.
  33. class ExprAST {
  34. public:
  35. virtual ~ExprAST() {}
  36. virtual Value *Codegen() = 0;
  37. };
  38.  
  39. /// NumberExprAST - Expression class for integer numeric literals like "12".
  40. class NumberExprAST : public ExprAST {
  41. int Val;
  42. public:
  43. NumberExprAST(int val) : Val(val) {}
  44. virtual Value *Codegen();
  45. };
  46.  
  47. /// VariableExprAST - Expression class for variables like "a".
  48. class VariableExprAST : public ExprAST {
  49. string Name;
  50. public:
  51. VariableExprAST(string name) : Name(name) {}
  52. const std::string &getName() const { return Name; }
  53. virtual Value *Codegen();
  54. };
  55.  
  56. /// BinaryExprAST - Expression class for a binary operator.
  57. class BinaryExprAST : public ExprAST {
  58. char Op;
  59. ExprAST *LHS, *RHS;
  60. public:
  61. BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
  62. : Op(op), LHS(lhs), RHS(rhs) {}
  63. virtual Value *Codegen();
  64. ~BinaryExprAST() {
  65. delete LHS;
  66. delete RHS;
  67. }
  68. };
  69.  
  70. // we also have to create a main function that contains
  71. // all the code generated for the expression and the print_int call
  72. Function *gen_main_def() {
  73. // create the top-level definition for main
  74. FunctionType *FT = FunctionType::get(IntegerType::get(TheContext, 32), false);
  75. Function *TheFunction = Function::Create(FT, Function::ExternalLinkage, "main", TheModule);
  76. if (TheFunction == 0) {
  77. throw runtime_error("empty function block");
  78. }
  79. // Create a new basic block which contains a sequence of LLVM instructions
  80. BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
  81. // All subsequent calls to IRBuilder will place instructions in this location
  82. Builder.SetInsertPoint(BB);
  83. return TheFunction;
  84. }
  85.  
  86. /// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
  87. /// the function. This is used for mutable variables etc.
  88. static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName) {
  89. IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin());
  90. return TmpB.CreateAlloca(IntegerType::get(TheContext, 32), 0, VarName.c_str());
  91. }
  92.  
  93. %}
  94.  
  95. %union{
  96. class ExprAST *ast;
  97. string *sval;
  98. int number;
  99. }
  100.  
  101. %token <number> NUMBER
  102. %token <sval> NAME
  103. %type <ast> expression
  104. %%
  105. statement_list: statement ';' statement_list
  106. | /* empty */
  107. ;
  108. statement: NAME '=' expression
  109. {
  110. Value *RetVal = $3->Codegen();
  111. AllocaInst *Alloca;
  112. if (NULL == (Alloca = (AllocaInst *)syms.access_symtbl(*$1))) {
  113. // unlike CreateEntryBlockAlloca the following will
  114. // create the alloca instr at the current insertion point in the
  115. // basic block
  116. Alloca = Builder.CreateAlloca(IntegerType::get(TheContext, 32), 0, $1->c_str());
  117. syms.enter_symtbl(*$1, Alloca);
  118. }
  119. Value *LHS = Builder.CreateStore(RetVal, Alloca);
  120. delete($1); // remove allocated string for NAME
  121. delete($3); // get rid of abstract syntax tree
  122. }
  123. | NAME '(' expression ')'
  124. {
  125. Value *RetVal = $3->Codegen();
  126. Function *CalleeF;
  127. if (NULL == (CalleeF = (Function *)syms.access_symtbl(*$1))) {
  128. // create a extern definition for function call
  129. std::vector<Type*> args;
  130. args.push_back(IntegerType::get(TheContext, 32)); // takes one integer argument
  131. FunctionType *Ty = FunctionType::get(IntegerType::get(TheContext, 32), args, false);
  132. Function *F = Function::Create(Ty, Function::ExternalLinkage, *$1, TheModule);
  133. CalleeF = TheModule->getFunction(F->getName());
  134. syms.enter_symtbl(*$1, CalleeF);
  135. }
  136. if (CalleeF == 0) {
  137. throw runtime_error("could not find the function print_int\n");
  138. }
  139. // print the value of the expression and we are done
  140. Value *CallF = Builder.CreateCall(CalleeF, RetVal, "calltmp");
  141. delete($1); // remove allocated string for NAME
  142. delete($3); // get rid of abstract syntax tree
  143. }
  144. ;
  145.  
  146. expression: expression '+' NUMBER
  147. {
  148. $$ = new BinaryExprAST('+', $1, new NumberExprAST($3));
  149. }
  150. | expression '-' NUMBER
  151. {
  152. $$ = new BinaryExprAST('-', $1, new NumberExprAST($3));
  153. }
  154. | expression '+' NAME
  155. {
  156. $$ = new BinaryExprAST('+', $1, new VariableExprAST(*$3));
  157. delete($3);
  158. }
  159. | expression '-' NAME
  160. {
  161. $$ = new BinaryExprAST('-', $1, new VariableExprAST(*$3));
  162. delete($3);
  163. }
  164. | NUMBER
  165. {
  166. $$ = new NumberExprAST($1);
  167. }
  168. | NAME
  169. {
  170. $$ = new VariableExprAST(*$1);
  171. delete($1);
  172. }
  173. ;
  174. %%
  175.  
  176. Value *VariableExprAST::Codegen() {
  177. Value *V = syms.access_symtbl(Name);
  178. if (V == 0) {
  179. throw runtime_error("could not find variable: " + Name);
  180. }
  181. return Builder.CreateLoad(V, Name.c_str());
  182. }
  183.  
  184. Value *NumberExprAST::Codegen() {
  185. return ConstantInt::get(TheContext, APInt(32, Val));
  186. }
  187.  
  188. Value *BinaryExprAST::Codegen() {
  189. Value *L = LHS->Codegen();
  190. Value *R = RHS->Codegen();
  191. if (L == 0 || R == 0) return 0;
  192.  
  193. switch (Op) {
  194. case '+': return Builder.CreateAdd(L, R, "addtmp");
  195. case '-': return Builder.CreateSub(L, R, "subtmp");
  196. default: throw runtime_error("what operator is this? never heard of it.");
  197. }
  198. }
  199.  
  200. int main() {
  201. // initialize LLVM
  202. LLVMContext &Context = TheContext;
  203. // Make the module, which holds all the code.
  204. TheModule = new Module("module for simple expressions", Context);
  205. // set up the declaration of the print_int function
  206. TheFunction = gen_main_def();
  207. // set up symbol table
  208. syms.new_symtbl();
  209. // parse the input and create the abstract syntax tree
  210. int retval = yyparse();
  211. // remove symbol table
  212. syms.remove_symtbl();
  213. // Finish off the main function.
  214. // return 0 from main, which is EXIT_SUCCESS
  215. Builder.CreateRet(ConstantInt::get(TheContext, APInt(32, 0)));
  216. // Validate the generated code, checking for consistency.
  217. verifyFunction(*TheFunction);
  218. // Print out all of the generated code to stderr
  219. TheModule->print(errs(), nullptr);
  220. return(retval >= 1 ? 1 : 0);
  221. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement