Ast.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. // =============================================================================
  2. //
  3. // This file is part of the qlow compiler.
  4. //
  5. // Copyright (C) 2014-2015 Nicolas Winkler
  6. //
  7. // This program is free software: you can redistribute it and/or modify
  8. // it under the terms of the GNU General Public License as published by
  9. // the Free Software Foundation, either version 3 of the License, or
  10. // (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License
  18. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. //
  20. // =============================================================================
  21. #ifndef QLOW_AST_H
  22. #define QLOW_AST_H
  23. #include <string>
  24. #include <vector>
  25. #include <memory>
  26. #include <utility>
  27. #include <map>
  28. #include "Visitor.h"
  29. #include "Util.h"
  30. #include "ErrorReporting.h"
  31. namespace qlow
  32. {
  33. struct CodePosition;
  34. class StructureVisitor;
  35. namespace ast
  36. {
  37. class Ast;
  38. // base class
  39. struct AstObject;
  40. struct ImportDeclaration;
  41. struct Class;
  42. struct Type;
  43. struct ClassType;
  44. struct ArrayType;
  45. struct PointerType;
  46. struct FeatureDeclaration;
  47. struct FieldDeclaration;
  48. struct MethodDefinition;
  49. struct VariableDeclaration;
  50. struct ArgumentDeclaration;
  51. struct Statement;
  52. struct DoEndBlock;
  53. struct IfElseBlock;
  54. struct WhileBlock;
  55. struct Expression;
  56. struct FeatureCall;
  57. struct AssignmentStatement;
  58. struct ReturnStatement;
  59. struct LocalVariableStatement;
  60. struct AddressExpression;
  61. struct IntConst;
  62. struct Operation;
  63. struct UnaryOperation;
  64. struct BinaryOperation;
  65. struct NewExpression;
  66. struct NewArrayExpression;
  67. struct CastExpression;
  68. }
  69. namespace sem
  70. {
  71. struct SemanticObject;
  72. struct Class;
  73. class Scope;
  74. // template<typename T>
  75. // using SymbolTable = std::map<std::string, std::unique_ptr<T>>;
  76. }
  77. }
  78. class qlow::ast::Ast
  79. {
  80. OwningList<AstObject> objects;
  81. public:
  82. inline const OwningList<AstObject>& getObjects(void) const { return objects; }
  83. inline OwningList<AstObject>& getObjects(void) { return objects; }
  84. void merge(Ast other);
  85. };
  86. struct qlow::ast::AstObject :
  87. public Visitable<std::unique_ptr<sem::SemanticObject>, sem::Scope&, StructureVisitor>
  88. {
  89. CodePosition pos;
  90. inline AstObject(const CodePosition& cp) :
  91. pos{ cp } {}
  92. virtual ~AstObject(void);
  93. };
  94. struct qlow::ast::ImportDeclaration
  95. {
  96. CodePosition pos;
  97. std::string imported;
  98. inline ImportDeclaration(std::string imported, const CodePosition& cp) :
  99. pos{ cp },
  100. imported{ std::move(imported) }
  101. {
  102. }
  103. };
  104. struct qlow::ast::Class : public AstObject
  105. {
  106. std::string name;
  107. OwningList<FeatureDeclaration> features;
  108. /// true if it is a class, false if struct
  109. bool isReferenceType;
  110. inline Class(std::string name, OwningList<FeatureDeclaration>& features, bool isReferenceType, const CodePosition& cp) :
  111. AstObject{ cp },
  112. name{ std::move(name) }, features(std::move(features)), isReferenceType{ isReferenceType }
  113. {
  114. }
  115. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&) override;
  116. };
  117. struct qlow::ast::Type : public AstObject
  118. {
  119. inline Type(const CodePosition& cp) :
  120. AstObject{ cp }
  121. {
  122. }
  123. virtual std::string asString(void) const = 0;
  124. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor&, sem::Scope&) override;
  125. };
  126. ///
  127. /// \brief represents a type identified by a single identifier
  128. ///
  129. struct qlow::ast::ClassType : public ast::Type
  130. {
  131. std::string typeName;
  132. inline ClassType(const std::string& typeName, const CodePosition& cp) :
  133. Type{ cp },
  134. typeName{ typeName }
  135. {
  136. }
  137. inline ClassType(std::string&& typeName, const CodePosition& cp) :
  138. Type{ cp },
  139. typeName{ std::move(typeName) }
  140. {
  141. }
  142. inline std::string asString(void) const override { return typeName; }
  143. };
  144. struct qlow::ast::ArrayType : public ast::Type
  145. {
  146. std::unique_ptr<ast::Type> arrayType;
  147. inline ArrayType(std::unique_ptr<ast::Type> arrayType, const CodePosition& cp) :
  148. Type{ cp },
  149. arrayType{ std::move(arrayType) }
  150. {
  151. }
  152. inline std::string asString(void) const override {
  153. return std::string("[") + arrayType->asString() + "]";
  154. }
  155. };
  156. struct qlow::ast::PointerType : public ast::Type
  157. {
  158. std::unique_ptr<ast::Type> derefType;
  159. inline PointerType(std::unique_ptr<ast::Type> derefType, const CodePosition& cp) :
  160. Type{ cp },
  161. derefType{ std::move(derefType) }
  162. {
  163. }
  164. inline std::string asString(void) const override {
  165. return derefType->asString() + "*";
  166. }
  167. };
  168. struct qlow::ast::FeatureDeclaration : public AstObject
  169. {
  170. std::string name;
  171. std::unique_ptr<ast::Type> type;
  172. inline FeatureDeclaration(std::unique_ptr<ast::Type> type, const std::string& name, const CodePosition& cp) :
  173. AstObject{ cp },
  174. name{ name },
  175. type{ std::move(type) }
  176. {
  177. }
  178. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  179. };
  180. struct qlow::ast::FieldDeclaration : public FeatureDeclaration
  181. {
  182. inline FieldDeclaration(std::unique_ptr<ast::Type> type, const std::string& name, const CodePosition& cp) :
  183. FeatureDeclaration{ std::move(type), name, cp }
  184. {
  185. }
  186. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  187. };
  188. struct qlow::ast::MethodDefinition : public FeatureDeclaration
  189. {
  190. OwningList<ArgumentDeclaration> arguments;
  191. /// pointer to method body. If this is a null pointer, the method has only
  192. /// been declared and not defined (with extern)
  193. std::unique_ptr<DoEndBlock> body;
  194. inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
  195. std::unique_ptr<DoEndBlock> body, const CodePosition& cp) :
  196. FeatureDeclaration{ std::move(type), name, cp },
  197. body{ std::move(body) }
  198. {
  199. }
  200. inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
  201. OwningList<ArgumentDeclaration>&& arguments, std::unique_ptr<DoEndBlock> body, const CodePosition& cp) :
  202. FeatureDeclaration{ std::move(type), name, cp },
  203. arguments(std::move(arguments)),
  204. body{ std::move(body) }
  205. {
  206. }
  207. inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
  208. const CodePosition& cp) :
  209. FeatureDeclaration{ std::move(type), name, cp },
  210. body{ nullptr }
  211. {
  212. }
  213. inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
  214. OwningList<ArgumentDeclaration>&& arguments, const CodePosition& cp) :
  215. FeatureDeclaration{ std::move(type), name, cp },
  216. arguments(std::move(arguments)),
  217. body{ nullptr }
  218. {
  219. }
  220. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  221. };
  222. struct qlow::ast::VariableDeclaration : public AstObject
  223. {
  224. std::unique_ptr<ast::Type> type;
  225. std::string name;
  226. inline VariableDeclaration(std::unique_ptr<ast::Type> type, std::string&& name, const CodePosition& cp) :
  227. AstObject{ cp },
  228. type{ std::move(type) },
  229. name{ std::move(name) }
  230. {
  231. }
  232. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  233. };
  234. struct qlow::ast::ArgumentDeclaration :
  235. public VariableDeclaration
  236. {
  237. inline ArgumentDeclaration(std::unique_ptr<ast::Type> type, std::string&& name, const CodePosition& cp) :
  238. VariableDeclaration{ std::move(type), std::move(name), cp }
  239. {
  240. }
  241. //virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  242. };
  243. struct qlow::ast::Statement : public virtual AstObject
  244. {
  245. inline Statement(const CodePosition& cp) :
  246. AstObject{ cp } {}
  247. virtual ~Statement(void);
  248. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  249. };
  250. struct qlow::ast::DoEndBlock : public Statement
  251. {
  252. OwningList<Statement> statements;
  253. inline DoEndBlock(OwningList<Statement>&& statements, const CodePosition& cp) :
  254. AstObject{ cp },
  255. Statement{ cp },
  256. statements(std::move(statements))
  257. {
  258. }
  259. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  260. };
  261. struct qlow::ast::IfElseBlock : public Statement
  262. {
  263. std::unique_ptr<Expression> condition;
  264. std::unique_ptr<DoEndBlock> ifBlock;
  265. std::unique_ptr<DoEndBlock> elseBlock;
  266. inline IfElseBlock(std::unique_ptr<Expression> condition,
  267. std::unique_ptr<DoEndBlock> ifBlock,
  268. std::unique_ptr<DoEndBlock> elseBlock,
  269. const CodePosition& cp) :
  270. AstObject{ cp },
  271. Statement{ cp },
  272. condition{ std::move(condition) },
  273. ifBlock{ std::move(ifBlock) },
  274. elseBlock{ std::move(elseBlock) }
  275. {
  276. }
  277. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  278. };
  279. struct qlow::ast::WhileBlock : public Statement
  280. {
  281. std::unique_ptr<Expression> condition;
  282. std::unique_ptr<DoEndBlock> body;
  283. inline WhileBlock(std::unique_ptr<Expression> condition,
  284. std::unique_ptr<DoEndBlock> body,
  285. const CodePosition& cp) :
  286. AstObject{ cp },
  287. Statement{ cp },
  288. condition{ std::move(condition) },
  289. body{ std::move(body) }
  290. {
  291. }
  292. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  293. };
  294. struct qlow::ast::Expression : public virtual AstObject
  295. {
  296. inline Expression(const CodePosition& cp) :
  297. AstObject{ cp } {}
  298. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  299. };
  300. struct qlow::ast::FeatureCall : public Expression, public Statement
  301. {
  302. std::unique_ptr<Expression> target;
  303. std::string name;
  304. OwningList<Expression> arguments;
  305. inline FeatureCall(std::unique_ptr<Expression> target, const std::string& name, const CodePosition& cp) :
  306. AstObject{ cp },
  307. Expression{ cp }, Statement{ cp },
  308. target(std::move(target)), name(name)
  309. {
  310. }
  311. inline FeatureCall(std::unique_ptr<Expression> target, const std::string& name,
  312. OwningList<Expression>&& arguments, const CodePosition& cp) :
  313. AstObject{ cp },
  314. Expression{ cp }, Statement{ cp },
  315. target(std::move(target)), name(name), arguments(std::move(arguments))
  316. {
  317. }
  318. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  319. };
  320. struct qlow::ast::ReturnStatement : public Statement
  321. {
  322. std::unique_ptr<Expression> expr;
  323. inline ReturnStatement(std::unique_ptr<Expression>&& expr, const CodePosition& cp) :
  324. AstObject{ cp },
  325. Statement{ cp },
  326. expr{ std::move(expr) }
  327. {
  328. }
  329. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  330. };
  331. struct qlow::ast::AssignmentStatement : public Statement
  332. {
  333. std::unique_ptr<Expression> target;
  334. std::unique_ptr<Expression> expr;
  335. inline AssignmentStatement(std::unique_ptr<Expression>&& target, std::unique_ptr<Expression>&& expr, const CodePosition& cp) :
  336. AstObject{ cp },
  337. Statement{ cp },
  338. target{ std::move(target) }, expr{ std::move(expr) }
  339. {
  340. }
  341. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  342. };
  343. struct qlow::ast::LocalVariableStatement : public Statement
  344. {
  345. std::string name;
  346. std::unique_ptr<ast::Type> type;
  347. inline LocalVariableStatement(std::string&& name, std::unique_ptr<Type> type, const CodePosition& cp) :
  348. AstObject{ cp },
  349. Statement{ cp },
  350. name{ name },
  351. type{ std::move(type) }
  352. {
  353. }
  354. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  355. };
  356. struct qlow::ast::AddressExpression : public Expression
  357. {
  358. std::unique_ptr<Expression> target;
  359. inline AddressExpression(std::unique_ptr<Expression> target,
  360. const CodePosition& cp) :
  361. AstObject{ cp },
  362. Expression{ cp },
  363. target{ std::move(target) }
  364. {
  365. }
  366. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  367. };
  368. struct qlow::ast::IntConst : public Expression
  369. {
  370. unsigned long long value;
  371. IntConst(unsigned long long v, const CodePosition& p) :
  372. AstObject(p),
  373. Expression(p),
  374. value{ v } {}
  375. IntConst(std::string&& val, const CodePosition& p);
  376. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  377. };
  378. struct qlow::ast::Operation : public Expression
  379. {
  380. std::string opString;
  381. CodePosition opPos;
  382. inline Operation(const std::string& opString, const CodePosition& cp,
  383. const CodePosition& opPos) :
  384. AstObject{ cp },
  385. Expression{ cp },
  386. opString{ opString },
  387. opPos{ opPos }
  388. {
  389. }
  390. };
  391. struct qlow::ast::UnaryOperation : public Operation
  392. {
  393. enum Side
  394. {
  395. PREFIX,
  396. SUFFIX,
  397. };
  398. Side side;
  399. std::unique_ptr<Expression> expr;
  400. inline UnaryOperation(std::unique_ptr<Expression> expr, Side side,
  401. const std::string& op, const CodePosition& cp,
  402. const CodePosition& opPos
  403. ) :
  404. AstObject{ cp },
  405. Operation{ op, cp, opPos },
  406. side{ side },
  407. expr{ std::move(expr) }
  408. {
  409. }
  410. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  411. };
  412. struct qlow::ast::BinaryOperation : public Operation
  413. {
  414. std::unique_ptr<Expression> left;
  415. std::unique_ptr<Expression> right;
  416. inline BinaryOperation(std::unique_ptr<Expression> left,
  417. std::unique_ptr<Expression> right,
  418. const std::string& op,
  419. const CodePosition& cp,
  420. const CodePosition& opPos
  421. ) :
  422. AstObject{ cp },
  423. Operation{ op, cp, opPos },
  424. left{ std::move(left) },
  425. right{ std::move(right) }
  426. {
  427. }
  428. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  429. };
  430. struct qlow::ast::NewExpression : public Expression
  431. {
  432. std::unique_ptr<ast::Type> type;
  433. inline NewExpression(std::unique_ptr<ast::Type> type,
  434. const CodePosition& cp) :
  435. AstObject{ cp },
  436. Expression{ cp },
  437. type{ std::move(type) }
  438. {
  439. }
  440. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  441. };
  442. struct qlow::ast::NewArrayExpression : public Expression
  443. {
  444. std::unique_ptr<ast::Type> type;
  445. std::unique_ptr<Expression> length;
  446. inline NewArrayExpression(std::unique_ptr<ast::Type> type,
  447. std::unique_ptr<Expression> length,
  448. const CodePosition& cp) :
  449. AstObject{ cp },
  450. Expression{ cp },
  451. type{ std::move(type) },
  452. length{ std::move(length) }
  453. {
  454. }
  455. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  456. };
  457. struct qlow::ast::CastExpression : public Expression
  458. {
  459. std::unique_ptr<ast::Expression> expression;
  460. std::unique_ptr<ast::Type> targetType;
  461. inline CastExpression(std::unique_ptr<ast::Expression> expression,
  462. std::unique_ptr<ast::Type> targetType,
  463. const CodePosition& cp) :
  464. AstObject{ cp },
  465. Expression{ cp },
  466. expression{ std::move(expression) },
  467. targetType{ std::move(targetType) }
  468. {
  469. }
  470. virtual std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, sem::Scope&);
  471. };
  472. #endif // QLOW_AST_H