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

📄 irfactory.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
                double ld = left.getDouble();                if (right.type == Token.NUMBER) {                    //both numbers                    left.setDouble(ld * right.getDouble());                    return left;                } else if (ld == 1.0) {                    // first 1: 1 *  x -> +x                    return new Node(Token.POS, right);                }            } else if (right.type == Token.NUMBER) {                if (right.getDouble() == 1.0) {                    //second 1: x * 1 -> +x                    // can not make simply x because x - 0 must be number                    return new Node(Token.POS, left);                }            }            // can't do x*0: Infinity * 0 gives NaN, not 0            break;          case Token.DIV:            // number division            if (right.type == Token.NUMBER) {                double rd = right.getDouble();                if (left.type == Token.NUMBER) {                    // both constants -- just divide, trust Java to handle x/0                    left.setDouble(left.getDouble() / rd);                    return left;               } else if (rd == 1.0) {                    // second 1: x/1 -> +x                    // not simply x to force number convertion                    return new Node(Token.POS, left);                }            }            break;          case Token.AND: {            // Since x && y gives x, not false, when Boolean(x) is false,            // and y, not Boolean(y), when Boolean(x) is true, x && y            // can only be simplified if x is defined. See bug 309957.            int leftStatus = isAlwaysDefinedBoolean(left);            if (leftStatus == ALWAYS_FALSE_BOOLEAN) {                // if the first one is false, just return it                return left;            } else if (leftStatus == ALWAYS_TRUE_BOOLEAN) {                // if first is true, set to second                return right;            }            break;          }          case Token.OR: {            // Since x || y gives x, not true, when Boolean(x) is true,            // and y, not Boolean(y), when Boolean(x) is false, x || y            // can only be simplified if x is defined. See bug 309957.            int leftStatus = isAlwaysDefinedBoolean(left);            if (leftStatus == ALWAYS_TRUE_BOOLEAN) {                // if the first one is true, just return it                return left;            } else if (leftStatus == ALWAYS_FALSE_BOOLEAN) {                // if first is false, set to second                return right;            }            break;          }        }        return new Node(nodeType, left, right);    }    private Node simpleAssignment(Node left, Node right)    {        int nodeType = left.getType();        switch (nodeType) {          case Token.NAME:            left.setType(Token.BINDNAME);            return new Node(Token.SETNAME, left, right);          case Token.GETPROP:          case Token.GETELEM: {            Node obj = left.getFirstChild();            Node id = left.getLastChild();            int type;            if (nodeType == Token.GETPROP) {                type = Token.SETPROP;            } else {                type = Token.SETELEM;            }            return new Node(type, obj, id, right);          }          case Token.GET_REF: {            Node ref = left.getFirstChild();            checkMutableReference(ref);            return new Node(Token.SET_REF, ref, right);          }        }        throw Kit.codeBug();    }    private void checkMutableReference(Node n)    {        int memberTypeFlags = n.getIntProp(Node.MEMBER_TYPE_PROP, 0);        if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {            parser.reportError("msg.bad.assign.left");        }    }    Node createAssignment(int assignType, Node left, Node right)    {        Node ref = makeReference(left);        if (ref == null) {            if (left.getType() == Token.ARRAYLIT ||                 left.getType() == Token.OBJECTLIT)            {                if (assignType != Token.ASSIGN) {                    parser.reportError("msg.bad.destruct.op");                    return right;                }                return createDestructuringAssignment(-1, left, right);            }            parser.reportError("msg.bad.assign.left");            return right;        }        left = ref;        int assignOp;        switch (assignType) {          case Token.ASSIGN:            return simpleAssignment(left, right);          case Token.ASSIGN_BITOR:  assignOp = Token.BITOR;  break;          case Token.ASSIGN_BITXOR: assignOp = Token.BITXOR; break;          case Token.ASSIGN_BITAND: assignOp = Token.BITAND; break;          case Token.ASSIGN_LSH:    assignOp = Token.LSH;    break;          case Token.ASSIGN_RSH:    assignOp = Token.RSH;    break;          case Token.ASSIGN_URSH:   assignOp = Token.URSH;   break;          case Token.ASSIGN_ADD:    assignOp = Token.ADD;    break;          case Token.ASSIGN_SUB:    assignOp = Token.SUB;    break;          case Token.ASSIGN_MUL:    assignOp = Token.MUL;    break;          case Token.ASSIGN_DIV:    assignOp = Token.DIV;    break;          case Token.ASSIGN_MOD:    assignOp = Token.MOD;    break;          default: throw Kit.codeBug();        }        int nodeType = left.getType();        switch (nodeType) {          case Token.NAME: {            Node op = new Node(assignOp, left, right);            Node lvalueLeft = Node.newString(Token.BINDNAME, left.getString());            return new Node(Token.SETNAME, lvalueLeft, op);          }          case Token.GETPROP:          case Token.GETELEM: {            Node obj = left.getFirstChild();            Node id = left.getLastChild();            int type = nodeType == Token.GETPROP                       ? Token.SETPROP_OP                       : Token.SETELEM_OP;            Node opLeft = new Node(Token.USE_STACK);            Node op = new Node(assignOp, opLeft, right);            return new Node(type, obj, id, op);          }          case Token.GET_REF: {            ref = left.getFirstChild();            checkMutableReference(ref);            Node opLeft = new Node(Token.USE_STACK);            Node op = new Node(assignOp, opLeft, right);            return new Node(Token.SET_REF_OP, ref, op);          }        }        throw Kit.codeBug();    }        /**     * Given a destructuring assignment with a left hand side parsed     * as an array or object literal and a right hand side expression,     * rewrite as a series of assignments to the variables defined in     * left from property accesses to the expression on the right.     * @param type declaration type: Token.VAR or Token.LET or -1     * @param left array or object literal containing NAME nodes for     *        variables to assign     * @param right expression to assign from     * @return expression that performs a series of assignments to     *         the variables defined in left     */    Node createDestructuringAssignment(int type, Node left, Node right)    {        String tempName = parser.currentScriptOrFn.getNextTempName();        Node result = destructuringAssignmentHelper(type, left, right,            tempName);        Node comma = result.getLastChild();        comma.addChildToBack(createName(tempName));        return result;    }    private Node destructuringAssignmentHelper(int variableType, Node left,                                                Node right, String tempName)    {        Node result = createScopeNode(Token.LETEXPR,            parser.getCurrentLineNumber());        result.addChildToFront(new Node(Token.LET,            createName(Token.NAME, tempName, right)));        try {            parser.pushScope(result);            parser.defineSymbol(Token.LET, tempName);        } finally {            parser.popScope();        }        Node comma = new Node(Token.COMMA);        result.addChildToBack(comma);        final int setOp = variableType == Token.CONST ? Token.SETCONST        		                                      : Token.SETNAME;        List<String> destructuringNames = new ArrayList<String>();        boolean empty = true;        int type = left.getType();        if (type == Token.ARRAYLIT) {            int index = 0;            int[] skipIndices = (int[])left.getProp(Node.SKIP_INDEXES_PROP);            int skip = 0;            Node n = left.getFirstChild();            for (;;) {                if (skipIndices != null) {                    while (skip < skipIndices.length &&                            skipIndices[skip] == index) {                        skip++;                        index++;                    }                }                if (n == null)                    break;                Node rightElem = new Node(Token.GETELEM,                    createName(tempName),                     createNumber(index));                if (n.getType() == Token.NAME) {                    String name = n.getString();                    comma.addChildToBack(new Node(setOp,                         createName(Token.BINDNAME, name, null),                        rightElem));                    if (variableType != -1) {                        parser.defineSymbol(variableType, name);                        destructuringNames.add(name);                    }                } else {                    comma.addChildToBack(                        destructuringAssignmentHelper(variableType, n,                            rightElem,                            parser.currentScriptOrFn.getNextTempName()));                }                index++;                empty = false;                n = n.getNext();            }        } else if (type == Token.OBJECTLIT) {            int index = 0;            Object[] propertyIds = (Object[])                left.getProp(Node.OBJECT_IDS_PROP);            for (Node n = left.getFirstChild(); n != null; n = n.getNext())            {                Object id = propertyIds[index];                Node rightElem = id instanceof String                     ? new Node(Token.GETPROP,                        createName(tempName),                         createString((String)id))                    : new Node(Token.GETELEM,                        createName(tempName),                         createNumber(((Number)id).intValue()));                if (n.getType() == Token.NAME) {                    String name = n.getString();                    comma.addChildToBack(new Node(setOp,                         createName(Token.BINDNAME, name, null),                        rightElem));                    if (variableType != -1) {                        parser.defineSymbol(variableType, name);                        destructuringNames.add(name);                    }                } else {                    comma.addChildToBack(                        destructuringAssignmentHelper(variableType, n,                            rightElem,                            parser.currentScriptOrFn.getNextTempName()));                }                index++;                empty = false;            }        } else if (type == Token.GETPROP || type == Token.GETELEM) {            comma.addChildToBack(simpleAssignment(left, createName(tempName)));        } else {            parser.reportError("msg.bad.assign.left");        }        if (empty) {            // Don't want a COMMA node with no children. Just add a zero.            comma.addChildToBack(createNumber(0));        }        result.putProp(Node.DESTRUCTURING_NAMES, destructuringNames);        return result;    }    Node createUseLocal(Node localBlock)    {        if (Token.LOCAL_BLOCK != localBlock.getType()) throw Kit.codeBug();        Node result = new Node(Token.LOCAL_LOAD);        result.putProp(Node.LOCAL_BLOCK_PROP, localBlock);        return result;    }    private Node.Jump makeJump(int type, Node target)    {        Node.Jump n = new Node.Jump(type);        n.target = target;        return n;    }    private Node makeReference(Node node)    {        int type = node.getType();        switch (type) {          case Token.NAME:          case Token.GETPROP:          case Token.GETELEM:          case Token.GET_REF:            return node;          case Token.CALL:            node.setType(Token.REF_CALL);            return new Node(Token.GET_REF, node);        }        // Signal caller to report error        return null;    }    // Check if Node always mean true or false in boolean context    private static int isAlwaysDefinedBoolean(Node node)    {        switch (node.getType()) {          case Token.FALSE:          case Token.NULL:            return ALWAYS_FALSE_BOOLEAN;          case Token.TRUE:            return ALWAYS_TRUE_BOOLEAN;          case Token.NUMBER: {            double num = node.getDouble();            if (num == num && num != 0.0) {                return ALWAYS_TRUE_BOOLEAN;            } else {                return ALWAYS_FALSE_BOOLEAN;            }          }        }        return 0;    }        private void checkActivationName(String name, int token)    {        if (parser.insideFunction()) {            boolean activation = false;            if ("arguments".equals(name)                || (parser.compilerEnv.activationNames != null                    && parser.compilerEnv.activationNames.containsKey(name)))            {                activation = true;            } else if ("length".equals(name)) {                if (token == Token.GETPROP                    && parser.compilerEnv.getLanguageVersion()                       == Context.VERSION_1_2)                {                    // Use of "length" in 1.2 requires an activation object.                    activation = true;                }            }            if (activation) {                setRequiresActivation();            }        }    }    private void setRequiresActivation()    {        if (parser.insideFunction()) {            ((FunctionNode)parser.currentScriptOrFn).itsNeedsActivation = true;        }    }    private void setIsGenerator()    {        if (parser.insideFunction()) {            ((FunctionNode)parser.currentScriptOrFn).itsIsGenerator = true;        }    }    private Parser parser;    private static final int LOOP_DO_WHILE = 0;    private static final int LOOP_WHILE    = 1;    private static final int LOOP_FOR      = 2;    private static final int ALWAYS_TRUE_BOOLEAN = 1;    private static final int ALWAYS_FALSE_BOOLEAN = -1;}

⌨️ 快捷键说明

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