⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qscriptcompiler.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    default:        break;    }    return false;}int Compiler::inplaceAssignmentOperator(int op) const{    switch (op) {    case QSOperator::BitAnd:        return QSOperator::InplaceAnd;    case QSOperator::Sub:        return QSOperator::InplaceSub;    case QSOperator::Div:        return QSOperator::InplaceDiv;    case QSOperator::Add:        return QSOperator::InplaceAdd;    case QSOperator::LShift:        return QSOperator::InplaceLeftShift;    case QSOperator::Mod:        return QSOperator::InplaceMod;    case QSOperator::Mul:        return QSOperator::InplaceMul;    case QSOperator::BitOr:        return QSOperator::InplaceOr;    case QSOperator::RShift:        return QSOperator::InplaceRightShift;    case QSOperator::URShift:        return QSOperator::InplaceURightShift;    case QSOperator::BitXor:        return QSOperator::InplaceXor;    default:        break;    }    return(-1);}bool Compiler::visit(AST::Expression *node){    node->left->accept(this);    iPop(); // ### or iSync?    node->right->accept(this);    return false;}bool Compiler::visit(AST::BinaryExpression *node){    if (isAssignmentOperator(node->op)) {        bool was = generateReferences(true);        node->left->accept(this);        generateReferences(was);    } else {        node->left->accept(this);    }    int address = 0;    if (node->op == QSOperator::Or || node->op == QSOperator::And) {        iDuplicate();        address = nextInstructionOffset();        if (node->op == QSOperator::Or)            iBranchTrue(0);        else            iBranchFalse(0);        iPop();    }    int op = node->op;    Compare compare;    if ((op == QSOperator::Assign) && node->right->binaryExpressionCast()        && (inplaceAssignmentOperator(node->right->binaryExpressionCast()->op) != -1)        && compare(node->left, node->right->binaryExpressionCast()->left)) {        // node->left is equivalent to node->right->left, so we generate        // x op= y rather than x = x op y        op = inplaceAssignmentOperator(node->right->binaryExpressionCast()->op);        node->right->binaryExpressionCast()->right->accept(this);    } else {        node->right->accept(this);    }    switch (op) {    case QSOperator::Assign:        iAssign();        break;    case QSOperator::InplaceAnd:        iInplaceAnd();        break;    case QSOperator::InplaceSub:        iInplaceSub();        break;    case QSOperator::InplaceDiv:        iInplaceDiv();        break;    case QSOperator::InplaceAdd:        iInplaceAdd();        break;    case QSOperator::InplaceLeftShift:        iInplaceLeftShift();        break;    case QSOperator::InplaceMod:        iInplaceMod();        break;    case QSOperator::InplaceMul:        iInplaceMul();        break;    case QSOperator::InplaceOr:        iInplaceOr();        break;    case QSOperator::InplaceRightShift:        iInplaceRightShift();        break;    case QSOperator::InplaceURightShift:        iInplaceURightShift();        break;    case QSOperator::InplaceXor:        iInplaceXor();        break;    case QSOperator::BitAnd:        iBitAnd();        break;    case QSOperator::BitOr:        iBitOr();        break;    case QSOperator::BitXor:        iBitXor();        break;    case QSOperator::LShift:        iLeftShift();        break;    case QSOperator::Mod:        iMod();        break;    case QSOperator::RShift:        iRightShift();        break;    case QSOperator::URShift:        iURightShift();        break;    case QSOperator::InstanceOf:        iInstanceOf();        break;    case QSOperator::Add:        iAdd();        break;    case QSOperator::And:        patchInstruction(address, nextInstructionOffset() - address);        break;    case QSOperator::Div:        iDiv();        break;    case QSOperator::Equal:        iEqual();        break;    case QSOperator::Ge:        iGreatOrEqual();        break;    case QSOperator::Gt:        iGreatThan();        break;    case QSOperator::Le:        iLessOrEqual();        break;    case QSOperator::Lt:        iLessThan();        break;    case QSOperator::Mul:        iMul();        break;    case QSOperator::NotEqual:        iNotEqual();        break;    case QSOperator::Or:        patchInstruction(address, nextInstructionOffset() - address);        break;    case QSOperator::Sub:        iSub();        break;    case QSOperator::StrictEqual:        iStrictEqual();        break;    case QSOperator::StrictNotEqual:        iStrictNotEqual();        break;    case QSOperator::In:        iIn();        break;    }    return false;}bool Compiler::visit(AST::TrueLiteral *){    iLoadTrue();    return false;}bool Compiler::visit(AST::FalseLiteral *){    iLoadFalse();    return false;}bool Compiler::visit(AST::SwitchStatement *node){    iLine(node);    Loop *previousLoop = changeActiveLoop(&m_loops[node]);    node->expression->accept(this);    bool was = switchStatement(true);    AST::CaseClauses *clauses;    int skipIndex = -1;    int fallthroughIndex = -1;    // ### make a function for this    for (clauses = node->block->clauses; clauses != 0; clauses = clauses->next) {        AST::CaseClause *clause = clauses->clause;        if (skipIndex != -1)            patchInstruction(skipIndex, nextInstructionOffset() - skipIndex);        iDuplicate(); // expression        clause->expression->accept(this);        iStrictEqual();        skipIndex = nextInstructionOffset();        iBranchFalse(0); // next case        if (fallthroughIndex != -1) // previous case falls through to here            patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex);        int breaksBefore = m_activeLoop->breakLabel.uses.count();        if (clause->statements)            clause->statements->accept(this);        int breaksAfter = m_activeLoop->breakLabel.uses.count();        if (breaksAfter == breaksBefore) { // fallthrough            fallthroughIndex = nextInstructionOffset();            iBranch(0);        } else { // no fallthrough (break)            fallthroughIndex = -1;        }    }    if (fallthroughIndex != -1) {        patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex);        fallthroughIndex = -1;    }    int defaultIndex = -1;    if (node->block->defaultClause) {        int skipDefaultIndex = -1;        if (!node->block->clauses && node->block->moreClauses) {            skipDefaultIndex = nextInstructionOffset();            iBranch(0);        }        defaultIndex = nextInstructionOffset();        int breaksBefore = m_activeLoop->breakLabel.uses.count();        if (node->block->defaultClause->statements)            node->block->defaultClause->statements->accept(this);        int breaksAfter = m_activeLoop->breakLabel.uses.count();        if (breaksAfter == breaksBefore) { // fallthrough            fallthroughIndex = nextInstructionOffset();            iBranch(0);        } else { // no fallthrough (break)            fallthroughIndex = -1;        }        if (skipDefaultIndex != -1)            patchInstruction(skipDefaultIndex, nextInstructionOffset() - skipDefaultIndex);    }    for (clauses = node->block->moreClauses; clauses != 0; clauses = clauses->next) {        AST::CaseClause *clause = clauses->clause;        if (skipIndex != -1)            patchInstruction(skipIndex, nextInstructionOffset() - skipIndex);        iDuplicate(); // expression        clause->expression->accept(this);        iStrictEqual();        skipIndex = nextInstructionOffset();        iBranchFalse(0); // next case        if (fallthroughIndex != -1) // previous case falls through to here            patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex);        int breaksBefore = m_activeLoop->breakLabel.uses.count();        if (clause->statements)            clause->statements->accept(this);        int breaksAfter = m_activeLoop->breakLabel.uses.count();        if (breaksAfter == breaksBefore) { // fallthrough            fallthroughIndex = nextInstructionOffset();            iBranch(0);        } else { // no fallthrough (break)            fallthroughIndex = -1;        }    }    if (skipIndex != -1) {        patchInstruction(skipIndex, nextInstructionOffset() - skipIndex);        if (defaultIndex != -1)            iBranch(defaultIndex - nextInstructionOffset()); // goto default    }    if (fallthroughIndex != -1)        patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex);    // backpatch the breaks    int term = nextInstructionOffset();    foreach (int index, m_activeLoop->breakLabel.uses) {        patchInstruction(index, term - index);    }    iPop(); // expression    switchStatement(was);    changeActiveLoop(previousLoop);    m_loops.remove(node);    return false;}bool Compiler::visit(AST::LabelledStatement *node){    Loop *loop = findLoop(node->label);    if (loop != 0) {        m_compilationUnit.setValid(false);        QString str = m_eng->toString(node->label);        m_compilationUnit.setErrorMessage(QString::fromUtf8("duplicate label `%1'").arg(str));        return false;    }    m_loops[node->statement].name = node->label;    node->statement->accept(this);    m_loops.remove(node->statement);    return false;}bool Compiler::visit(AST::ExpressionStatement *node){    if (node->expression)        iLine(node->expression);    return true;}void Compiler::endVisit(AST::ExpressionStatement *){    if (topLevelCompiler())        iSync();    else        iPop();}void Compiler::endVisit(AST::UnaryPlusExpression *){    iUnaryPlus();}void Compiler::endVisit(AST::UnaryMinusExpression *){    iUnaryMinus();}bool Compiler::visit(AST::ContinueStatement *node){    iLine(node);    return true;}void Compiler::endVisit(AST::ContinueStatement *node){    int offset = nextInstructionOffset();    iBranch(0);    Loop *loop = findLoop(node->label);    if (! loop) {        m_compilationUnit.setErrorMessage(QString::fromUtf8("label not found"));        m_compilationUnit.setValid(false);        return;    }    loop->continueLabel.uses.append(offset);}bool Compiler::visit(AST::BreakStatement *node){    iLine(node);    return true;}void Compiler::endVisit(AST::BreakStatement *node){    Loop *loop = findLoop(node->label);    if (! loop) {        m_compilationUnit.setErrorMessage(QString::fromUtf8("label not found"));        m_compilationUnit.setValid(false);        return;    }    if (m_generateLeaveWithOnBreak)        iLeaveWith();    int offset = nextInstructionOffset();    iBranch(0);    loop->breakLabel.uses.append(offset);}void Compiler::patchInstruction(int index, int offset){    QScriptInstruction &i = m_instructions[index];    switch (i.op) {        case QScriptInstruction::OP_Branch:        case QScriptInstruction::OP_BranchFalse:        case QScriptInstruction::OP_BranchTrue:            m_eng->newInteger(&i.operand[0], offset);            break;        default:            Q_ASSERT_X(0, "Compiler::patchInstruction()", "expected a branch instruction");            break;    }}bool Compiler::visit(AST::WithStatement *node){    iLine(node);    node->expression->accept(this);    iEnterWith();    bool was = withStatement(true);    bool was2 = generateLeaveOnBreak(m_iterationStatement);    node->statement->accept(this);    generateLeaveOnBreak(was2);    withStatement(was);    iLeaveWith();    return false;}bool Compiler::visit(AST::ArrayLiteral *node){    iNewArray();    int length = 0;    for (AST::ElementList *it = node->elements; it != 0; it = it->next) {        for (AST::Elision *eit = it->elision; eit != 0; eit = eit->next) {            iDuplicate();            iLoadNumber(length);            iMakeReference();            iLoadUndefined();            iAssign();            iPop();            ++length;        }        if (it->expression) {            iDuplicate();            iLoadNumber(length);            iMakeReference();            it->expression->accept(this);            iAssign();            iPop();            ++length;        }    }    for (AST::Elision *eit = node->elision; eit != 0; eit = eit->next) {        iDuplicate();        iLoadNumber(length);        iMakeReference();        iLoadUndefined();        iAssign();        iPop();        ++length;    }    return false;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -