123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- #include "Scope.h"
- #include "Ast.h"
- #include "Semantic.h"
- #include "Type.h"
- #include "Builtin.h"
- using namespace qlow;
- sem::Scope::~Scope(void)
- {
- }
- sem::Method* sem::Scope::resolveMethod(const std::string& name,
- const std::vector<TypeId> argumentTypes)
- {
- sem::Method* m = getMethod(name);
- if (!m)
- return nullptr;
-
- if (m->arguments.size() != argumentTypes.size())
- return nullptr;
-
- for (size_t i = 0; i < argumentTypes.size(); i++) {
- if (!m->arguments[i]->type->equals(*argumentTypes[i]))
- return nullptr;
- }
-
- return m;
- }
- sem::Variable* sem::GlobalScope::getVariable(const std::string& name)
- {
- return nullptr;
- }
- sem::Method* sem::GlobalScope::getMethod(const std::string& name)
- {
- if (const auto& f = functions.find(name); f != functions.end()) {
- return f->second.get();
- }
- return nullptr;
- }
- std::shared_ptr<sem::Type> sem::GlobalScope::getType(const ast::Type& name)
- {
- if (const auto* arr = dynamic_cast<const ast::ArrayType*>(&name); arr) {
- return std::make_shared<sem::ArrayType>(getType(*arr->arrayType));
- }
-
- if (const auto* ptr = dynamic_cast<const ast::PointerType*>(&name)) {
- return std::make_shared<sem::PointerType>(getType(*ptr->derefType));
- }
-
- auto native = NativeScope::getInstance().getType(name);
- if (native) {
- return native;
- }
-
- const auto* classType = dynamic_cast<const ast::ClassType*>(&name);
-
- if (!classType)
- throw "internal error, non class-type top-level type";
-
-
-
- auto t = classes.find(classType->typeName);
- if (t != classes.end())
- return std::make_shared<sem::ClassType>(t->second.get());
-
- return nullptr;
- }
- std::shared_ptr<sem::Type> sem::GlobalScope::getReturnableType(void)
- {
- return nullptr;
- }
- std::string sem::GlobalScope::toString(void)
- {
- std::string ret;
- ret += "Classes:\n";
- for (auto& [name, c] : classes) {
- ret += "\t";
- ret += c->toString() + "\n";
- }
- return ret;
- }
- std::shared_ptr<sem::Type> sem::NativeScope::getType(const ast::Type& name)
- {
- if (const auto* arr = dynamic_cast<const ast::ArrayType*>(&name); arr) {
- return std::make_shared<sem::ArrayType>(getType(*arr->arrayType));
- }
-
- const auto* classType = dynamic_cast<const ast::ClassType*>(&name);
-
- if (!classType)
- return std::make_shared<sem::NativeType>(NativeType::VOID);
-
-
- auto t = types.find(classType->typeName);
- if (t != types.end())
- return *t->second;
-
- return nullptr;
- }
- sem::NativeScope sem::NativeScope::instance = sem::generateNativeScope();
- sem::NativeScope& sem::NativeScope::getInstance(void)
- {
- return instance;
- }
- std::string sem::NativeScope::toString(void)
- {
- return "NativeScope";
- }
- sem::Variable* sem::ClassScope::getVariable(const std::string& name)
- {
- if (classRef == nullptr)
- return parentScope.getVariable(name);
- auto m = classRef->fields.find(name);
- if (m != classRef->fields.end())
- return (*m).second.get();
-
- return parentScope.getVariable(name);
- }
- sem::Method* sem::ClassScope::getMethod(const std::string& name)
- {
- if (classRef == nullptr)
- return parentScope.getMethod(name);
- auto m = classRef->methods.find(name);
- if (m != classRef->methods.end())
- return (*m).second.get();
-
- return parentScope.getMethod(name);
- }
- std::string sem::ClassScope::toString(void)
- {
- std::string ret;
- for (auto& [name, m] : classRef->methods) {
- ret += "\t";
- ret += m->toString() + "\n";
- }
- for (auto& [name, f] : classRef->fields) {
- ret += "\t";
- ret += f->toString() + "\n";
- }
- return ret + "\nParent:\n" + parentScope.toString();
- }
- sem::TypeId sem::ClassScope::getType(const ast::Type& name)
- {
- return parentScope.getType(name);
- }
- sem::TypeId sem::ClassScope::getReturnableType(void)
- {
- return nullptr;
- }
- sem::LocalScope::LocalScope(Scope& parentScope, Method* enclosingMethod) :
- parentScope{ parentScope },
- returnType{ enclosingMethod->returnType },
- enclosingMethod{ enclosingMethod }
- {
- }
- sem::LocalScope::LocalScope(LocalScope& parentScope) :
- parentScope{ parentScope },
- returnType{ parentScope.returnType },
- enclosingMethod{ parentScope.enclosingMethod }
- {
- }
- void sem::LocalScope::putVariable(const std::string& name, std::unique_ptr<Variable> v)
- {
- localVariables.insert({name, std::move(v)});
- }
- sem::SymbolTable<sem::Variable>& sem::LocalScope::getLocals(void)
- {
- return localVariables;
- }
- sem::Variable* sem::LocalScope::getVariable(const std::string& name)
- {
- /*
- if (name == "this") {
- return enclosingMethod->thisExpression.get();
- }
- */
-
- auto m = localVariables.find(name);
- if (m != localVariables.end())
- return (*m).second.get();
-
- return parentScope.getVariable(name);
- }
- sem::Method* sem::LocalScope::getMethod(const std::string& name)
- {
- return parentScope.getMethod(name);
- }
- std::shared_ptr<sem::Type> sem::LocalScope::getType(const ast::Type& name)
- {
- return parentScope.getType(name);
- }
- std::shared_ptr<sem::Type> sem::LocalScope::getReturnableType(void)
- {
- return returnType;
- }
- std::string sem::LocalScope::toString(void)
- {
- std::string ret;
- for (auto& [name, v] : localVariables) {
- ret += "\t";
- ret += v->toString() + "\n";
- }
- return ret + "\nParent:\n" + parentScope.toString();
- }
- sem::Variable* sem::TypeScope::getVariable(const std::string& name)
- {
- if (ClassType* ct = dynamic_cast<ClassType*>(&type); ct) {
- auto& fields = ct->getClassType()->fields;
- if (fields.find(name) != fields.end())
- return fields[name].get();
- }
- return nullptr;
- return nullptr;
- }
- sem::Method* sem::TypeScope::getMethod(const std::string& name)
- {
- if (ClassType* ct = dynamic_cast<ClassType*>(&type); ct) {
- auto& methods = ct->getClassType()->methods;
- if (methods.find(name) != methods.end())
- return methods[name].get();
- }
- return nullptr;
- }
- std::shared_ptr<sem::Type> sem::TypeScope::getType(const ast::Type& name)
- {
- return nullptr;
- }
- std::shared_ptr<sem::Type> sem::TypeScope::getReturnableType(void)
- {
- return nullptr;
- }
- std::string sem::TypeScope::toString(void)
- {
- std::string ret;
- return ret;
- }
- sem::Method* sem::NativeTypeScope::getMethod(const std::string& name)
- {
- auto m = nativeType.nativeMethods.find(name);
- if (m != nativeType.nativeMethods.end())
- return m->second.get();
- else
- return TypeScope::getMethod(name);
- }
|