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(); } }
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(); }
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); }
void checkWhileStmt(AST_NODE* whileNode) { AST_NODE *condNode = whileNode->child; AST_NODE *blockNode = condNode->rightSibling; processExprRelatedNode(condNode); openScope(); processBlockNode(blockNode); closeScope(); }
void BytecodeTranslatorVisitor::visitBlockNode(BlockNode* node) { onVisitNode(node); CONTEXT(function(), locals(), node->scope(), typeStack()); beforeProcessBlock(); processBlockNode(node); afterProcessBlock(); pushType(VT_VOID); }
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(); }
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(); }