Пример #1
0
void checkIfStmt(AST_NODE* ifNode)
{
  AST_NODE* exprNode = ifNode->child;
  AST_NODE* blockNode1 = exprNode->rightSibling;
  AST_NODE* blockNode2 = blockNode1->rightSibling;
  openScope();
  processBlockNode(blockNode1);
  closeScope();
  if (blockNode2->nodeType == BLOCK_NODE) {
    openScope();
    processBlockNode(blockNode2);
    closeScope();
  }
}
Пример #2
0
void checkForStmt(AST_NODE* forNode)
{
  AST_NODE *initNode = forNode->child;
  AST_NODE *condNode = initNode->rightSibling;
  AST_NODE *incrNode = condNode->rightSibling;
  AST_NODE *stmtNode = incrNode->rightSibling;
  initNode = initNode->child;
  while (initNode) {
    checkAssignmentStmt(initNode);
    initNode = initNode->rightSibling;
  }
  if (condNode->nodeType != NUL_NODE) {
    condNode = condNode->child;
    while (condNode) {
      processExprRelatedNode(condNode);
      condNode = condNode->rightSibling;
    }
  }
  incrNode = incrNode->child;
  while (incrNode) {
    checkAssignmentStmt(incrNode);
    incrNode = incrNode->rightSibling;
  }
  openScope();
  processBlockNode(stmtNode);
  closeScope();
}
Пример #3
0
void BytecodeTranslatorVisitor::visitForNode(ForNode* node) {
    onVisitNode(node);

    const AstVar* i = node->var();
    if (i->type() != VT_INT)
        ERROR("Non-iterable type in for loop");

    const BinaryOpNode* expr = node->inExpr()->asBinaryOpNode();
    if (expr == NULL || expr->kind() != tRANGE)
        ERROR("Invalid range in for loop");

    CONTEXT(function(), locals(), node->body()->scope(), typeStack());

    beforeProcessBlock();

    bool needTempVar = !expr->right()->isIntLiteralNode();
    AstVar* temp = NULL;
    if (needTempVar) {
        if (!scope()->declareVariable("<tempForEnd>", VT_INT))
            ERROR("internal error: temp name is unavailable");
        temp = scope()->lookupVariable("<tempForEnd>", false);
    }

    Label L_Begin(bytecode());
    Label L_End(bytecode());

    VISIT(expr->left());
    EMIT_STORE(i);

    if (needTempVar) {
        VISIT(expr->right());
        EMIT_STORE(temp);
        popType(VT_INT);
    }

    popType(VT_INT);
    EMIT_BIND(L_Begin);
    if (needTempVar)
        EMIT_LOAD(temp);
    else
        VISIT(expr->right());
    EMIT_LOAD(i);
    EMIT_BRANCH(BC_IFICMPG, L_End);

    processBlockNode(node->body());
    afterProcessBlock();

    /* i += 1 */
    EMIT_LOAD(i);
    EMIT(BC_ILOAD1);
    EMIT(BC_IADD);
    EMIT_STORE(i);

    EMIT_BRANCH(BC_JA, L_Begin);
    EMIT_BIND(L_End);

    pushType(VT_VOID);
}
Пример #4
0
void checkWhileStmt(AST_NODE* whileNode)
{
  AST_NODE *condNode = whileNode->child;
  AST_NODE *blockNode = condNode->rightSibling;
  processExprRelatedNode(condNode);
  openScope();
  processBlockNode(blockNode);
  closeScope();
}
Пример #5
0
void BytecodeTranslatorVisitor::visitBlockNode(BlockNode* node) {
    onVisitNode(node);

    CONTEXT(function(), locals(), node->scope(), typeStack());

    beforeProcessBlock();
    processBlockNode(node);
    afterProcessBlock();

    pushType(VT_VOID);
}
Пример #6
0
void QTextHtmlImporter::import()
{
    cursor.beginEditBlock();
    hasBlock = true;
    forceBlockMerging = false;
    compressNextWhitespace = !textEditMode;
    blockTagClosed = false;
    for (currentNodeIdx = 0; currentNodeIdx < count(); ++currentNodeIdx) {
        currentNode = &at(currentNodeIdx);
        wsm = textEditMode ? QTextHtmlParserNode::WhiteSpacePreWrap : currentNode->wsm;

        /*
         * process each node in three stages:
         * 1) check if the hierarchy changed and we therefore passed the
         *    equivalent of a closing tag -> we may need to finish off
         *    some structures like tables
         *
         * 2) check if the current node is a special node like a
         *    <table>, <ul> or <img> tag that requires special processing
         *
         * 3) if the node should result in a QTextBlock create one and
         *    finally insert text that may be attached to the node
         */

        /* emit 'closing' table blocks or adjust current indent level
         * if we
         *  1) are beyond the first node
         *  2) the current node not being a child of the previous node
         *      means there was a tag closing in the input html
         */
        if (currentNodeIdx > 0 && (currentNode->parent != currentNodeIdx - 1)) {
            blockTagClosed = closeTag();
            // visually collapse subsequent block tags, but if the element after the closed block tag
            // is for example an inline element (!isBlock) we have to make sure we start a new paragraph by setting
            // hasBlock to false.
            if (blockTagClosed
                && !currentNode->isBlock()
                && currentNode->id != Html_unknown)
                hasBlock = false;
        }

        if (currentNode->displayMode == QTextHtmlElement::DisplayNone) {
            if (currentNode->id == Html_title)
                doc->setMetaInformation(QTextDocument::DocumentTitle, currentNode->text);
            // ignore explicitly 'invisible' elements
            continue;
        }

        if (processSpecialNodes() == ContinueWithNextNode)
            continue;

        // make sure there's a block for 'Blah' after <ul><li>foo</ul>Blah
        if (blockTagClosed
            && !hasBlock
            && !currentNode->isBlock()
            && !currentNode->text.isEmpty() && !currentNode->hasOnlyWhitespace()
            && currentNode->displayMode == QTextHtmlElement::DisplayInline) {

            QTextBlockFormat block = currentNode->blockFormat;
            block.setIndent(indent);

            appendBlock(block, currentNode->charFormat);

            hasBlock = true;
        }

        if (currentNode->isBlock()) {
            if (processBlockNode() == ContinueWithNextNode)
                continue;
        }

        if (currentNode->charFormat.isAnchor() && !currentNode->charFormat.anchorName().isEmpty()) {
            namedAnchors.append(currentNode->charFormat.anchorName());
        }

        if (appendNodeText())
            hasBlock = false; // if we actually appended text then we don't
                              // have an empty block anymore
    }

    cursor.endEditBlock();
}
Пример #7
0
void declareFunction(AST_NODE* declarationNode)
{
  //get node
  AST_NODE* idNode = declarationNode->rightSibling;
  AST_NODE* paramListNode = idNode->rightSibling;
  AST_NODE* blockNode = paramListNode->rightSibling;

  SymbolAttribute *funcAttr = (SymbolAttribute*)malloc(sizeof(SymbolAttribute));
  FunctionSignature* funcSig = (FunctionSignature*)malloc(sizeof(FunctionSignature));
  Parameter *param = NULL;
  //generate attribute
  funcAttr->attributeKind = FUNCTION_SIGNATURE;
  funcAttr->attr.functionSignature = funcSig;

  //generate signature
  funcSig->parametersCount = 0;
  funcSig->parameterList = NULL;
  funcSig->returnType = retrieveType(declarationNode->semantic_value.identifierSemanticValue.identifierName);

  //printf("get function %s\n", idNode->semantic_value.identifierSemanticValue.identifierName);
  //printf("return type %d\n", retrieveType(declarationNode->semantic_value.identifierSemanticValue.identifierName));

  //parse parameter node
  AST_NODE *paramNode = paramListNode->child;
  while(paramNode) {
    //push into Parameter node
    AST_NODE *varTypeNode = paramNode->child;
    AST_NODE *varidNode = varTypeNode->rightSibling;
    Parameter *nextParam = param;
    param = (Parameter*)malloc(sizeof(Parameter));
    param->type = (TypeDescriptor*)malloc(sizeof(TypeDescriptor));
    param->parameterName = (char*)malloc(strlen(varidNode->semantic_value.identifierSemanticValue.identifierName+1));
    strcpy(param->parameterName, varidNode->semantic_value.identifierSemanticValue.identifierName);
    param->next = nextParam;
    ++(funcSig->parametersCount);
    param->type->properties.dataType
      = retrieveType(varTypeNode->semantic_value.identifierSemanticValue.identifierName);

    processDeclDimList(varidNode, param->type, True);

    paramNode = paramNode->rightSibling;
  }
  funcSig->parameterList = param;
  if (detectSymbol(idNode->semantic_value.identifierSemanticValue.identifierName)) {
    //function name redefine
    printErrorMsg(idNode, SYMBOL_REDECLARE);
  } else {
    //push into symbol table
    enterSymbol(idNode->semantic_value.identifierSemanticValue.identifierName, funcAttr);
  }
  openScope();
  //generate param symbol
  SymbolAttribute *paramAttr = NULL;
  TypeDescriptor *paramType = NULL;
  Parameter *paramVar = param;
  while(paramVar){
    SymbolAttribute *paramAttr = (SymbolAttribute*)malloc(sizeof(SymbolAttribute));
    TypeDescriptor *paramType = (TypeDescriptor*)malloc(sizeof(TypeDescriptor));
    paramAttr->attributeKind = VARIABLE_ATTRIBUTE;
    paramAttr->attr.typeDescriptor = paramType;

    memcpy(paramType, param->type, sizeof(TypeDescriptor));
    if (detectSymbol(paramVar->parameterName)) {
      //function name redefine
      printErrorMsg(paramListNode, SYMBOL_REDECLARE);
    } else {
      //push into symbol table
      enterSymbol(paramVar->parameterName, paramAttr);
    }

    paramVar = paramVar->next;
  }
  
  processBlockNode(blockNode);
  closeScope();
}