Exemplo n.º 1
0
std::pair<CallableScoper, int> CallableScoper::flattenedCopy(int argumentCount) const {
    int variableCount = 0;
    CallableScoper scoper = CallableScoper(objectScope());
    Scope &flattenedScope = scoper.pushScope();
    
    scoper.nextVariableID_ += argumentCount;
    
    for (auto &scope : scopes_) {
        for (auto &it : scope.map_) {
            auto variable = Variable(it.second.type, argumentCount + it.second.id(),
                                     it.second.initialized, true, it.second.definitionToken);
            flattenedScope.setLocalVariable(it.first, variable);
        }
        scoper.nextVariableID_ += scope.map_.size();
        variableCount += scope.map_.size();
    }
    scoper.syncMaxVariableCount();
    
    return std::pair<CallableScoper, int>(scoper, variableCount);
}
Exemplo n.º 2
0
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);
    }
}