Scope.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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<TypeId> 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. if (const auto* ptr = dynamic_cast<const ast::PointerType*>(&name)) {
  41. return std::make_shared<sem::PointerType>(getType(*ptr->derefType));
  42. }
  43. auto native = NativeScope::getInstance().getType(name);
  44. if (native) {
  45. return native;
  46. }
  47. const auto* classType = dynamic_cast<const ast::ClassType*>(&name);
  48. if (!classType)
  49. throw "internal error, non class-type top-level type";
  50. auto t = classes.find(classType->typeName);
  51. if (t != classes.end())
  52. return std::make_shared<sem::ClassType>(t->second.get());
  53. return nullptr;
  54. }
  55. std::shared_ptr<sem::Type> sem::GlobalScope::getReturnableType(void)
  56. {
  57. return nullptr;
  58. }
  59. std::string sem::GlobalScope::toString(void)
  60. {
  61. std::string ret;
  62. ret += "Classes:\n";
  63. for (auto& [name, c] : classes) {
  64. ret += "\t";
  65. ret += c->toString() + "\n";
  66. }
  67. return ret;
  68. }
  69. std::shared_ptr<sem::Type> sem::NativeScope::getType(const ast::Type& name)
  70. {
  71. if (const auto* arr = dynamic_cast<const ast::ArrayType*>(&name); arr) {
  72. return std::make_shared<sem::ArrayType>(getType(*arr->arrayType));
  73. }
  74. const auto* classType = dynamic_cast<const ast::ClassType*>(&name);
  75. if (!classType)
  76. return std::make_shared<sem::NativeType>(NativeType::VOID);
  77. auto t = types.find(classType->typeName);
  78. if (t != types.end())
  79. return *t->second;
  80. return nullptr;
  81. }
  82. sem::NativeScope sem::NativeScope::instance = sem::generateNativeScope();
  83. sem::NativeScope& sem::NativeScope::getInstance(void)
  84. {
  85. return instance;
  86. }
  87. std::string sem::NativeScope::toString(void)
  88. {
  89. return "NativeScope";
  90. }
  91. sem::Variable* sem::ClassScope::getVariable(const std::string& name)
  92. {
  93. if (classRef == nullptr)
  94. return parentScope.getVariable(name);
  95. auto m = classRef->fields.find(name);
  96. if (m != classRef->fields.end())
  97. return (*m).second.get();
  98. return parentScope.getVariable(name);
  99. }
  100. sem::Method* sem::ClassScope::getMethod(const std::string& name)
  101. {
  102. if (classRef == nullptr)
  103. return parentScope.getMethod(name);
  104. auto m = classRef->methods.find(name);
  105. if (m != classRef->methods.end())
  106. return (*m).second.get();
  107. return parentScope.getMethod(name);
  108. }
  109. std::string sem::ClassScope::toString(void)
  110. {
  111. std::string ret;
  112. for (auto& [name, m] : classRef->methods) {
  113. ret += "\t";
  114. ret += m->toString() + "\n";
  115. }
  116. for (auto& [name, f] : classRef->fields) {
  117. ret += "\t";
  118. ret += f->toString() + "\n";
  119. }
  120. return ret + "\nParent:\n" + parentScope.toString();
  121. }
  122. sem::TypeId sem::ClassScope::getType(const ast::Type& name)
  123. {
  124. return parentScope.getType(name);
  125. }
  126. sem::TypeId sem::ClassScope::getReturnableType(void)
  127. {
  128. return nullptr;
  129. }
  130. sem::LocalScope::LocalScope(Scope& parentScope, Method* enclosingMethod) :
  131. parentScope{ parentScope },
  132. returnType{ enclosingMethod->returnType },
  133. enclosingMethod{ enclosingMethod }
  134. {
  135. }
  136. sem::LocalScope::LocalScope(LocalScope& parentScope) :
  137. parentScope{ parentScope },
  138. returnType{ parentScope.returnType },
  139. enclosingMethod{ parentScope.enclosingMethod }
  140. {
  141. }
  142. void sem::LocalScope::putVariable(const std::string& name, std::unique_ptr<Variable> v)
  143. {
  144. localVariables.insert({name, std::move(v)});
  145. }
  146. sem::SymbolTable<sem::Variable>& sem::LocalScope::getLocals(void)
  147. {
  148. return localVariables;
  149. }
  150. sem::Variable* sem::LocalScope::getVariable(const std::string& name)
  151. {
  152. /*
  153. if (name == "this") {
  154. return enclosingMethod->thisExpression.get();
  155. }
  156. */
  157. auto m = localVariables.find(name);
  158. if (m != localVariables.end())
  159. return (*m).second.get();
  160. return parentScope.getVariable(name);
  161. }
  162. sem::Method* sem::LocalScope::getMethod(const std::string& name)
  163. {
  164. return parentScope.getMethod(name);
  165. }
  166. std::shared_ptr<sem::Type> sem::LocalScope::getType(const ast::Type& name)
  167. {
  168. return parentScope.getType(name);
  169. }
  170. std::shared_ptr<sem::Type> sem::LocalScope::getReturnableType(void)
  171. {
  172. return returnType;
  173. }
  174. std::string sem::LocalScope::toString(void)
  175. {
  176. std::string ret;
  177. for (auto& [name, v] : localVariables) {
  178. ret += "\t";
  179. ret += v->toString() + "\n";
  180. }
  181. return ret + "\nParent:\n" + parentScope.toString();
  182. }
  183. sem::Variable* sem::TypeScope::getVariable(const std::string& name)
  184. {
  185. if (ClassType* ct = dynamic_cast<ClassType*>(&type); ct) {
  186. auto& fields = ct->getClassType()->fields;
  187. if (fields.find(name) != fields.end())
  188. return fields[name].get();
  189. }
  190. return nullptr;
  191. return nullptr;
  192. }
  193. sem::Method* sem::TypeScope::getMethod(const std::string& name)
  194. {
  195. if (ClassType* ct = dynamic_cast<ClassType*>(&type); ct) {
  196. auto& methods = ct->getClassType()->methods;
  197. if (methods.find(name) != methods.end())
  198. return methods[name].get();
  199. }
  200. return nullptr;
  201. }
  202. std::shared_ptr<sem::Type> sem::TypeScope::getType(const ast::Type& name)
  203. {
  204. return nullptr;
  205. }
  206. std::shared_ptr<sem::Type> sem::TypeScope::getReturnableType(void)
  207. {
  208. return nullptr;
  209. }
  210. std::string sem::TypeScope::toString(void)
  211. {
  212. std::string ret;
  213. return ret;
  214. }
  215. sem::Method* sem::NativeTypeScope::getMethod(const std::string& name)
  216. {
  217. auto m = nativeType.nativeMethods.find(name);
  218. if (m != nativeType.nativeMethods.end())
  219. return m->second.get();
  220. else
  221. return TypeScope::getMethod(name);
  222. }