void CreateInternalClasses(Lexer::ILexer* lexer, SyntaxApi::IClass* base_class, SemanticApi::ISClass* _sbase_class) { lexer->ParseSource("class dword {}"); SyntaxApi::IClass* t_syntax = SyntaxApi::AnalyzeNestedClass(lexer, base_class); auto sbase_class = dynamic_cast<TSClass*>(_sbase_class); TSClass* t = new TSClass(sbase_class, t_syntax); t->SetSize(1); t->SetSignatureLinked(); t->SetBodyLinked(); sbase_class->AddClass(t); }
void TSyntaxAnalyzer::CreateInternalClasses() { TNameId name_id = lexer->GetIdFromName("dword"); TClass* t_syntax = new TClass(base_class.get()); base_class->AddNested(t_syntax); t_syntax->name = name_id; TSClass* t = new TSClass(sem_base_class.get(), t_syntax); t->SetSize(1); t->SetSignatureLinked(); t->SetBodyLinked(); sem_base_class->AddClass(t); }
TSClass* RegisterEnum(TClassRegistryParams& params, const char* source) { auto syntax = params.syntax; TClass* cl = new TClass(syntax->base_class.get()); syntax->base_class->AddNested(cl); syntax->lexer.ParseSource(source); cl->AnalyzeSyntax(syntax->lexer); syntax->lexer.GetToken(TTokenType::Done); TSClass* scl = new TSClass(syntax->sem_base_class.get(), cl); syntax->sem_base_class->AddClass(scl); scl->Build(); std::vector<TSClassField*> static_fields; std::vector<TSLocalVar*> static_variables; TGlobalBuildContext global_build_context(&static_fields, &static_variables); scl->LinkSignature(global_build_context); scl->InitAutoMethods(); scl->LinkBody(global_build_context); scl->CheckForErrors(); std::vector<TSClass*> owners; scl->CalculateSizes(owners); scl->CalculateMethodsSizes(); owners.clear(); syntax->sem_base_class->CalculateSizes(owners);//т.к. в этом классе могут использоваться другие шаблонные класса, реализацию которых нужно обновить InitializeStaticClassFields(static_fields, *params.static_objects); InitializeStaticVariables(static_variables, *params.static_objects); return scl; }
ISClass* SAnalyzeExternalClass(Lexer::ILexer* lexer, SyntaxApi::IClass* base_class, SemanticApi::ISClass* _sbase_class, TExternalClassDecl decl, TGlobalBuildContext build_context, std::vector<SemanticApi::TExternalSMethod> external_classes_bindings, int& curr_bind) { auto sbase_class = dynamic_cast<TSClass*>(_sbase_class); lexer->ParseSource(decl.source.c_str()); auto cl = SyntaxApi::AnalyzeNestedClass(lexer, base_class); TSClass* scl = new TSClass(sbase_class, cl); sbase_class->AddClass(scl); scl->Build(); scl->LinkSignature(build_context); scl->SetSize(decl.size); if (scl->GetType() == SemanticApi::TNodeWithTemplatesType::Template) scl->SetAutoMethodsInitialized(); else scl->InitAutoMethods(); //scl->CalculateMethodsSizes(); //TODO проверка что заданы все external_func scl->SetExternal(external_classes_bindings, curr_bind); return scl; }
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("Неизвестный идентификатор!"); } } }