Semantic.h 14 KB

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