Semantic.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. #ifndef QLOW_SEMANTIC_H
  2. #define QLOW_SEMANTIC_H
  3. #include <string>
  4. #include <map>
  5. #include "Util.h"
  6. #include "Ast.h"
  7. #include "Visitor.h"
  8. #include "Scope.h"
  9. #include "Type.h"
  10. #include <llvm/IR/Value.h>
  11. #include <llvm/IR/IRBuilder.h>
  12. #include <llvm/IR/BasicBlock.h>
  13. namespace qlow
  14. {
  15. namespace sem
  16. {
  17. std::unique_ptr<GlobalScope>
  18. createFromAst(const std::vector<std::unique_ptr<qlow::ast::AstObject>>& objects);
  19. struct Class;
  20. struct Variable;
  21. struct Field;
  22. struct Method;
  23. struct Statement;
  24. struct Expression;
  25. struct ThisExpression;
  26. struct DoEndBlock;
  27. struct IfElseBlock;
  28. struct WhileBlock;
  29. struct FeatureCallStatement;
  30. struct AssignmentStatement;
  31. struct ReturnStatement;
  32. struct LocalVariableExpression;
  33. struct AddressExpression;
  34. struct Operation;
  35. struct UnaryOperation;
  36. struct BinaryOperation;
  37. struct CastExpression;
  38. struct NewArrayExpression;
  39. struct MethodCallExpression;
  40. struct FieldAccessExpression;
  41. struct IntConst;
  42. }
  43. class ExpressionCodegenVisitor;
  44. class LValueVisitor;
  45. class StatementVisitor;
  46. namespace gen
  47. {
  48. class FunctionGenerator;
  49. }
  50. }
  51. struct qlow::sem::Class : public SemanticObject
  52. {
  53. qlow::ast::Class* astNode;
  54. std::string name;
  55. SymbolTable<Field> fields;
  56. SymbolTable<Method> methods;
  57. ClassScope scope;
  58. /// \brief generated during llvm code generation, not availab
  59. llvm::Type* llvmType;
  60. inline Class(qlow::ast::Class* astNode, GlobalScope& globalScope) :
  61. astNode{ astNode },
  62. name{ astNode->name },
  63. scope{ globalScope, this },
  64. llvmType{ nullptr }
  65. {
  66. }
  67. inline Class(const std::string& nativeName, GlobalScope& globalScope) :
  68. astNode{ nullptr },
  69. name{ nativeName },
  70. scope{ globalScope, this },
  71. llvmType{ nullptr }
  72. {
  73. }
  74. virtual std::string toString(void) const override;
  75. };
  76. struct qlow::sem::Variable : public SemanticObject
  77. {
  78. std::shared_ptr<Type> type;
  79. std::string name;
  80. bool isParameter;
  81. /// if this is a local variable, this stores a reference to the llvm
  82. /// instance of this variable. If it is a parameter, the parameter value
  83. llvm::Value* allocaInst;
  84. Variable(void) = default;
  85. inline Variable(std::shared_ptr<Type> type, const std::string& name) :
  86. type{ std::move(type) },
  87. name{ name },
  88. allocaInst { nullptr }
  89. {
  90. }
  91. virtual std::string toString(void) const override;
  92. };
  93. struct qlow::sem::Field : public Variable
  94. {
  95. int llvmStructIndex;
  96. virtual std::string toString(void) const override;
  97. };
  98. struct qlow::sem::Method : public SemanticObject
  99. {
  100. Class* containingType;
  101. std::shared_ptr<Type> returnType;
  102. std::vector<Variable*> arguments;
  103. std::string name;
  104. ast::MethodDefinition* astNode;
  105. ThisExpression* thisExpression;
  106. std::unique_ptr<DoEndBlock> body;
  107. LocalScope scope;
  108. llvm::Function* llvmNode;
  109. inline Method(Scope& parentScope, std::shared_ptr<Type> returnType) :
  110. containingType{ nullptr },
  111. returnType{ std::move(returnType) },
  112. scope{ parentScope, this },
  113. thisExpression{ nullptr },
  114. body{ nullptr }
  115. {
  116. }
  117. inline Method(ast::MethodDefinition* astNode, Scope& parentScope) :
  118. containingType{ nullptr },
  119. astNode{ astNode },
  120. name{ astNode->name },
  121. scope{ parentScope, this },
  122. thisExpression{ nullptr },
  123. body{ nullptr }
  124. {
  125. }
  126. void generateThisExpression(void);
  127. virtual std::string toString(void) const override;
  128. };
  129. struct qlow::sem::ThisExpression : public Variable
  130. {
  131. Method* method;
  132. inline ThisExpression(Method* method) :
  133. Variable{ std::make_shared<PointerType>(std::make_shared<ClassType>(method->containingType)), "this" },
  134. method{ method }
  135. {
  136. }
  137. llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2);
  138. };
  139. struct qlow::sem::Statement : public SemanticObject, public Visitable<llvm::Value*, gen::FunctionGenerator, qlow::StatementVisitor>
  140. {
  141. virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) = 0;
  142. };
  143. struct qlow::sem::DoEndBlock : public Statement
  144. {
  145. LocalScope scope;
  146. OwningList<Statement> statements;
  147. inline DoEndBlock(LocalScope& parentScope) :
  148. scope{ parentScope } {}
  149. virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
  150. };
  151. struct qlow::sem::IfElseBlock : public Statement
  152. {
  153. std::unique_ptr<Expression> condition;
  154. std::unique_ptr<DoEndBlock> ifBlock;
  155. std::unique_ptr<DoEndBlock> elseBlock;
  156. inline IfElseBlock(std::unique_ptr<Expression> condition,
  157. std::unique_ptr<DoEndBlock> ifBlock,
  158. std::unique_ptr<DoEndBlock> elseBlock) :
  159. condition{ std::move(condition) },
  160. ifBlock{ std::move(ifBlock) },
  161. elseBlock{ std::move(elseBlock) }
  162. {
  163. }
  164. virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
  165. };
  166. struct qlow::sem::WhileBlock : public Statement
  167. {
  168. std::unique_ptr<Expression> condition;
  169. std::unique_ptr<DoEndBlock> body;
  170. inline WhileBlock(std::unique_ptr<Expression> condition,
  171. std::unique_ptr<DoEndBlock> body) :
  172. condition{ std::move(condition) },
  173. body{ std::move(body) }
  174. {
  175. }
  176. virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
  177. };
  178. struct qlow::sem::AssignmentStatement : public Statement
  179. {
  180. std::unique_ptr<Expression> target;
  181. std::unique_ptr<Expression> value;
  182. virtual std::string toString(void) const override;
  183. virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
  184. };
  185. struct qlow::sem::ReturnStatement : public Statement
  186. {
  187. std::unique_ptr<Expression> value;
  188. virtual std::string toString(void) const override;
  189. virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
  190. };
  191. struct qlow::sem::Expression :
  192. public SemanticObject,
  193. public Visitable<llvm::Value*,
  194. llvm::IRBuilder<>,
  195. qlow::ExpressionCodegenVisitor>,
  196. public Visitable<llvm::Value*,
  197. llvm::IRBuilder<>,
  198. qlow::LValueVisitor>
  199. {
  200. std::shared_ptr<sem::Type> type;
  201. inline Expression(std::shared_ptr<Type> type) :
  202. type{ std::move(type) }
  203. {
  204. }
  205. inline virtual bool isLValue(void) const { return false; }
  206. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override = 0;
  207. virtual llvm::Value* accept(LValueVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  208. };
  209. struct qlow::sem::Operation : public Expression
  210. {
  211. std::string opString;
  212. inline Operation(std::shared_ptr<Type> type) :
  213. Expression{ std::move(type) }
  214. {
  215. }
  216. };
  217. struct qlow::sem::LocalVariableExpression : public Expression
  218. {
  219. Variable* var;
  220. inline LocalVariableExpression(Variable* var) :
  221. Expression{ var->type },
  222. var{ var }
  223. {
  224. }
  225. inline virtual bool isLValue(void) const override { return true; }
  226. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  227. virtual llvm::Value* accept(LValueVisitor& visitor, llvm::IRBuilder<>& arg2);
  228. virtual std::string toString(void) const override;
  229. };
  230. struct qlow::sem::AddressExpression : public Expression
  231. {
  232. std::unique_ptr<sem::Expression> target;
  233. inline AddressExpression(std::unique_ptr<sem::Expression> target) :
  234. Expression{ std::make_shared<sem::PointerType>(target->type) },
  235. target{ std::move(target) }
  236. {
  237. }
  238. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  239. };
  240. struct qlow::sem::BinaryOperation : public Operation
  241. {
  242. std::unique_ptr<Expression> left;
  243. std::unique_ptr<Expression> right;
  244. ast::BinaryOperation* astNode;
  245. /// method that is called to execute the operator
  246. sem::Method* operationMethod;
  247. inline BinaryOperation(std::shared_ptr<Type> type, ast::BinaryOperation* astNode) :
  248. Operation{ std::move(type) },
  249. astNode{ astNode }
  250. {
  251. }
  252. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  253. virtual std::string toString(void) const override;
  254. };
  255. struct qlow::sem::CastExpression : public Expression
  256. {
  257. std::unique_ptr<Expression> expression;
  258. std::shared_ptr<Type> targetType;
  259. ast::CastExpression* astNode;
  260. inline CastExpression(std::unique_ptr<Expression> expression,
  261. std::shared_ptr<Type> type,
  262. ast::CastExpression* astNode) :
  263. Expression{ type },
  264. expression{ std::move(expression) },
  265. targetType{ std::move(type) },
  266. astNode{ astNode }
  267. {
  268. }
  269. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  270. virtual std::string toString(void) const override;
  271. };
  272. struct qlow::sem::NewArrayExpression : public Expression
  273. {
  274. std::shared_ptr<Type> arrayType;
  275. std::unique_ptr<Expression> length;
  276. inline NewArrayExpression(std::shared_ptr<Type> arrayType) :
  277. Expression{ std::make_shared<ArrayType>(arrayType) },
  278. arrayType{ std::move(arrayType) }
  279. {
  280. }
  281. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  282. virtual std::string toString(void) const override;
  283. };
  284. struct qlow::sem::UnaryOperation : public Operation
  285. {
  286. qlow::ast::UnaryOperation::Side side;
  287. std::unique_ptr<Expression> arg;
  288. inline UnaryOperation(std::shared_ptr<Type> type) :
  289. Operation{ std::move(type) }
  290. {
  291. }
  292. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  293. virtual std::string toString(void) const override;
  294. };
  295. struct qlow::sem::MethodCallExpression : public Expression
  296. {
  297. Method* callee;
  298. std::unique_ptr<Expression> target;
  299. OwningList<Expression> arguments;
  300. inline MethodCallExpression(std::unique_ptr<Expression> target,
  301. Method* callee) :
  302. Expression{ callee->returnType },
  303. target{ std::move(target) },
  304. callee{ callee }
  305. {
  306. }
  307. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  308. virtual std::string toString(void) const override;
  309. };
  310. struct qlow::sem::FieldAccessExpression : public Expression
  311. {
  312. sem::Field* accessed;
  313. std::unique_ptr<Expression> target;
  314. //OwningList<Expression> arguments;
  315. inline FieldAccessExpression(std::unique_ptr<Expression> target,
  316. Field* accessed ) :
  317. Expression{ accessed->type },
  318. target{ std::move(target) },
  319. accessed{ accessed }
  320. {
  321. }
  322. inline virtual bool isLValue(void) const override { return true; }
  323. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  324. virtual llvm::Value* accept(LValueVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  325. virtual std::string toString(void) const override;
  326. };
  327. struct qlow::sem::IntConst : public Expression
  328. {
  329. unsigned long long value;
  330. inline IntConst(unsigned long long value) :
  331. Expression{ std::make_shared<NativeType>(NativeType::INTEGER) },
  332. value{ value }
  333. {
  334. }
  335. virtual llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2) override;
  336. };
  337. struct qlow::sem::FeatureCallStatement : public Statement
  338. {
  339. std::unique_ptr<MethodCallExpression> expr;
  340. inline FeatureCallStatement(std::unique_ptr<MethodCallExpression> expr) :
  341. expr{ std::move(expr) } {}
  342. virtual std::string toString(void) const override;
  343. virtual llvm::Value* accept(qlow::StatementVisitor&, gen::FunctionGenerator&) override;
  344. };
  345. #endif // QLOW_SEMANTIC_H