Scope.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #include "Scope.h"
  2. #include "Ast.h"
  3. #include "Semantic.h"
  4. #include "Type.h"
  5. #include "Builtin.h"
  6. using namespace qlow;
  7. sem::Scope::~Scope(void)
  8. {
  9. }
  10. sem::Method* sem::Scope::resolveMethod(const std::string& name,
  11. const std::vector<std::shared_ptr<Type>> argumentTypes)
  12. {
  13. sem::Method* m = getMethod(name);
  14. if (!m)
  15. return nullptr;
  16. if (m->arguments.size() != argumentTypes.size())
  17. return nullptr;
  18. for (size_t i = 0; i < argumentTypes.size(); i++) {
  19. if (!m->arguments[i]->type->equals(*argumentTypes[i]))
  20. return nullptr;
  21. }
  22. return m;
  23. }
  24. sem::Variable* sem::GlobalScope::getVariable(const std::string& name)
  25. {
  26. return nullptr;
  27. }
  28. sem::Method* sem::GlobalScope::getMethod(const std::string& name)
  29. {
  30. if (const auto& f = functions.find(name); f != functions.end()) {
  31. return f->second.get();
  32. }
  33. return nullptr;
  34. }
  35. std::shared_ptr<sem::Type> sem::GlobalScope::getType(const ast::Type& name)
  36. {
  37. if (const auto* arr = dynamic_cast<const ast::ArrayType*>(&name); arr) {
  38. return std::make_shared<sem::ArrayType>(getType(*arr->arrayType));
  39. }
  40. auto native = NativeScope::getInstance().getType(name);
  41. if (native) {
  42. return native;
  43. }
  44. const auto* classType = dynamic_cast<const ast::ClassType*>(&name);
  45. if (!classType)
  46. throw "internal error, non class-type top-level type";
  47. auto t = classes.find(classType->typeName);
  48. if (t != classes.end())
  49. return std::make_shared<sem::ClassType>(t->second.get());
  50. return nullptr;
  51. }
  52. std::shared_ptr<sem::Type> sem::GlobalScope::getReturnableType(void)
  53. {
  54. return nullptr;
  55. }
  56. std::string sem::GlobalScope::toString(void)
  57. {
  58. std::string ret;
  59. ret += "Classes:\n";
  60. for (auto& [name, c] : classes) {
  61. ret += "\t";
  62. ret += c->toString() + "\n";
  63. }
  64. return ret;
  65. }
  66. std::shared_ptr<sem::Type> sem::NativeScope::getType(const ast::Type& name)
  67. {
  68. if (const auto* arr = dynamic_cast<const ast::ArrayType*>(&name); arr) {
  69. return std::make_shared<sem::ArrayType>(getType(*arr->arrayType));
  70. }
  71. const auto* classType = dynamic_cast<const ast::ClassType*>(&name);
  72. if (!classType)
  73. return std::make_shared<sem::NativeType>(NativeType::VOID);
  74. auto t = types.find(classType->typeName);
  75. if (t != types.end())
  76. return *t->second;
  77. return nullptr;
  78. }
  79. sem::NativeScope sem::NativeScope::instance = sem::generateNativeScope();
  80. sem::NativeScope& sem::NativeScope::getInstance(void)
  81. {
  82. return instance;
  83. }
  84. std::string sem::NativeScope::toString(void)
  85. {
  86. return "NativeScope";
  87. }
  88. sem::Variable* sem::ClassScope::getVariable(const std::string& name)
  89. {
  90. if (classRef == nullptr)
  91. return parentScope.getVariable(name);
  92. auto m = classRef->fields.find(name);
  93. if (m != classRef->fields.end())
  94. return (*m).second.get();
  95. return parentScope.getVariable(name);
  96. }
  97. sem::Method* sem::ClassScope::getMethod(const std::string& name)
  98. {
  99. if (classRef == nullptr)
  100. return parentScope.getMethod(name);
  101. auto m = classRef->methods.find(name);
  102. if (m != classRef->methods.end())
  103. return (*m).second.get();
  104. return parentScope.getMethod(name);
  105. }
  106. std::string sem::ClassScope::toString(void)
  107. {
  108. std::string ret;
  109. for (auto& [name, m] : classRef->methods) {
  110. ret += "\t";
  111. ret += m->toString() + "\n";
  112. }
  113. for (auto& [name, f] : classRef->fields) {
  114. ret += "\t";
  115. ret += f->toString() + "\n";
  116. }
  117. return ret + "\nParent:\n" + parentScope.toString();
  118. }
  119. std::shared_ptr<sem::Type> sem::ClassScope::getType(const ast::Type& name)
  120. {
  121. return parentScope.getType(name);
  122. }
  123. std::shared_ptr<sem::Type> sem::ClassScope::getReturnableType(void)
  124. {
  125. return nullptr;
  126. }
  127. sem::LocalScope::LocalScope(Scope& parentScope, Method* enclosingMethod) :
  128. parentScope{ parentScope },
  129. returnType{ enclosingMethod->returnType },
  130. enclosingMethod{ enclosingMethod }
  131. {
  132. }
  133. sem::LocalScope::LocalScope(LocalScope& parentScope) :
  134. parentScope{ parentScope },
  135. returnType{ parentScope.returnType },
  136. enclosingMethod{ parentScope.enclosingMethod }
  137. {
  138. }
  139. void sem::LocalScope::putVariable(const std::string& name, std::unique_ptr<Variable> v)
  140. {
  141. localVariables.insert({name, std::move(v)});
  142. }
  143. sem::SymbolTable<sem::Variable>& sem::LocalScope::getLocals(void)
  144. {
  145. return localVariables;
  146. }
  147. sem::Variable* sem::LocalScope::getVariable(const std::string& name)
  148. {
  149. /*
  150. if (name == "this") {
  151. return enclosingMethod->thisExpression.get();
  152. }
  153. */
  154. auto m = localVariables.find(name);
  155. if (m != localVariables.end())
  156. return (*m).second.get();
  157. return parentScope.getVariable(name);
  158. }
  159. sem::Method* sem::LocalScope::getMethod(const std::string& name)
  160. {
  161. return parentScope.getMethod(name);
  162. }
  163. std::shared_ptr<sem::Type> sem::LocalScope::getType(const ast::Type& name)
  164. {
  165. return parentScope.getType(name);
  166. }
  167. std::shared_ptr<sem::Type> sem::LocalScope::getReturnableType(void)
  168. {
  169. return returnType;
  170. }
  171. std::string sem::LocalScope::toString(void)
  172. {
  173. std::string ret;
  174. for (auto& [name, v] : localVariables) {
  175. ret += "\t";
  176. ret += v->toString() + "\n";
  177. }
  178. return ret + "\nParent:\n" + parentScope.toString();
  179. }
  180. sem::Variable* sem::TypeScope::getVariable(const std::string& name)
  181. {
  182. if (ClassType* ct = dynamic_cast<ClassType*>(&type); ct) {
  183. auto& fields = ct->getClassType()->fields;
  184. if (fields.find(name) != fields.end())
  185. return fields[name].get();
  186. }
  187. return nullptr;
  188. return nullptr;
  189. }
  190. sem::Method* sem::TypeScope::getMethod(const std::string& name)
  191. {
  192. if (ClassType* ct = dynamic_cast<ClassType*>(&type); ct) {
  193. auto& methods = ct->getClassType()->methods;
  194. if (methods.find(name) != methods.end())
  195. return methods[name].get();
  196. }
  197. return nullptr;
  198. }
  199. std::shared_ptr<sem::Type> sem::TypeScope::getType(const ast::Type& name)
  200. {
  201. return nullptr;
  202. }
  203. std::shared_ptr<sem::Type> sem::TypeScope::getReturnableType(void)
  204. {
  205. return nullptr;
  206. }
  207. std::string sem::TypeScope::toString(void)
  208. {
  209. std::string ret;
  210. return ret;
  211. }
  212. sem::Method* sem::NativeTypeScope::getMethod(const std::string& name)
  213. {
  214. auto m = nativeType.nativeMethods.find(name);
  215. if (m != nativeType.nativeMethods.end())
  216. return m->second.get();
  217. else
  218. return TypeScope::getMethod(name);
  219. }