void TSConstructObject::Destruct(TStackValue& constructed_object, TGlobalRunContext run_context) { TSMethod* destr = object_type->GetDestructor(); if (destr != NULL) { destr->Run(TMethodRunContext(run_context.static_fields, nullptr, nullptr, &constructed_object)); } }
void Visit(SyntaxApi::IOperations::IThis *operation_node) { if (method->GetSyntax()->IsStatic()) syntax_node->Error("Ключевое слово 'this' можно использовать только в нестатических методах!"); TSExpression::TGetThis* result = new TSExpression::TGetThis(owner); Return(result); }
void Visit(SyntaxApi::IOperations::IGetMemberOp* operation_node) { TSOperation *left; left = VisitNode(operation_node->GetLeft()); TExpressionResult left_result = left->GetFormalParameter(); auto left_class = dynamic_cast<TSClass*>(left_result.GetClass()); if (left_result.IsMethods()) syntax_node->Error("Оператор доступа к члену класса нельзя применить к методу!"); if (left_result.IsType()) { auto left_result_class = dynamic_cast<TSClass*>(left_result.GetType()); if (left_result_class->GetSyntax()->IsEnumeration()) { int id = left_result_class->GetSyntax()->GetEnumId(operation_node->GetName()); //TODO ввести спец функции min max count if (id == -1) syntax_node->Error("Перечислимого типа с таким именем не существует!"); else { delete left; TSExpression::TEnumValue* result = new TSExpression::TEnumValue(owner, dynamic_cast<TSClass*>(left_result.GetType())); result->val = id; Return(result); } } else { TSClassField* static_member = left_result_class->GetField(operation_node->GetName(), true, true); if (static_member != nullptr) { TSExpression::TGetClassField* result = new TSExpression::TGetClassField( left, left_result, static_member); Return(result); } else { std::vector<SemanticApi::ISMethod*> methods; if (left_result_class->GetMethods(methods, operation_node->GetName(), SemanticApi::Filter::True)) { TSExpression::TGetMethods* result = new TSExpression::TGetMethods( left, left_result, TExpressionResult(methods, method->GetSyntax()->IsStatic())); Return(result); } else syntax_node->Error("Статического поля или метода с таким именем не существует!"); } } } else { TSClassField* member = (left_class != nullptr) ? left_class->GetField(operation_node->GetName(), true) : nullptr; if (member != nullptr) { if (member->GetSyntax()->IsStatic()) syntax_node->Error("Оператор доступа к члену класса нельзя применить к объекту для доступа к статическому члену, \nвместо объекта следует использовать имя класса!"); ValidateAccess(syntax_node, owner, member); TSExpression::TGetClassField* result = new TSExpression::TGetClassField( left, left_result, member); Return(result); } else { std::vector<SemanticApi::ISMethod*> methods; if (left_class->GetMethods(methods, operation_node->GetName(), SemanticApi::Filter::False)) { TSExpression::TGetMethods* result = new TSExpression::TGetMethods( left, left_result, TExpressionResult(methods, false)); Return(result); } else syntax_node->Error("Члена класса с таким именем не существует!"); } } }
void Visit(SyntaxApi::IOperations::IId* operation_node) { SemanticApi::IVariable* var = parent->GetVar(operation_node->GetName()); if (var != nullptr) { switch (var->GetVariableType()) { case SemanticApi::VariableType::ClassField: { ValidateAccess(syntax_node, owner, (TSClassField*)var); auto var_field = dynamic_cast<TSClassField*>(var); if ((!var_field->GetSyntax()->IsStatic()) && method->GetSyntax()->IsStatic()) syntax_node->Error("К нестатическому полю класса нельзя обращаться из статического метода!"); TSExpression::TGetClassField* result = new TSExpression::TGetClassField( nullptr, TExpressionResult(dynamic_cast<TSClass*>(var_field->GetClass()), true), var_field); Return(result); }break; case SemanticApi::VariableType::Local: { TSExpression::TGetLocal* result = new TSExpression::TGetLocal(dynamic_cast<TSLocalVar*>(var)); Return(result); }break; case SemanticApi::VariableType::Parameter: { TSExpression::TGetParameter* result = new TSExpression::TGetParameter(dynamic_cast<TSParameter*>(var)); Return(result); }break; default: assert(false);//ошибка в поиске переменной } } else { std::vector<SemanticApi::ISMethod*> methods; if (method->GetSyntax()->IsStatic()) { owner->GetMethods(methods, operation_node->GetName(), SemanticApi::Filter::True); if (methods.size() == 0) { std::vector<SemanticApi::ISMethod*> temp; if (owner->GetMethods(temp, operation_node->GetName(), SemanticApi::Filter::False)) { syntax_node->Error("К нестатическому методу класса нельзя обращаться из статического метода!"); } } } else { owner->GetMethods(methods, operation_node->GetName()); } if (methods.size() != 0) { TSExpression::TGetMethods* result = new TSExpression::TGetMethods(nullptr, TExpressionResult(), TExpressionResult(methods, method->GetSyntax()->IsStatic())); Return(result); } else { syntax_node->Error("Неизвестный идентификатор!"); } } }
TSMethod* TSyntaxAnalyzer::GetMethod(char* use_method) { lexer->ParseSource(use_method); std::unique_ptr<TMethod> method_decl_syntax(new TMethod(base_class.get())); method_decl_syntax->AnalyzeSyntax(lexer.get(), false); lexer->GetToken(TTokenType::Done); std::unique_ptr<TSMethod> method_decl(new TSMethod(sem_base_class->GetNestedByFullName(method_decl_syntax->GetOwner()->GetFullClassName(),1), method_decl_syntax.get())); method_decl->Build(); //method_decl->LinkBody(&static_fields, &static_variables); std::vector<TSMethod*> methods; TSMethod* method = NULL; switch (method_decl->GetSyntax()->GetMemberType()) { case TClassMember::Func: method_decl->GetOwner()->GetMethods(methods, method_decl->GetSyntax()->GetName()); break; case TClassMember::DefaultConstr: method = method_decl->GetOwner()->GetDefConstr(); break; case TClassMember::CopyConstr: method_decl->GetOwner()->GetCopyConstructors(methods); break; case TClassMember::MoveConstr: method_decl->GetOwner()->GetMoveConstructors(methods); break; case TClassMember::Destr: method = method_decl->GetOwner()->GetDestructor(); break; case TClassMember::Operator: method_decl->GetOwner()->GetOperators(methods, method_decl->GetSyntax()->GetOperatorType()); break; case TClassMember::Conversion: method = method_decl->GetOwner()->GetConversion(method_decl->GetParam(0)->GetSyntax()->IsRef(), method_decl->GetRetClass()); break; default:assert(false); } TClassMember temp = method_decl->GetSyntax()->GetMemberType(); if (temp == TClassMember::Func || temp == TClassMember::CopyConstr || temp == TClassMember::MoveConstr || temp == TClassMember::Operator) { for (size_t i = 0; i<methods.size(); i++) { if (method_decl->GetParamsCount() == 0 && methods[i]->GetParamsCount() == 0){ method = methods[i]; break; } if (method_decl->GetParamsCount() != methods[i]->GetParamsCount())continue; for (int k = 0; k < method_decl->GetParamsCount(); k++) { if (!methods[i]->GetParam(k)->IsEqualTo(*method_decl->GetParam(k))) goto end_search; } method = methods[i]; i = methods.size(); end_search:continue; } } if (method != NULL) { if (method_decl->GetSyntax()->IsStatic() != method->GetSyntax()->IsStatic()) lexer->Error("Метод отличается по статичности!"); if (method_decl->GetSyntax()->IsExternal() != method->GetSyntax()->IsExternal()) lexer->Error("Несоответствует классификатор extern!"); if (method_decl->GetRetClass() != method->GetRetClass() || method_decl->GetSyntax()->IsReturnRef() != method->GetSyntax()->IsReturnRef()) lexer->Error("Метод возвращает другое значение!"); return method; } else lexer->Error("Такого метода не существует!"); return NULL; }