示例#1
0
void X86::declareMatrix(int decl_type, int type, string name, list<string> dims) {
  int size = 1;
  for(list<string>::iterator it = dims.begin(); it != dims.end(); it++) {
    size *= atoi((*it).c_str());
  }


  if(decl_type == VAR_GLOBAL) {
    stringstream s;
    switch(type) {
      case TIPO_INTEIRO:
      case TIPO_REAL:
      case TIPO_CARACTERE:
      case TIPO_LOGICO:
      case TIPO_LITERAL:
        s << X86::makeID(name) << " times " << size << " dd 0";
        break;
      default:
        GPTDisplay::self()->showError("Erro interno: tipo nao suportado (X86::declarePrimitive).");
        exit(1);
    }
    writeDATA(s.str());
  } else if(decl_type == VAR_PARAM) {
    _subprograms[currentScope()].declareParam(name, type, size);
  } else if(decl_type == VAR_LOCAL) {
    _subprograms[currentScope()].declareLocal(name, size);
  } else {
    GPTDisplay::self()->showError("Erro interno: X86::declareMatrix).");
    exit(1);
  }
}
示例#2
0
void X86::declarePrimitive(int decl_type, const string& name, int type) {
  stringstream s;
  if(decl_type == VAR_GLOBAL) {
    //all sizes have 32 bits (double word)
    switch(type) {
      case TIPO_INTEIRO:
      case TIPO_REAL:
      case TIPO_CARACTERE:
      case TIPO_LITERAL:
      case TIPO_LOGICO:
        s << X86::makeID(name) << " dd 0";
        writeDATA(s.str());
        break;
      default:
        GPTDisplay::self()->showError("Erro interno: tipo nao suportado (X86::declarePrimitive).");
        exit(1);
    }
  } else if(decl_type == VAR_PARAM) {
    _subprograms[currentScope()].declareParam(name, type);
  } else if(decl_type == VAR_LOCAL) {
    _subprograms[currentScope()].declareLocal(name);
  } else {
    GPTDisplay::self()->showError("Erro interno: X86::declarePrimitive).");
    exit(1);
  }
}
示例#3
0
文件: nodeGen.cpp 项目: ardeujho/self
 Node* NodeGen::uncommonBranch(PRegBList* exprStack, bool restartSend) {
   assert(SICDeferUncommonBranches, "shouldn't use uncommon traps");
   Node* n = APPEND(new UncommonNode(exprStack, restartSend));
   assert(currentScope()->isCodeScope(), "must be non-access");
   ((SCodeScope*)currentScope())->addSend(exprStack);
   current = NULL;
   return n;
 }
示例#4
0
文件: nodeGen.cpp 项目: ardeujho/self
 void NodeGen::loadArg(fint argNo, PReg* from, bool isPrimCall) {
   Unused(isPrimCall);
   assert(currentScope()->isCodeScope(), "oops");
   SCodeScope* s = (SCodeScope*)currentScope();
   fint bci = s->bci();
   Location l = argNo == -1 ? ReceiverReg : ArgLocation(argNo);
               // weird arg numbering - 0 is 1st arg, not receiver
   // uses aren't right yet (call should have use) -fix this
   loadArg(from, new ArgSAPReg(s, l, true, false, bci, bci));
 }
示例#5
0
BackendScope::~BackendScope() {
    assert(nextScope == nullptr);
    deactivate();

    if (priorScope) {
        priorScope->activate();
        currentScope().set(priorScope);
        assert(priorScope->nextScope == this);
        priorScope->nextScope = nullptr;
    } else {
        currentScope().set(nullptr);
    }
}
示例#6
0
BackendScope::BackendScope(RendererBackend& backend_, ScopeType scopeType_)
    : priorScope(currentScope().get()),
      nextScope(nullptr),
      backend(backend_),
      scopeType(scopeType_) {
    if (priorScope) {
        assert(priorScope->nextScope == nullptr);
        priorScope->nextScope = this;
        priorScope->deactivate();
    }

    activate();

    currentScope().set(this);
}
示例#7
0
void
SymbolTreeBuilder::visit(ConditionNode& node)
{
    node.setScope(currentScope());

    if (node.hasConditionComponent())
    {
        _curStatment = node.condition();
        node.condition()->accept(*this);
        // check condition expression
        if (!_expResult.type->isPromotableToBoolean())
        {
            throw SemanticException("Condition expression can not be promoted to boolean\n",
                                    node);
        }
    }

    if (node.hasOnTrueComponent())
    {
        // begin new scope
        beginScope();
        node.onTrue()->accept(*this);
        endScope();
    }

    if (node.hasOnFalseComponent())
    {
        // begin new scope
        beginScope();
        node.onFalse()->accept(*this);
        endScope();
    }
}
示例#8
0
void
SymbolTreeBuilder::visit(ReturnNode& node)
{
    if (!_curFunctionDecl)
    {
        throw SemanticException("Return statement outside function scope\n",
                                node);
    }

    const char* function_name = _curFunctionDecl->symbolName();
    const FunctionType* func_type = cast_type<FunctionType>(_curFunctionDecl->symbolType());
    const Type* func_return = func_type->typeOfReturnValue();
    // current return type

    if (!func_return->isVoidType() && !node.expression())
    {
        std::stringstream stream;
        stream <<"Function '"
              << function_name
              << "' has return type '"
              << func_return->typeString()
              << "', but we are not returning any" << std::endl;
        throw SemanticException(stream.str(), node);
    }


    if (node.expression())
    {
        if (func_return->isVoidType())
        {
            std::stringstream stream;
            stream <<"Function '"
                  << function_name
                  << "' has return type '"
                  << func_return->typeString()
                  << "', but we are returning type '"
                  << _expResult.type->typeString() <<"'" <<  std::endl;
            throw SemanticException(stream.str(), node);
        }

        node.expression()->accept(*this);

        // check if the return types match
        if(!_expResult.type->isPromotableTo(func_return))
        {
            std::stringstream stream;
            stream <<"Function '"
                  << function_name
                  << "' has return type '"
                  << func_return->typeString()
                  << "', but we are returning type '"
                  << _expResult.type->typeString() <<"'" <<  std::endl;
            throw SemanticException(stream.str(), node);
        }
        _expResult.symbol->markReturnValue();
    }

    node.setScope(currentScope());
    node.setNodeType(_expResult.type);
}
示例#9
0
void
SymbolTreeBuilder::visit(CompareOperatorNode& node)
{
    node.setScope(currentScope());
    node.expressionLeft()->accept(*this);

    ExpressionResult left_type = _expResult;

    node.expressionRight()->accept(*this);

    // evaluate right type
    ExpressionResult right_type = _expResult;
    if (!right_type.type->isPromotableTo(left_type.type))
    {
        std::stringstream stream;
        stream <<"Cannot convert right expression to left, expression type "
              << _expResult.type->typeString()
              <<" cannot be cast to "
             << left_type.type->typeString()
             << std::endl;
        throw SemanticException(stream.str(), node);
    }

    _expResult = left_type;

    Symbol* tmp_sym = _curScope->declareTemporarySymbol(_expResult.type);
    YAL_ASSERT(tmp_sym);
    _curStatment->addSymbolToScope(tmp_sym);

    _expResult = ExpressionResult(BuiltinType::GetBuiltinType(BuiltinType::kBool), tmp_sym);
    node.setNodeType(_expResult.type);
    node.setExpressionResult(_expResult);
}
示例#10
0
void
SymbolTreeBuilder::visit(VariableAccessNode& node)
{
    node.setScope(currentScope());
    const char* symbol_name = node.variableName();
    auto sym = _curScope->resolveSymbol(symbol_name);
    if (!sym)
    {
        std::stringstream stream;
        stream << "Symbol '" << symbol_name
               << "' is undefined"
               << std::endl;
        throw SemanticException(stream.str(), node);
    }

    if (!sym->isVariable())
    {
        std::stringstream stream;
        stream << "Symbol '" << symbol_name
               << "' is not a variable"
               << std::endl;
        throw SemanticException(stream.str(), node);
    }

    _expResult = ExpressionResult(sym->symbolType(), sym);
    node.setNodeType(_expResult.type);
    node.setExpressionResult(_expResult);
    sym->touchRead();
}
const SymTabEntry* 
SymTabMgr::lookUpInScope(string name, SymTabEntry::Kind k) const {
  const SymTabEntry *ste = currentScope(k);
  if ((ste != NULL) && (ste->symTab() != NULL)) {
    ste = ste->symTab()->lookUp(name);
    return ste;
  }
  else return NULL;
}
示例#12
0
void
SymbolTreeBuilder::visit(CodeBodyNode& node)
{
    node.setScope(currentScope());
    for(auto& v : node.statements)
    {
        _curStatment = v.get();
        v->accept(*this);
    }
}
示例#13
0
void
SymbolTreeBuilder::visit(StringCreateNode& node)
{
    node.setScope(currentScope());
    node.constantNode()->accept(*this);
    Symbol* tmp_sym = _curScope->declareTemporarySymbol(StringType::GetType(), Symbol::kFlagNewObject);
    _curStatment->addSymbolToScope(tmp_sym);
    _expResult = ExpressionResult(StringType::GetType(), tmp_sym);
    node.setNodeType(_expResult.type);
    node.setExpressionResult(_expResult);
}
示例#14
0
文件: qscheck.cpp 项目: aschet/qsaqt5
void QSCheckData::registerType( QSClass *t )
{
    Q_ASSERT( !t->asClass() );
    QSClass * scope = currentScope();
    // ### Uncertain as to use identifier or name here?
    QSMember member;
    Q_ASSERT( !scope->member( 0, t->identifier(), &member ) );
    scope->addStaticVariableMember( t->identifier(),
				    env()->typeClass()->createType(t),
				    AttributeExecutable );
}
示例#15
0
void
SymbolTreeBuilder::visit(ArgumentDeclNode& node)
{
    node.setScope(currentScope());
    if (node.isCustomType())
    {
        throw SemanticException("Custom types not yet supported!!!\n", node);
    }

    YAL_ASSERT(_curFunctionDecl);

    auto sym = _curScope->resolveSymbol(node.argumentName());
    if (sym && sym->scope() == _curScope)
    {
        std::stringstream stream;
        stream <<"Variable '"
              << node.argumentName()
              << "' has already been declared as an argument"
              << std::endl;
        throw SemanticException(stream.str(), node);
    }

    Type* arg_data_type = node.argumentType();
    if (node.isCustomType())
    {
        /*sym = _curScope->resolveSymbol(node.argumentId());
        if (!sym)
        {
            _formater.format("Could not find type '%s'\n",
                             node.argumentId());
            logError(node);
            return;
        }

        if (sym->isVariable())
        {
            _formater.format("Symbol type '%s' cannot be a variable name\n",
                             node.argumentId());
            logError(node);
            return;
        }

        arg_data_type = sym->astNode()->nodeType();*/
    }

    const Symbol* result = _curScope->declareSymbol(node.argumentName(),
                                                    arg_data_type,
                                                    Symbol::kFlagAssignable | Symbol::kFlagFunctionParam | Symbol::kFlagVariable);
    (void) result;
    YAL_ASSERT(result);
    node.setNodeType(arg_data_type);
}
示例#16
0
文件: nodeGen.cpp 项目: ardeujho/self
  Node* NodeGen::restart(MergeNode* loopStart,
                         PRegBList* exprStack, SplitSig* s) {
    Node* n = APPEND(new RestartNode(exprStack, s, loopStart));
    // reset current so that any code generated after the restart will
    // be ignored in later phases since there is no path reaching it

    // Next line added by dmu 4/26/07 to try to fix bug:
    //  inlined [3] loop had nsends of 0, but needed mask for call to InterruptCheck
    ((SCodeScope*)currentScope())->addSend(exprStack);
    
    current = new NopNode;
    return n;
  }
示例#17
0
文件: nodeGen.cpp 项目: ardeujho/self
 void NodeGen::pathAssign(PReg* rcvr,
                          realSlotRef* path,
                          PReg* val,
                          bool checkStore) {
   COMMENT("Begin slot assignment");
   int32 offset = smiOop(path->desc->data)->byte_count() - Mem_Tag;
   if (path->holder->is_object_or_map()) {
     PReg* t = new TempPReg(currentScope());
     t = loadPath(path->holder, rcvr, t);
     APPEND(new StoreOffsetNode(val, t, offset, checkStore));  
   } else {
     fatal("don't support vframe lookups");
   }
 }
示例#18
0
void
SymbolTreeBuilder::visit(FunctionDeclBaseNode& node)
{
    node.setScope(currentScope());

    const char* func_name = node.functionNameWithType();
    auto sym = _curScope->resolveSymbol(func_name);
    if (sym)
    {
        std::stringstream stream;
        stream << "Symbol name '" << func_name
        << "' already delcared"
        << std::endl;
        throw SemanticException(stream.str(), node);
    }

    // check for object type
    if (node.isObjectFunction())
    {
        Type* object_type = node.objectType();
        if (object_type->isUndefined())
        {
            std::stringstream stream;
            stream << "Function's object type '"
            << object_type->typeString() << "'"
            << "for function '" <<func_name
            << "' is undefined."
            << std::endl;
            throw SemanticException(stream.str(), node);
        }

        const char* builtin_function = object_type->builtinFunctionSymName(node.functionName());
        if (builtin_function)
        {
            std::stringstream stream;
            stream << "Can not declare function '"
            << func_name << "'"
            << " for type '" <<object_type->typeString()
            << "' since it conflicts with a builtin function."
            << std::endl;
            throw SemanticException(stream.str(), node);
        }
    }



}
示例#19
0
void
SymbolTreeBuilder::visit(PrintArgsNode& node)
{
    node.setScope(currentScope());

    for(auto& v : node.expressions)
    {
        // optimize for strings
        StringCreateNode* str_node = ast_cast<StringCreateNode>(v.get());
        if (str_node)
        {
            v = (std::move(str_node->constantNodePtr()));
            v->setParentNode(&node);
        }
        v->accept(*this);
    }
}
示例#20
0
void
SymbolTreeBuilder::visit(AssignOperatorNode& node)
{
    node.setScope(currentScope());


    node.expressionLeft()->accept(*this);

    ExpressionResult left_exp_result = _expResult;

    if (!left_exp_result.symbol || (left_exp_result.symbol && !left_exp_result.symbol->isAssignable()))
    {
        throw SemanticException("Expression is not assignable", node);
    }

    node.expressionRight()->accept(*this);

    // validate types
    if (!_expResult.type->isPromotableTo(left_exp_result.type))
    {
        std::stringstream stream;
        stream <<"Cannot convert right expression to left, expression type "
              << _expResult.type->typeString()
              <<" cannot be cast to "
             << left_exp_result.type->typeString()
             << std::endl;
        throw SemanticException(stream.str(), node);
    }

    _expResult.symbol->markAssigned();

    if (node.assignOperatorType() == kOperatorTypeCopy
            && !left_exp_result.type->isObjectType()
            && left_exp_result.symbol->isTemporary())
    {
        _curStatment->removeSymbolFromScope(_expResult.symbol);
        _curScope->eraseSymbol(_expResult.symbol);
        node.expressionRight()->setExpressionResult(ExpressionResult(_expResult.type, left_exp_result.symbol));
    }
    node.setNodeType(left_exp_result.type);
    node.setExpressionResult(left_exp_result);

    left_exp_result.symbol->touchWrite();
}
示例#21
0
void
SymbolTreeBuilder::visit(WhileLoopNode& node)
{
    node.setScope(currentScope());

    _curStatment = &node;
    node.condition()->accept(*this);
    // check condition expression
    if (!_expResult.type->isPromotableToBoolean())
    {
        throw SemanticException("Condition expression can not be promoted to boolean\n",
                                node);
    }

    // begin new scope
    beginScope();
    node.code()->accept(*this);
    endScope();
}
示例#22
0
void X86::writeAttribution(int e1, int e2, pair<pair<int, bool>, string>& lv) {
  writeTEXT("pop eax");
  writeTEXT("pop ecx");

  writeCast(e1, e2);

  stringstream s;

  Symbol symb = _stable.getSymbol(currentScope(), lv.second, true);
  s << "lea edx, [" << X86::makeID(lv.second) << "]";
  writeTEXT(s.str());

  s.str("");
  s << "lea edx, [edx + ecx * SIZEOF_DWORD]";
  writeTEXT(s.str());
  s.str("");
  s << "mov [edx], eax";
  writeTEXT(s.str());
}
示例#23
0
void
SymbolTreeBuilder::visit(ArgumentDeclsNode& node)
{
    if (node.arguments().size() > kMaxFunctionArgs)
    {
        std::stringstream stream;
        stream <<"Function '"
              <<_curFunctionCall->symbolName()
             << "' exceeds maximum arg count ("
             << kMaxFunctionArgs << ")"
             << std::endl;
        throw SemanticException(stream.str(), node);
    }

    node.setScope(currentScope());
    for(auto& v : node.arguments())
    {
        v->accept(*this);
    }
}
示例#24
0
void
SymbolTreeBuilder::visit(ConstantNode& node)
{
    node.setScope(currentScope());
    // check module if a constant that matches this value is available
    if (!node.constantValue().valueFitsInByteCode())
    {
        ModuleConstant* mod_constant = _parserState->module.constant(node.constantValue());
        if (!mod_constant)
        {
            _parserState->module.addConstant(new ModuleConstant(node.constantValue()));
        }
    }

    Symbol* tmp_sym = _curScope->declareTemporarySymbol(node.constantType());
    YAL_ASSERT(tmp_sym);
    _curStatment->addSymbolToScope(tmp_sym);
    _expResult = ExpressionResult(node.constantType(), tmp_sym);
    node.setNodeType(_expResult.type);
    node.setExpressionResult(_expResult);
}
示例#25
0
void
SymbolTreeBuilder::visit(FunctionCallArgsNode& node)
{
    YAL_ASSERT(_curFunctionCall);
    node.setScope(currentScope());

    FunctionType* func_type = cast_type<FunctionType>(_curFunctionCall->symbolType());
    YAL_ASSERT(func_type);
    const yal_u32 nargs = func_type->argumentCount();
    if (nargs != node.expressions.size())
    {
        std::stringstream stream;
        stream <<"Function '"
              <<_curFunctionCall->symbolName()
             << "' expects"<< nargs << "arguments, you have provided "
             << node.expressions.size()
             << std::endl;
        throw SemanticException(stream.str(), node);
    }

    yal_u32 idx = 0;
    for(auto& v : node.expressions)
    {
        v->accept(*this);
        const Type* arg_type = func_type->typeOfArgument(idx);
        if (!_expResult.type->isPromotableTo(arg_type))
        {
            std::stringstream stream;
            stream <<"Function '"
                  <<_curFunctionCall->symbolName()
                 << "' argument "<< idx << "expects type '"
                 << arg_type->typeString() << "', but you have provided type '"
                 << _expResult.type->typeString() << "'"
                 << std::endl;
            throw SemanticException(stream.str(), node);
        }
        ++idx;
    }
}
示例#26
0
void
SymbolTreeBuilder::visit(SingleOperatorNode& node)
{
    node.setScope(currentScope());
    node.expression()->accept(*this);

    const OperatorType op_type = node.singleOperatorType();
    const bool requires_signed_int = OperatorRequiresSignedType(op_type);
    const bool requires_integer = OperatorRequiresInteger(op_type);


    if (requires_signed_int && !_expResult.type->isSignedType())
    {
        std::stringstream stream;
        stream << "Operator '" << OperatorTypeToStr(node.singleOperatorType())
               << "' requires that right expression has a signed type"
               << std::endl;
        throw SemanticException(stream.str(), node);
    }

    if (requires_integer && !_expResult.type->isInteger())
    {
        std::stringstream stream;
        stream << "Operator '" << OperatorTypeToStr(node.singleOperatorType())
               << "' requires that right expression has an integer result"
               << std::endl;
        throw SemanticException(stream.str(), node);
    }

    Symbol* tmp_sym = _curScope->declareTemporarySymbol(_expResult.type,
                                                        _expResult.type->isObjectType() ? Symbol::kFlagNewObject : 0);
    _curStatment->addSymbolToScope(tmp_sym);

    _expResult = ExpressionResult(_expResult.type, tmp_sym);

    node.setNodeType(_expResult.type);
    node.setExpressionResult(_expResult);
}
示例#27
0
/**
 * Implement abstract operation from NativeImportBase.
 */
bool AdaImport::parseStmt()
{
    const int srcLength = m_source.count();
    QString keyword = m_source[m_srcIndex];
    UMLDoc *umldoc = UMLApp::app()->document();
    //uDebug() << '"' << keyword << '"';
    if (keyword == QLatin1String("with")) {
        if (m_inGenericFormalPart) {
            // mapping of generic formal subprograms or packages is not yet implemented
            return false;
        }
        while (++m_srcIndex < srcLength && m_source[m_srcIndex] != QLatin1String(";")) {
            QStringList components = m_source[m_srcIndex].toLower().split(QLatin1Char('.'));
            const QString& prefix = components.first();
            if (prefix == QLatin1String("system")
                || prefix == QLatin1String("ada")
                || prefix == QLatin1String("gnat")
                || prefix == QLatin1String("interfaces")
                || prefix == QLatin1String("text_io")
                || prefix == QLatin1String("unchecked_conversion")
                || prefix == QLatin1String("unchecked_deallocation")) {
                if (advance() != QLatin1String(","))
                    break;
                continue;
            }
            parseStems(components);
            if (advance() != QLatin1String(","))
                break;
        }
        return true;
    }
    if (keyword == QLatin1String("generic")) {
        m_inGenericFormalPart = true;
        return true;
    }
    if (keyword == QLatin1String("package")) {
        const QString& name = advance();
        QStringList parentPkgs = name.toLower().split(QLatin1Char('.'));
        parentPkgs.pop_back();  // exclude the current package
        parseStems(parentPkgs);
        UMLObject *ns = NULL;
        if (advance() == QLatin1String("is")) {
            ns = Import_Utils::createUMLObject(UMLObject::ot_Package, name,
                                               currentScope(), m_comment);
            if (m_source[m_srcIndex + 1] == QLatin1String("new")) {
                m_srcIndex++;
                QString pkgName = advance();
                UMLObject *gp = Import_Utils::createUMLObject(UMLObject::ot_Package, pkgName,
                                                              currentScope());
                gp->setStereotype(QLatin1String("generic"));
                // Add binding from instantiator to instantiatee
                UMLAssociation *assoc = new UMLAssociation(Uml::AssociationType::Dependency, ns, gp);
                assoc->setUMLPackage(umldoc->rootFolder(Uml::ModelType::Logical));
                assoc->setStereotype(QLatin1String("bind"));
                // Work around missing display of stereotype in AssociationWidget:
                assoc->setName(assoc->stereotype(true));
                umldoc->addAssociation(assoc);
                skipStmt();
            } else {
                pushScope(static_cast<UMLPackage*>(ns));
            }
        } else if (m_source[m_srcIndex] == QLatin1String("renames")) {
            m_renaming[name] = advance();
        } else {
            uError() << "unexpected: " << m_source[m_srcIndex];
            skipStmt(QLatin1String("is"));
        }
        if (m_inGenericFormalPart) {
            if (ns)
                ns->setStereotype(QLatin1String("generic"));
            m_inGenericFormalPart = false;
        }
        return true;
    }
    if (m_inGenericFormalPart)
        return false;  // skip generic formal parameter (not yet implemented)
    if (keyword == QLatin1String("subtype")) {
        QString name = advance();
        advance();  // "is"
        QString base = expand(advance());
        base.remove(QLatin1String("Standard."), Qt::CaseInsensitive);
        UMLObject *type = umldoc->findUMLObject(base, UMLObject::ot_UMLObject, currentScope());
        if (type == NULL) {
            type = Import_Utils::createUMLObject(UMLObject::ot_Datatype, base, currentScope());
        }
        UMLObject *subtype = Import_Utils::createUMLObject(type->baseType(), name,
                                                           currentScope(), m_comment);
        UMLAssociation *assoc = new UMLAssociation(Uml::AssociationType::Dependency, subtype, type);
        assoc->setUMLPackage(umldoc->rootFolder(Uml::ModelType::Logical));
        assoc->setStereotype(QLatin1String("subtype"));
        // Work around missing display of stereotype in AssociationWidget:
        assoc->setName(assoc->stereotype(true));
        umldoc->addAssociation(assoc);
        skipStmt();
        return true;
    }
    if (keyword == QLatin1String("type")) {
        QString name = advance();
        QString next = advance();
        if (next == QLatin1String("(")) {
            uDebug() << name << ": discriminant handling is not yet implemented";
            // @todo Find out how to map discriminated record to UML.
            //       For now, we just create a pro forma empty record.
            Import_Utils::createUMLObject(UMLObject::ot_Class, name, currentScope(),
                                          m_comment, QLatin1String("record"));
            skipStmt(QLatin1String("end"));
            if ((next = advance()) == QLatin1String("case"))
                m_srcIndex += 2;  // skip "case" ";"
            skipStmt();
            return true;
        }
        if (next == QLatin1String(";")) {
            // forward declaration
            Import_Utils::createUMLObject(UMLObject::ot_Class, name, currentScope(),
                                          m_comment);
            return true;
        }
        if (next != QLatin1String("is")) {
            uError() << "expecting \"is\"";
            return false;
        }
        next = advance();
        if (next == QLatin1String("(")) {
            // enum type
            UMLObject *ns = Import_Utils::createUMLObject(UMLObject::ot_Enum,
                            name, currentScope(), m_comment);
            UMLEnum *enumType = static_cast<UMLEnum*>(ns);
            while ((next = advance()) != QLatin1String(")")) {
                Import_Utils::addEnumLiteral(enumType, next, m_comment);
                m_comment.clear();
                if (advance() != QLatin1String(","))
                    break;
            }
            skipStmt();
            return true;
        }
        bool isTaggedType = false;
        if (next == QLatin1String("abstract")) {
            m_isAbstract = true;
            next = advance();
        }
        if (next == QLatin1String("tagged")) {
            isTaggedType = true;
            next = advance();
        }
        if (next == QLatin1String("limited") ||
            next == QLatin1String("task") ||
            next == QLatin1String("protected") ||
            next == QLatin1String("synchronized")) {
            next = advance();  // we can't (yet?) represent that
        }
        if (next == QLatin1String("private") ||
            next == QLatin1String("interface") ||
            next == QLatin1String("record") ||
            (next == QLatin1String("null") &&
             m_source[m_srcIndex+1] == QLatin1String("record"))) {
            UMLObject::ObjectType t = (next == QLatin1String("interface") ? UMLObject::ot_Interface
                                                                          : UMLObject::ot_Class);
            UMLObject *ns = Import_Utils::createUMLObject(t, name, currentScope(), m_comment);
            if (t == UMLObject::ot_Interface) {
                while ((next = advance()) == QLatin1String("and")) {
                    UMLClassifier *klass = static_cast<UMLClassifier*>(ns);
                    QString base = expand(advance());
                    UMLObject *p = Import_Utils::createUMLObject(UMLObject::ot_Interface, base, currentScope());
                    UMLClassifier *parent = static_cast<UMLClassifier*>(p);
                    Import_Utils::createGeneralization(klass, parent);
                }
            } else {
                ns->setAbstract(m_isAbstract);
            }
            m_isAbstract = false;
            if (isTaggedType) {
                if (! m_classesDefinedInThisScope.contains(ns))
                    m_classesDefinedInThisScope.append(ns);
            } else {
                ns->setStereotype(QLatin1String("record"));
            }
            if (next == QLatin1String("record"))
                m_klass = static_cast<UMLClassifier*>(ns);
            else
                skipStmt();
            return true;
        }
        if (next == QLatin1String("new")) {
            QString base = expand(advance());
            QStringList baseInterfaces;
            while ((next = advance()) == QLatin1String("and")) {
                baseInterfaces.append(expand(advance()));
            }
            const bool isExtension = (next == QLatin1String("with"));
            UMLObject::ObjectType t;
            if (isExtension || m_isAbstract) {
                t = UMLObject::ot_Class;
            } else {
                base.remove(QLatin1String("Standard."), Qt::CaseInsensitive);
                UMLObject *known = umldoc->findUMLObject(base, UMLObject::ot_UMLObject, currentScope());
                t = (known ? known->baseType() : UMLObject::ot_Datatype);
            }
            UMLObject *ns = Import_Utils::createUMLObject(t, base, NULL);
            UMLClassifier *parent = static_cast<UMLClassifier*>(ns);
            ns = Import_Utils::createUMLObject(t, name, currentScope(), m_comment);
            if (isExtension) {
                next = advance();
                if (next == QLatin1String("null") || next == QLatin1String("record")) {
                    UMLClassifier *klass = static_cast<UMLClassifier*>(ns);
                    Import_Utils::createGeneralization(klass, parent);
                    if (next == QLatin1String("record")) {
                        // Set the m_klass for attributes.
                        m_klass = klass;
                    }
                    if (baseInterfaces.count()) {
                        t = UMLObject::ot_Interface;
                        QStringList::Iterator end(baseInterfaces.end());
                        for (QStringList::Iterator bi(baseInterfaces.begin()); bi != end; ++bi) {
                             ns = Import_Utils::createUMLObject(t, *bi, currentScope());
                             parent = static_cast<UMLClassifier*>(ns);
                             Import_Utils::createGeneralization(klass, parent);
                        }
                    }
                }
            }
            skipStmt();
            return true;
        }
        // Datatypes: TO BE DONE
        return false;
    }
    if (keyword == QLatin1String("private")) {
        m_currentAccess = Uml::Visibility::Private;
        return true;
    }
    if (keyword == QLatin1String("end")) {
        if (m_klass) {
            if (advance() != QLatin1String("record")) {
                uError() << "end: expecting \"record\" at "
                          << m_source[m_srcIndex];
            }
            m_klass = NULL;
        } else if (scopeIndex()) {
            if (advance() != QLatin1String(";")) {
                QString scopeName = currentScope()->fullyQualifiedName();
                if (scopeName.toLower() != m_source[m_srcIndex].toLower())
                    uError() << "end: expecting " << scopeName << ", found "
                              << m_source[m_srcIndex];
            }
            popScope();
            m_currentAccess = Uml::Visibility::Public;   // @todo make a stack for this
        } else {
            uError() << "importAda: too many \"end\"";
        }
        skipStmt();
        return true;
    }
    // subprogram
    if (keyword == QLatin1String("not"))
        keyword = advance();
    if (keyword == QLatin1String("overriding"))
        keyword = advance();
    if (keyword == QLatin1String("function") || keyword == QLatin1String("procedure")) {
        const QString& name = advance();
        QString returnType;
        if (advance() != QLatin1String("(")) {
            // Unlike an Ada package, a UML package does not support
            // subprograms.
            // In order to map those, we would need to create a UML
            // class with stereotype <<utility>> for the Ada package.
            uDebug() << "ignoring parameterless " << keyword << " " << name;
            skipStmt();
            return true;
        }
        UMLClassifier *klass = NULL;
        UMLOperation *op = NULL;
        const uint MAX_PARNAMES = 16;
        while (m_srcIndex < srcLength && m_source[m_srcIndex] != QLatin1String(")")) {
            QString parName[MAX_PARNAMES];
            uint parNameCount = 0;
            do {
                if (parNameCount >= MAX_PARNAMES) {
                    uError() << "MAX_PARNAMES is exceeded at " << name;
                    break;
                }
                parName[parNameCount++] = advance();
            } while (advance() == QLatin1String(","));
            if (m_source[m_srcIndex] != QLatin1String(":")) {
                uError() << "importAda: expecting ':'";
                skipStmt();
                break;
            }
            const QString &direction = advance();
            QString typeName;
            Uml::ParameterDirection::Enum dir = Uml::ParameterDirection::In;
            if (direction == QLatin1String("access")) {
                // Oops, we have to improvise here because there
                // is no such thing as "access" in UML.
                // So we use the next best thing, "inout".
                // Better ideas, anyone?
                dir = Uml::ParameterDirection::InOut;
                typeName = advance();
            } else if (direction == QLatin1String("in")) {
                if (m_source[m_srcIndex + 1] == QLatin1String("out")) {
                    dir = Uml::ParameterDirection::InOut;
                    m_srcIndex++;
                }
                typeName = advance();
            } else if (direction == QLatin1String("out")) {
                dir = Uml::ParameterDirection::Out;
                typeName = advance();
            } else {
                typeName = direction;  // In Ada, the default direction is "in"
            }
            typeName.remove(QLatin1String("Standard."), Qt::CaseInsensitive);
            typeName = expand(typeName);
            if (op == NULL) {
                // In Ada, the first parameter indicates the class.
                UMLObject *type = Import_Utils::createUMLObject(UMLObject::ot_Class, typeName, currentScope());
                UMLObject::ObjectType t = type->baseType();
                if ((t != UMLObject::ot_Interface &&
                     (t != UMLObject::ot_Class || type->stereotype() == QLatin1String("record"))) ||
                    !m_classesDefinedInThisScope.contains(type)) {
                    // Not an instance bound method - we cannot represent it.
                    skipStmt(QLatin1String(")"));
                    break;
                }
                klass = static_cast<UMLClassifier*>(type);
                op = Import_Utils::makeOperation(klass, name);
                // The controlling parameter is suppressed.
                parNameCount--;
                if (parNameCount) {
                    for (uint i = 0; i < parNameCount; ++i) {
                        parName[i] = parName[i + 1];
                    }
                }
            }
            for (uint i = 0; i < parNameCount; ++i) {
                UMLAttribute *att = Import_Utils::addMethodParameter(op, typeName, parName[i]);
                att->setParmKind(dir);
            }
            if (advance() != QLatin1String(";"))
                break;
        }
        if (keyword == QLatin1String("function")) {
            if (advance() != QLatin1String("return")) {
                if (klass)
                    uError() << "importAda: expecting \"return\" at function "
                        << name;
                return false;
            }
            returnType = expand(advance());
            returnType.remove(QLatin1String("Standard."), Qt::CaseInsensitive);
        }
        bool isAbstract = false;
        if (advance() == QLatin1String("is") && advance() == QLatin1String("abstract"))
            isAbstract = true;
        if (klass != NULL && op != NULL)
            Import_Utils::insertMethod(klass, op, m_currentAccess, returnType,
                                       false, isAbstract, false, false, m_comment);
        skipStmt();
        return true;
    }
    if (keyword == QLatin1String("task") || keyword == QLatin1String("protected")) {
        // Can task and protected objects/types be mapped to UML?
        QString name = advance();
        if (name == QLatin1String("type")) {
            name = advance();
        }
        QString next = advance();
        if (next == QLatin1String("(")) {
            skipStmt(QLatin1String(")"));  // skip discriminant
            next = advance();
        }
        if (next == QLatin1String("is"))
            skipStmt(QLatin1String("end"));
        skipStmt();
        return true;
    }
    if (keyword == QLatin1String("for")) {    // rep spec
        QString typeName = advance();
        QString next = advance();
        if (next == QLatin1String("'")) {
            advance();  // skip qualifier
            next = advance();
        }
        if (next == QLatin1String("use")) {
            if (advance() == QLatin1String("record"))
                skipStmt(QLatin1String("end"));
        } else {
            uError() << "importAda: expecting \"use\" at rep spec of "
                      << typeName;
        }
        skipStmt();
        return true;
    }
    // At this point we're only interested in attribute declarations.
    if (m_klass == NULL || keyword == QLatin1String("null")) {
        skipStmt();
        return true;
    }
    const QString& name = keyword;
    if (advance() != QLatin1String(":")) {
        uError() << "adaImport: expecting \":\" at " << name << " "
                  << m_source[m_srcIndex];
        skipStmt();
        return true;
    }
    QString nextToken = advance();
    if (nextToken == QLatin1String("aliased"))
        nextToken = advance();
    QString typeName = expand(nextToken);
    QString initialValue;
    if (advance() == QLatin1String(":=")) {
        initialValue = advance();
        QString token;
        while ((token = advance()) != QLatin1String(";")) {
            initialValue.append(QLatin1Char(' ') + token);
        }
    }
    UMLObject *o = Import_Utils::insertAttribute(m_klass, m_currentAccess, name,
                                                 typeName, m_comment);
    if (o) {
        UMLAttribute *attr = static_cast<UMLAttribute*>(o);
        attr->setInitialValue(initialValue);
    }
    skipStmt();
    return true;
}
示例#28
0
文件: nodeGen.cpp 项目: ardeujho/self
 void NodeGen::testStackOverflow(PRegBList* exprStack, SplitSig* sig) {
   APPEND(new InterruptCheckNode(exprStack, sig));
   ((SCodeScope*)currentScope())->addSend(exprStack);
 }
示例#29
0
文件: nodeGen.cpp 项目: ardeujho/self
 void NodeGen::exitScope (SSelfScope* s) {
   assert(currentScope() == s, "exiting wrong scope");
   scopeStack->pop();
 }
示例#30
0
文件: nodeGen.cpp 项目: ardeujho/self
 const char* NodeGen::splitCondBranch( MergeNode*           targetNode,
                                       bool                 isBackwards,
                                       PReg*                targetPR,
                                       SExpr*               testExpr,
                                       BranchBCTargetStack* targetStack,
                                       SExprStack*          exprStack,
                                       PRegBList*           exprStackPRs, 
                                       SplitSig*            s ) {
   // try to split a conditional branch bc to avoid materializing
   // the boolean
   
   // local splitting only for now
 
   assert(targetPR->isConstPReg(), 
          "cond branch must be testing for constant");
   oop targetOop = ((ConstPReg*)targetPR)->constant;
   
   if (!testExpr->isMergeSExpr()) 
     return "testExpr not MergeSExpr";
   if (!((MergeSExpr*)testExpr)->isSplittable()) 
     return "textExpr not splittable";
   SExprBList* exprs = ((MergeSExpr*)testExpr)->exprs;
   assert(testExpr->node(), "splittable implies node()");
   Node* preceedingMerge = testExpr->node();
   if (current != preceedingMerge)
     return "not local"; // local only for now
   
   if ( preceedingMerge->nPredecessors() != exprs->length() )
     return "would have to iterate over predecessors";
     
   fint i;
   for ( i = 0;  
         i < exprs->length(); 
         ++i) {
      SExpr* e = exprs->nth(i);
      Node* n = e->node();
      if ( !preceedingMerge->isPredecessor(n) )
        return "merge not immediately after expr node";
      if ( !e->isConstantSExpr() )
        return "merge contains non-constant expression";
   }
   MergeNode* mergeForBranching      = new MergeNode("for branching");
   MergeNode* mergeForFallingThrough = new MergeNode("for falling through");
   mergeForBranching     ->setScope(currentScope());
   mergeForFallingThrough->setScope(currentScope());
   for ( i = 0;  
         i < exprs->length();  
         ++i) {
     SExpr* e = exprs->nth(i);
     Node* n = e->node();
     MergeNode* mn = e->constant() == targetOop
       ?  mergeForBranching
       :  mergeForFallingThrough;
     mn->setPrev(n);
     n->moveNext(preceedingMerge, mn);
   }     
   while (preceedingMerge->nPredecessors())
     preceedingMerge->removePrev(preceedingMerge->prev(0));
      
   current = mergeForBranching;
   branchCode( targetNode,
               isBackwards,
               NULL,
               NULL,
               targetStack,
               exprStack,
               exprStackPRs,
               s);
               
   append(mergeForFallingThrough);
   return NULL;
 }