void analyzeClass(Type classType, Writer &writer){ auto eclass = classType.eclass; writer.writeEmojicodeChar(eclass->name); if(eclass->superclass){ writer.writeUInt16(eclass->superclass->index); } else { //If the eclass does not have a superclass the own index gets written writer.writeUInt16(eclass->index); } Scope objectScope(true); //Get the ID offset for this eclass by summing up all superclasses instance variable counts uint16_t offset = 0; for(Class *aClass = eclass->superclass; aClass != nullptr; aClass = aClass->superclass){ offset += aClass->instanceVariables.size(); } writer.writeUInt16(eclass->instanceVariables.size() + offset); //Number of methods inclusive superclass writer.writeUInt16(eclass->nextMethodVti); //Number of eclass methods inclusive superclass writer.writeUInt16(eclass->nextClassMethodVti); //Initializer inclusive superclass writer.writeByte(eclass->inheritsContructors ? 1 : 0); writer.writeUInt16(eclass->nextInitializerVti); writer.writeUInt16(eclass->methodList.size()); writer.writeUInt16(eclass->initializerList.size()); writer.writeUInt16(eclass->classMethodList.size()); for (auto var : eclass->instanceVariables) { CompilerVariable *cv = new CompilerVariable(var->type, offset++, 1, false); cv->variable = var; objectScope.setLocalVariable(var->name, cv); } pushScope(&objectScope); for (auto method : eclass->methodList) { StaticFunctionAnalyzer::writeAndAnalyzeProcedure(*method, writer, classType); } for (auto initializer : eclass->initializerList) { StaticFunctionAnalyzer::writeAndAnalyzeProcedure(*initializer, writer, classType, false, initializer); } popScope(); for (auto classMethod : eclass->classMethodList) { StaticFunctionAnalyzer::writeAndAnalyzeProcedure(*classMethod, writer, classType, true); } if (eclass->instanceVariables.size() > 0 && eclass->initializerList.size() == 0) { auto str = classType.toString(typeNothingness, true); compilerWarning(eclass->classBegin, "Class %s defines %d instances variables but has no initializers.", str.c_str(), eclass->instanceVariables.size()); } writer.writeUInt16(eclass->protocols().size()); if (eclass->protocols().size() > 0) { auto biggestPlaceholder = writer.writePlaceholder<uint16_t>(); auto smallestPlaceholder = writer.writePlaceholder<uint16_t>(); uint_fast16_t smallestProtocolIndex = UINT_FAST16_MAX; uint_fast16_t biggestProtocolIndex = 0; for (auto protocol : eclass->protocols()) { writer.writeUInt16(protocol->index); if (protocol->index > biggestProtocolIndex) { biggestProtocolIndex = protocol->index; } if (protocol->index < smallestProtocolIndex) { smallestProtocolIndex = protocol->index; } writer.writeUInt16(protocol->methods().size()); for (auto method : protocol->methods()) { Method *clm = eclass->getMethod(method->name); if (clm == nullptr) { auto className = classType.toString(typeNothingness, true); auto protocolName = Type(protocol, false).toString(typeNothingness, true); ecCharToCharStack(method->name, ms); compilerError(eclass->classBegin, "Class %s does not agree to protocol %s: Method %s is missing.", className.c_str(), protocolName.c_str(), ms); } writer.writeUInt16(clm->vti); clm->checkPromises(method, "protocol definition", classType); } } biggestPlaceholder.write(biggestProtocolIndex); smallestPlaceholder.write(smallestProtocolIndex); } }