Semantic.h 11 KB

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