|  | @@ -1,4 +1,5 @@
 | 
	
		
			
				|  |  |  #include "Semantic.h"
 | 
	
		
			
				|  |  | +#include "Ast.h"
 | 
	
		
			
				|  |  |  #include "AstVisitor.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include "CodegenVisitor.h"
 | 
	
	
		
			
				|  | @@ -13,8 +14,10 @@ namespace sem
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  std::unique_ptr<GlobalScope>
 | 
	
		
			
				|  |  | -    createFromAst(const std::vector<std::unique_ptr<qlow::ast::Class>>& classes)
 | 
	
		
			
				|  |  | +    createFromAst(const std::vector<std::unique_ptr<qlow::ast::AstObject>>& objects)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    Logger& logger = Logger::getInstance();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #ifdef DEBUGGING
 | 
	
		
			
				|  |  |      printf("starting building semantic representation\n");
 | 
	
	
		
			
				|  | @@ -22,8 +25,13 @@ std::unique_ptr<GlobalScope>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // create classes
 | 
	
		
			
				|  |  |      std::unique_ptr<sem::GlobalScope> globalScope = std::make_unique<sem::GlobalScope>();
 | 
	
		
			
				|  |  | -    for (auto& astClass : classes) {
 | 
	
		
			
				|  |  | -        globalScope->classes[astClass->name] = std::make_unique<sem::Class>(astClass.get(), *globalScope);
 | 
	
		
			
				|  |  | +    for (auto& astObject : objects) {
 | 
	
		
			
				|  |  | +        if (auto* cls = dynamic_cast<ast::Class*>(astObject.get()); cls) {
 | 
	
		
			
				|  |  | +            globalScope->classes[cls->name] = std::make_unique<sem::Class>(cls, *globalScope);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else if (auto* function = dynamic_cast<ast::MethodDefinition*>(astObject.get()); function) {
 | 
	
		
			
				|  |  | +            globalScope->functions[function->name] = std::make_unique<sem::Method>(function, *globalScope);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #ifdef DEBUGGING
 | 
	
	
		
			
				|  | @@ -38,14 +46,14 @@ std::unique_ptr<GlobalScope>
 | 
	
		
			
				|  |  |              
 | 
	
		
			
				|  |  |              if (auto* field = dynamic_cast<qlow::ast::FieldDeclaration*> (feature.get()); field) {
 | 
	
		
			
				|  |  |                  if (semClass->fields.find(field->name) != semClass->fields.end()) // throw, if field already exists
 | 
	
		
			
				|  |  | -                    throw SemanticException(SemanticException::DUPLICATE_FIELD_DECLARATION, field->name, field->pos);
 | 
	
		
			
				|  |  | +                    throw SemanticError(SemanticError::DUPLICATE_FIELD_DECLARATION, field->name, field->pos);
 | 
	
		
			
				|  |  |                  
 | 
	
		
			
				|  |  |                  // otherwise add to the fields list
 | 
	
		
			
				|  |  |                  semClass->fields[field->name] = unique_dynamic_cast<Field>(field->accept(av, semClass->scope));
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              else if (auto* method = dynamic_cast<qlow::ast::MethodDefinition*> (feature.get()); method) {
 | 
	
		
			
				|  |  |                  if (semClass->methods.find(method->name) != semClass->methods.end()) // throw, if method already exists
 | 
	
		
			
				|  |  | -                    throw SemanticException(SemanticException::DUPLICATE_METHOD_DEFINITION, method->name, method->pos);
 | 
	
		
			
				|  |  | +                    throw SemanticError(SemanticError::DUPLICATE_METHOD_DEFINITION, method->name, method->pos);
 | 
	
		
			
				|  |  |                  
 | 
	
		
			
				|  |  |                  // otherwise add to the methods list
 | 
	
		
			
				|  |  |                  semClass->methods[method->name] = unique_dynamic_cast<Method>(method->accept(av, semClass->scope));
 | 
	
	
		
			
				|  | @@ -57,6 +65,16 @@ std::unique_ptr<GlobalScope>
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  | +    for (auto& [name, method] : globalScope->functions) {
 | 
	
		
			
				|  |  | +        auto returnType = globalScope->getType(method->astNode->type);
 | 
	
		
			
				|  |  | +        if (returnType) {
 | 
	
		
			
				|  |  | +            method->returnType = returnType.value();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else {
 | 
	
		
			
				|  |  | +            SemanticError se(SemanticError::UNKNOWN_TYPE, method->astNode->type, method->astNode->pos);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  |  #ifdef DEBUGGING
 | 
	
		
			
				|  |  |      printf("created all methods and fields\n");
 | 
	
		
			
				|  |  |  #endif
 | 
	
	
		
			
				|  | @@ -195,19 +213,6 @@ std::string FeatureCallStatement::toString(void) const
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -std::string SemanticException::getMessage(void) const
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    static std::map<ErrorCode, std::string> error = {
 | 
	
		
			
				|  |  | -        {UNKNOWN_TYPE, "unknown type"},
 | 
	
		
			
				|  |  | -        {FEATURE_NOT_FOUND, "method or variable not found"}
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    std::string pos = std::to_string(where.first_line) + ":" +
 | 
	
		
			
				|  |  | -        std::to_string(where.first_column);
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    return pos + ": " + error[errorCode] + ": " + message;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 |