Semantic.h 13 KB

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